diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-26 20:04:50 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-26 20:04:50 +0000 |
commit | b8183567bfe1c62f5a5c83e89bac0340639a29a7 (patch) | |
tree | 32c8bf80c87876721932006b709a23edb6ca2d73 /driver/xf86-video-i128/src | |
parent | 85b8022e36c5bde7945354cb63ead06f93780c91 (diff) |
Importing xf86-video-i128 1.1.0.6
Diffstat (limited to 'driver/xf86-video-i128/src')
-rw-r--r-- | driver/xf86-video-i128/src/IBMRGB.h | 67 | ||||
-rw-r--r-- | driver/xf86-video-i128/src/Makefile.am | 41 | ||||
-rw-r--r-- | driver/xf86-video-i128/src/Makefile.in | 526 | ||||
-rw-r--r-- | driver/xf86-video-i128/src/Ti302X.h | 209 | ||||
-rw-r--r-- | driver/xf86-video-i128/src/i128.h | 167 | ||||
-rw-r--r-- | driver/xf86-video-i128/src/i128IBMDAC.c | 737 | ||||
-rw-r--r-- | driver/xf86-video-i128/src/i128_driver.c | 2478 | ||||
-rw-r--r-- | driver/xf86-video-i128/src/i128accel.c | 520 | ||||
-rw-r--r-- | driver/xf86-video-i128/src/i128dga.c | 278 | ||||
-rw-r--r-- | driver/xf86-video-i128/src/i128exa.c | 683 | ||||
-rw-r--r-- | driver/xf86-video-i128/src/i128init.c | 580 | ||||
-rw-r--r-- | driver/xf86-video-i128/src/i128reg.h | 730 |
12 files changed, 7016 insertions, 0 deletions
diff --git a/driver/xf86-video-i128/src/IBMRGB.h b/driver/xf86-video-i128/src/IBMRGB.h new file mode 100644 index 000000000..9a3656585 --- /dev/null +++ b/driver/xf86-video-i128/src/IBMRGB.h @@ -0,0 +1,67 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/IBMRGB.h,v 1.1 2000/10/04 23:34:58 robin Exp $ */ + + + +/* $XConsortium: $ */ + +#define IBMRGB_REF_FREQ_1 14.31818 +#define IBMRGB_REF_FREQ_2 50.00000 + +#define IBMRGB_rev 0x00 +#define IBMRGB_id 0x01 +#define IBMRGB_misc_clock 0x02 +#define IBMRGB_sync 0x03 +#define IBMRGB_hsync_pos 0x04 +#define IBMRGB_pwr_mgmt 0x05 +#define IBMRGB_dac_op 0x06 +#define IBMRGB_pal_ctrl 0x07 +#define IBMRGB_sysclk 0x08 /* not RGB525 */ +#define IBMRGB_pix_fmt 0x0a +#define IBMRGB_8bpp 0x0b +#define IBMRGB_16bpp 0x0c +#define IBMRGB_24bpp 0x0d +#define IBMRGB_32bpp 0x0e +#define IBMRGB_pll_ctrl1 0x10 +#define IBMRGB_pll_ctrl2 0x11 +#define IBMRGB_pll_ref_div_fix 0x14 +#define IBMRGB_sysclk_ref_div 0x15 /* not RGB525 */ +#define IBMRGB_sysclk_vco_div 0x16 /* not RGB525 */ +#define IBMRGB_f0 0x20 +#define IBMRGB_m0 0x20 +#define IBMRGB_n0 0x21 +#define IBMRGB_curs 0x30 +#define IBMRGB_curs_xl 0x31 +#define IBMRGB_curs_xh 0x32 +#define IBMRGB_curs_yl 0x33 +#define IBMRGB_curs_yh 0x34 +#define IBMRGB_curs_hot_x 0x35 +#define IBMRGB_curs_hot_y 0x36 +#define IBMRGB_curs_col1_r 0x40 +#define IBMRGB_curs_col1_g 0x41 +#define IBMRGB_curs_col1_b 0x42 +#define IBMRGB_curs_col2_r 0x43 +#define IBMRGB_curs_col2_g 0x44 +#define IBMRGB_curs_col2_b 0x45 +#define IBMRGB_curs_col3_r 0x46 +#define IBMRGB_curs_col3_g 0x47 +#define IBMRGB_curs_col3_b 0x48 +#define IBMRGB_border_col_r 0x60 +#define IBMRGB_border_col_g 0x61 +#define IBMRGB_botder_col_b 0x62 +#define IBMRGB_misc1 0x70 +#define IBMRGB_misc2 0x71 +#define IBMRGB_misc3 0x72 +#define IBMRGB_misc4 0x73 /* not RGB525 */ +#define IBMRGB_dac_sense 0x82 +#define IBMRGB_misr_r 0x84 +#define IBMRGB_misr_g 0x86 +#define IBMRGB_misr_b 0x88 +#define IBMRGB_pll_vco_div_in 0x8e +#define IBMRGB_pll_ref_div_in 0x8f +#define IBMRGB_vram_mask_0 0x90 +#define IBMRGB_vram_mask_1 0x91 +#define IBMRGB_vram_mask_2 0x92 +#define IBMRGB_vram_mask_3 0x93 +#define IBMRGB_curs_array 0x100 + + diff --git a/driver/xf86-video-i128/src/Makefile.am b/driver/xf86-video-i128/src/Makefile.am new file mode 100644 index 000000000..60d188454 --- /dev/null +++ b/driver/xf86-video-i128/src/Makefile.am @@ -0,0 +1,41 @@ +# 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@ +i128_drv_la_LTLIBRARIES = i128_drv.la +i128_drv_la_LDFLAGS = -module -avoid-version +i128_drv_ladir = @moduledir@/drivers + +i128_drv_la_SOURCES = \ + i128accel.c \ + i128dga.c \ + i128exa.c \ + i128_driver.c \ + i128.h \ + i128IBMDAC.c \ + i128init.c \ + i128reg.h \ + IBMRGB.h \ + Ti302X.h diff --git a/driver/xf86-video-i128/src/Makefile.in b/driver/xf86-video-i128/src/Makefile.in new file mode 100644 index 000000000..b1702b519 --- /dev/null +++ b/driver/xf86-video-i128/src/Makefile.in @@ -0,0 +1,526 @@ +# 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)$(i128_drv_ladir)" +i128_drv_laLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(i128_drv_la_LTLIBRARIES) +i128_drv_la_LIBADD = +am_i128_drv_la_OBJECTS = i128accel.lo i128dga.lo i128exa.lo \ + i128_driver.lo i128IBMDAC.lo i128init.lo +i128_drv_la_OBJECTS = $(am_i128_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 = $(i128_drv_la_SOURCES) +DIST_SOURCES = $(i128_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@ +BUILD_LINUXDOC_FALSE = @BUILD_LINUXDOC_FALSE@ +BUILD_LINUXDOC_TRUE = @BUILD_LINUXDOC_TRUE@ +BUILD_PDFDOC_FALSE = @BUILD_PDFDOC_FALSE@ +BUILD_PDFDOC_TRUE = @BUILD_PDFDOC_TRUE@ +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@ +LINUXDOC = @LINUXDOC@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +MAKE_HTML = @MAKE_HTML@ +MAKE_PDF = @MAKE_PDF@ +MAKE_PS = @MAKE_PS@ +MAKE_TEXT = @MAKE_TEXT@ +MISC_MAN_DIR = @MISC_MAN_DIR@ +MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ +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@ +PS2PDF = @PS2PDF@ +RANLIB = @RANLIB@ +SED = @SED@ +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@ +i128_drv_la_LTLIBRARIES = i128_drv.la +i128_drv_la_LDFLAGS = -module -avoid-version +i128_drv_ladir = @moduledir@/drivers +i128_drv_la_SOURCES = \ + i128accel.c \ + i128dga.c \ + i128exa.c \ + i128_driver.c \ + i128.h \ + i128IBMDAC.c \ + i128init.c \ + i128reg.h \ + IBMRGB.h \ + Ti302X.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-i128_drv_laLTLIBRARIES: $(i128_drv_la_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(i128_drv_ladir)" || $(mkdir_p) "$(DESTDIR)$(i128_drv_ladir)" + @list='$(i128_drv_la_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(i128_drv_laLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(i128_drv_ladir)/$$f'"; \ + $(LIBTOOL) --mode=install $(i128_drv_laLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(i128_drv_ladir)/$$f"; \ + else :; fi; \ + done + +uninstall-i128_drv_laLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @set -x; list='$(i128_drv_la_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(i128_drv_ladir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(i128_drv_ladir)/$$p"; \ + done + +clean-i128_drv_laLTLIBRARIES: + -test -z "$(i128_drv_la_LTLIBRARIES)" || rm -f $(i128_drv_la_LTLIBRARIES) + @list='$(i128_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 +i128_drv.la: $(i128_drv_la_OBJECTS) $(i128_drv_la_DEPENDENCIES) + $(LINK) -rpath $(i128_drv_ladir) $(i128_drv_la_LDFLAGS) $(i128_drv_la_OBJECTS) $(i128_drv_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i128IBMDAC.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i128_driver.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i128accel.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i128dga.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i128exa.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i128init.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)$(i128_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-i128_drv_laLTLIBRARIES clean-libtool \ + 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-i128_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-i128_drv_laLTLIBRARIES uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-i128_drv_laLTLIBRARIES clean-libtool 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-i128_drv_laLTLIBRARIES install-info \ + install-info-am install-man 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-i128_drv_laLTLIBRARIES \ + uninstall-info-am + +# 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-i128/src/Ti302X.h b/driver/xf86-video-i128/src/Ti302X.h new file mode 100644 index 000000000..a03835aae --- /dev/null +++ b/driver/xf86-video-i128/src/Ti302X.h @@ -0,0 +1,209 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/Ti302X.h,v 1.2 2001/03/03 22:26:11 tsi Exp $ */ +/* + * Copyright 1994-2000 by Robin Cutshaw <robin@XFree86.Org> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Robin Cutshaw not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Robin Cutshaw makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ROBIN CUTSHAW DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ROBIN CUTSHAW 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. + * + */ +/* $XConsortium: $ */ + +#include "compiler.h" + +/* Indirect indexed registers */ + +#define TI_CURS_X_LOW 0x00 +#define TI_CURS_X_HIGH 0x01 /* only lower 4 bits are used */ +#define TI_CURS_Y_LOW 0x02 +#define TI_CURS_Y_HIGH 0x03 /* only lower 4 bits are used */ +#define TI_SPRITE_ORIGIN_X 0x04 +#define TI_SPRITE_ORIGIN_Y 0x05 +#define TI_CURS_CONTROL 0x06 +#define TI_PLANAR_ACCESS 0x80 /* 3025 only - 80 == BT485 mode */ +#define TI_CURS_SPRITE_ENABLE 0x40 +#define TI_CURS_X_WINDOW_MODE 0x10 +#define TI_CURS_CTRL_MASK (TI_CURS_SPRITE_ENABLE | TI_CURS_X_WINDOW_MODE) +#define TI_CURS_RAM_ADDR_LOW 0x08 +#define TI_CURS_RAM_ADDR_HIGH 0x09 +#define TI_CURS_RAM_DATA 0x0A +#define TI_TRUE_COLOR_CONTROL 0x0E /* 3025 only */ +#define TI_TC_BTMODE 0x04 /* on = BT485 mode, off = TI3020 mode */ +#define TI_TC_NONVGAMODE 0x02 /* on = nonvgamode, off = vgamode */ +#define TI_TC_8BIT 0x01 /* on = 8/4bit, off = 16/32bit */ +#define TI_VGA_SWITCH_CONTROL 0x0F /* 3025 only */ +#define TI_LATCH_CONTROL 0x0F /* 3026 only */ +#define TI_WINDOW_START_X_LOW 0x10 +#define TI_WINDOW_START_X_HIGH 0x11 +#define TI_WINDOW_STOP_X_LOW 0x12 +#define TI_WINDOW_STOP_X_HIGH 0x13 +#define TI_WINDOW_START_Y_LOW 0x14 +#define TI_WINDOW_START_Y_HIGH 0x15 +#define TI_WINDOW_STOP_Y_LOW 0x16 +#define TI_WINDOW_STOP_Y_HIGH 0x17 +#define TI_MUX_CONTROL_1 0x18 +#define TI_MUX1_PSEUDO_COLOR 0x80 +#define TI_MUX1_DIRECT_888 0x06 +#define TI_MUX1_DIRECT_565 0x05 +#define TI_MUX1_DIRECT_555 0x04 +#define TI_MUX1_DIRECT_664 0x03 +#define TI_MUX1_TRUE_888 0x46 +#define TI_MUX1_TRUE_565 0x45 +#define TI_MUX1_TRUE_555 0x44 +#define TI_MUX1_TRUE_664 0x43 +#define TI_MUX1_3025D_888 0x0E /* 3025 only */ +#define TI_MUX1_3025D_565 0x0D /* 3025 only */ +#define TI_MUX1_3025D_555 0x0C /* 3025 only */ +#define TI_MUX1_3025T_888 0x4E /* 3025 only */ +#define TI_MUX1_3025T_565 0x4D /* 3025 only */ +#define TI_MUX1_3025T_555 0x4C /* 3025 only */ +#define TI_MUX1_3026D_888 0x06 /* 3026 only */ +#define TI_MUX1_3026D_565 0x05 /* 3026 only */ +#define TI_MUX1_3026D_555 0x04 /* 3026 only */ +#define TI_MUX1_3026D_888_P8 0x16 /* 3026 only */ +#define TI_MUX1_3026D_888_P5 0x1e /* 3026 only */ +#define TI_MUX1_3026T_888 0x46 /* 3026 only */ +#define TI_MUX1_3026T_565 0x45 /* 3026 only */ +#define TI_MUX1_3026T_555 0x44 /* 3026 only */ +#define TI_MUX1_3026T_888_P8 0x56 /* 3026 only */ +#define TI_MUX1_3026T_888_P5 0x5e /* 3026 only */ +#define TI_MUX_CONTROL_2 0x19 +#define TI_MUX2_BUS_VGA 0x98 +#define TI_MUX2_BUS_PC_D8P64 0x1C +#define TI_MUX2_BUS_DC_D24P64 0x1C +#define TI_MUX2_BUS_DC_D16P64 0x04 +#define TI_MUX2_BUS_DC_D15P64 0x04 +#define TI_MUX2_BUS_TC_D24P64 0x04 +#define TI_MUX2_BUS_TC_D16P64 0x04 +#define TI_MUX2_BUS_TC_D15P64 0x04 +#define TI_MUX2_BUS_3026PC_D8P64 0x4C +#define TI_MUX2_BUS_3026DC_D24P64 0x5C +#define TI_MUX2_BUS_3026DC_D16P64 0x54 +#define TI_MUX2_BUS_3026DC_D15P64 0x54 +#define TI_MUX2_BUS_3026TC_D24P64 0x5c +#define TI_MUX2_BUS_3026TC_D16P64 0x54 +#define TI_MUX2_BUS_3026TC_D15P64 0x54 +#define TI_MUX2_BUS_3030PC_D8P128 0x4d +#define TI_MUX2_BUS_3030DC_D24P128 0x5d +#define TI_MUX2_BUS_3030DC_D16P128 0x55 +#define TI_MUX2_BUS_3030DC_D15P128 0x55 +#define TI_MUX2_BUS_3030TC_D24P128 0x5d +#define TI_MUX2_BUS_3030TC_D16P128 0x55 +#define TI_MUX2_BUS_3030TC_D15P128 0x55 +#define TI_INPUT_CLOCK_SELECT 0x1A +#define TI_ICLK_CLK0 0x00 +#define TI_ICLK_CLK0_DOUBLE 0x10 +#define TI_ICLK_CLK1 0x01 +#define TI_ICLK_CLK1_DOUBLE 0x11 +#define TI_ICLK_CLK2 0x02 /* 3025 only */ +#define TI_ICLK_CLK2_DOUBLE 0x12 /* 3025 only */ +#define TI_ICLK_CLK2_I 0x03 /* 3025 only */ +#define TI_ICLK_CLK2_I_DOUBLE 0x13 /* 3025 only */ +#define TI_ICLK_CLK2_E 0x04 /* 3025 only */ +#define TI_ICLK_CLK2_E_DOUBLE 0x14 /* 3025 only */ +#define TI_ICLK_PLL 0x05 /* 3025 only */ +#define TI_OUTPUT_CLOCK_SELECT 0x1B +#define TI_OCLK_VGA 0x3E +#define TI_OCLK_S 0x40 +#define TI_OCLK_NS 0x80 /* 3025 only */ +#define TI_OCLK_V1 0x00 +#define TI_OCLK_V2 0x08 +#define TI_OCLK_V4 0x10 +#define TI_OCLK_V8 0x18 +#define TI_OCLK_R1 0x00 +#define TI_OCLK_R2 0x01 +#define TI_OCLK_R4 0x02 +#define TI_OCLK_R8 0x03 +#define TI_OCLK_S_V1_R8 (TI_OCLK_S | TI_OCLK_V1 | TI_OCLK_R8) +#define TI_OCLK_S_V2_R8 (TI_OCLK_S | TI_OCLK_V2 | TI_OCLK_R8) +#define TI_OCLK_S_V4_R8 (TI_OCLK_S | TI_OCLK_V4 | TI_OCLK_R8) +#define TI_OCLK_S_V8_R8 (TI_OCLK_S | TI_OCLK_V8 | TI_OCLK_R8) +#define TI_OCLK_S_V2_R4 (TI_OCLK_S | TI_OCLK_V2 | TI_OCLK_R4) +#define TI_OCLK_S_V4_R4 (TI_OCLK_S | TI_OCLK_V4 | TI_OCLK_R4) +#define TI_OCLK_S_V1_R2 (TI_OCLK_S | TI_OCLK_V1 | TI_OCLK_R2) +#define TI_OCLK_S_V2_R2 (TI_OCLK_S | TI_OCLK_V2 | TI_OCLK_R2) +#define TI_OCLK_NS_V1_R1 (TI_OCLK_NS | TI_OCLK_V1 | TI_OCLK_R1) +#define TI_OCLK_NS_V2_R2 (TI_OCLK_NS | TI_OCLK_V2 | TI_OCLK_R2) +#define TI_OCLK_NS_V4_R4 (TI_OCLK_NS | TI_OCLK_V4 | TI_OCLK_R4) +#define TI_PALETTE_PAGE 0x1C +#define TI_GENERAL_CONTROL 0x1D +#define TI_MISC_CONTROL 0x1E /* 3025 only */ +#define TI_MC_POWER_DOWN 0x01 +#define TI_MC_DOTCLK_DISABLE 0x02 +#define TI_MC_INT_6_8_CONTROL 0x04 /* 00 == external 6/8 pin */ +#define TI_MC_8_BPP 0x08 /* 00 == 6bpp */ +#define TI_MC_PSEL_POLARITY 0x20 /* 3026 only, PSEL polarity select */ +#define TI_MC_VCLK_POLARITY 0x20 +#define TI_MC_LCLK_LATCH 0x40 /* VCLK == 00, default */ +#define TI_MC_LOOP_PLL_RCLK 0x80 +#define TI_OVERSCAN_COLOR_RED 0x20 +#define TI_OVERSCAN_COLOR_GREEN 0x21 +#define TI_OVERSCAN_COLOR_BLUE 0x22 +#define TI_CURSOR_COLOR_0_RED 0x23 +#define TI_CURSOR_COLOR_0_GREEN 0x24 +#define TI_CURSOR_COLOR_0_BLUE 0x25 +#define TI_CURSOR_COLOR_1_RED 0x26 +#define TI_CURSOR_COLOR_1_GREEN 0x27 +#define TI_CURSOR_COLOR_1_BLUE 0x28 +#define TI_AUXILIARY_CONTROL 0x29 +#define TI_AUX_SELF_CLOCK 0x08 +#define TI_AUX_W_CMPL 0x01 +#define TI_GENERAL_IO_CONTROL 0x2A +#define TI_GIC_ALL_BITS 0x1F +#define TI_GENERAL_IO_DATA 0x2B +#define TI_GID_W2000_6BIT 0x00 +#define TI_GID_N9_964 0x01 +#define TI_GID_ELSA_SOG 0x04 +#define TI_GID_W2000_8BIT 0x08 +#define TI_GID_S3_DAC_6BIT 0x1C +#define TI_GID_S3_DAC_8BIT 0x1E +#define TI_GID_TI_DAC_6BIT 0x1D +#define TI_GID_TI_DAC_8BIT 0x1F +#define TI_PLL_CONTROL 0x2C /* 3025 only */ +#define TI_PIXEL_CLOCK_PLL_DATA 0x2D /* 3025 only */ +#define TI_PLL_ENABLE 0x08 /* 3025 only */ +#define TI_MCLK_PLL_DATA 0x2E /* 3025 only */ +#define TI_LOOP_CLOCK_PLL_DATA 0x2F /* 3025 only */ +#define TI_COLOR_KEY_OLVGA_LOW 0x30 +#define TI_COLOR_KEY_OLVGA_HIGH 0x31 +#define TI_COLOR_KEY_RED_LOW 0x32 +#define TI_COLOR_KEY_RED_HIGH 0x33 +#define TI_COLOR_KEY_GREEN_LOW 0x34 +#define TI_COLOR_KEY_GREEN_HIGH 0x35 +#define TI_COLOR_KEY_BLUE_LOW 0x36 +#define TI_COLOR_KEY_BLUE_HIGH 0x37 +#define TI_COLOR_KEY_CONTROL 0x38 +#define TI_COLOR_KEY_CMPL 0x10 +#define TI_MCLK_DCLK_CONTROL 0x39 /* 3025 only */ +#define TI_MCLK_LCLK_CONTROL 0x39 /* 3026 only */ +#define TI_SENSE_TEST 0x3A +#define TI_TEST_DATA 0x3B +#define TI_CRC_LOW 0x3C +#define TI_CRC_HIGH 0x3D +#define TI_CRC_CONTROL 0x3E +#define TI_ID 0x3F +#define TI_VIEWPOINT20_ID 0x20 +#define TI_VIEWPOINT25_ID 0x25 +#define TI_MODE_85_CONTROL 0xD5 /* 3025 only */ + +#define TI_REF_FREQ 14.31818 /* 3025 only */ + +/* + * which clocks should be set (just flags...) + */ +#define TI_BOTH_CLOCKS 1 +#define TI_LOOP_CLOCK 2 diff --git a/driver/xf86-video-i128/src/i128.h b/driver/xf86-video-i128/src/i128.h new file mode 100644 index 000000000..24d53b8d6 --- /dev/null +++ b/driver/xf86-video-i128/src/i128.h @@ -0,0 +1,167 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128.h,v 1.5 2001/04/01 14:00:11 tsi Exp $ */ +/* + * Number Nine I128 functions + * + * Copyright 1996 The XFree86 Project, Inc. + * + * Author + * Robin Cutshaw + * robin@XFree86.Org + */ + +#ifndef I128_H +#define I128_H + +#include "compiler.h" +#include "xaa.h" +#include "exa.h" +#include "xf86Cursor.h" +#include "vgaHW.h" +#include "colormapst.h" +#include "xf86DDC.h" +#include "i128reg.h" + +struct source_format { + int render_format; + int i128_format; + int swap_flags; + int ignore_alpha; +}; + +/* Card-specific driver information */ + +#define I128PTR(p) ((I128Ptr)((p)->driverPrivate)) + +typedef struct { + EntityInfoPtr pEnt; + pciVideoPtr PciInfo; + PCITAG PciTag; + xf86AccessRec Access; + int Chipset; + int ChipRev; + Bool Primary; + + /* Ramdac specific */ + int RamdacType; + Bool DAC8Bit; + Bool DACSyncOnGreen; + int hotX; + int hotY; + Bool HWCursor; + Bool BlockCursor; + Bool ReloadCursor; + Bool CursorNeedsInit; + int CursorStartX; + int CursorStartY; + int CursorLines; + int AdjustCursorXPos; + int CursGeneration; + + /* layout specific */ + int bitsPerPixel; + int depth; + rgb weight; + int displayWidth; + int displayOffset; + DisplayModePtr mode; + + /* accel specific */ + CARD32 buf_ctrl; + CARD32 blitdir; + CARD32 planemask; + CARD32 cmd; + CARD32 rop; /* XXX XAA only */ + CARD32 clptl; + CARD32 clpbr; + CARD32 sorg; + CARD32 sptch; + CARD32 dorg; + CARD32 dptch; + CARD32 wh; + CARD32 torg; + CARD32 tptch; + CARD32 tex_ctl; + CARD32 threedctl; + CARD32 acntrl; + struct source_format *source; + /* struct dest_format *dest; */ + + Bool NoAccel; + Bool exa; + Bool FlatPanel; + Bool DoubleScan; + Bool ShowCache; + Bool ModeSwitched; + Bool Debug; + unsigned char *MemoryPtr; + int MemorySize; + int MemoryType; + volatile struct i128mem mem; + struct i128io io; + I128RegRec RegRec; + Bool StateSaved; + Bool Initialized; + Bool FontsSaved; + Bool LUTSaved; + Bool InitCursorFlag; + LUTENTRY lutorig[256]; + LUTENTRY lutcur[256]; + int HDisplay; + int maxClock; + int minClock; + + CloseScreenProcPtr CloseScreen; + XAAInfoRecPtr XaaInfoRec; + ExaDriverPtr ExaDriver; + xf86CursorInfoPtr CursorInfoRec; + I2CBusPtr I2C; + Bool DGAactive; + int DGAViewportStatus; + int numDGAModes; + DGAModePtr DGAModes; + Bool (*ProgramDAC)(ScrnInfoPtr, DisplayModePtr); + unsigned int (*ddc1Read)(ScrnInfoPtr); + Bool (*i2cInit)(ScrnInfoPtr); + + OptionInfoPtr Options; + +} I128Rec, *I128Ptr; + + +/* Prototypes */ + +void I128AdjustFrame(int scrnIndex, int x, int y, int flags); +Bool I128SwitchMode(int scrnIndex, DisplayModePtr mode, int flags); + +Bool I128HWCursorInit(ScreenPtr pScreen); + +Bool I128XaaInit(ScreenPtr pScreen); +Bool I128ExaInit(ScreenPtr pScreen); +void I128EngineDone(ScrnInfoPtr pScrn); + +Bool I128Init(ScrnInfoPtr pScrn, DisplayModePtr mode); + +Bool I128DGAInit(ScreenPtr pScreen); + +void I128LoadPalette(ScrnInfoPtr pScrn, int numColors, + int *indices, LOCO *colors, VisualPtr pVisual); + +void I128SaveState(ScrnInfoPtr pScrn); +void I128RestoreState(ScrnInfoPtr pScrn); +void I128InitLUT(I128Ptr pI128); + +Bool I128RestoreCursor(ScrnInfoPtr pScrn); +Bool I128RepositionCursor(ScrnInfoPtr pScrn); + +Bool I128IBMHWCursorInit(ScrnInfoPtr pScrn); +Bool I128TIHWCursorInit(ScrnInfoPtr pScrn); + +Bool I128ProgramTi3025(ScrnInfoPtr pScrn, DisplayModePtr mode); +Bool I128ProgramIBMRGB(ScrnInfoPtr pScrn, DisplayModePtr mode); +Bool I128ProgramSilverHammer(ScrnInfoPtr pScrn, DisplayModePtr mode); + +/* void I128DumpBaseRegisters(ScrnInfoPtr pScrn); */ +void I128DumpActiveRegisters(ScrnInfoPtr pScrn); +/* void I128DumpIBMDACRegisters(ScrnInfoPtr pScrn, volatile CARD32 *vrbg); */ + +#endif diff --git a/driver/xf86-video-i128/src/i128IBMDAC.c b/driver/xf86-video-i128/src/i128IBMDAC.c new file mode 100644 index 000000000..5616d7116 --- /dev/null +++ b/driver/xf86-video-i128/src/i128IBMDAC.c @@ -0,0 +1,737 @@ +/* + * Copyright 1996-2000 by Robin Cutshaw <robin@XFree86.Org> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Robin Cutshaw not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Robin Cutshaw makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ROBIN CUTSHAW DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ROBIN CUTSHAW 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. + * + */ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128IBMDAC.c,v 1.3tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "cursorstr.h" +#include "servermd.h" + +#include "i128.h" +#include "i128reg.h" +#include "IBMRGB.h" + + +static void I128IBMShowCursor(ScrnInfoPtr pScrn); +static void I128IBMHideCursor(ScrnInfoPtr pScrn); +static void I128IBMSetCursorPosition(ScrnInfoPtr pScrn, int x, int y); +static void I128IBMSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); +static void I128IBMLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src); +static unsigned char *I128IBMRealizeCursor(xf86CursorInfoPtr infoPtr, + CursorPtr pCurs); +static Bool I128IBMUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs); + + +Bool +I128IBMHWCursorInit(ScrnInfoPtr pScrn) +{ + xf86CursorInfoPtr infoPtr; + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + I128Ptr pI128 = I128PTR(pScrn); + + if (!pI128->HWCursor) + return FALSE; + + infoPtr = xf86CreateCursorInfoRec(); + if (!infoPtr) return FALSE; + + pI128->CursorInfoRec = infoPtr; + infoPtr->MaxWidth = 64; + infoPtr->MaxHeight = 64; + infoPtr->SetCursorColors = I128IBMSetCursorColors; + infoPtr->SetCursorPosition = I128IBMSetCursorPosition; + infoPtr->LoadCursorImage = I128IBMLoadCursorImage; + infoPtr->HideCursor = I128IBMHideCursor; + infoPtr->ShowCursor = I128IBMShowCursor; + infoPtr->UseHWCursor = I128IBMUseHWCursor; + infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | + HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1; + infoPtr->RealizeCursor = I128IBMRealizeCursor; + + return(xf86InitCursor(pScreen, infoPtr)); +} + + +/* + * Convert the cursor from server-format to hardware-format. The IBMRGB + * has two planes, plane 0 selects cursor color 0 or 1 and plane 1 + * selects transparent or display cursor. The bits of these planes + * are packed together so that one byte has 4 pixels. The organization + * looks like: + * Byte 0x000 - 0x00F top scan line, left to right + * 0x010 - 0x01F + * . . + * 0x3F0 - 0x3FF bottom scan line + * + * Byte/bit map - D7D6,D5D4,D3D2,D1D0 four pixels, two planes each + * Pixel/bit map - P1P0 (plane 1) == 1 maps to cursor color + * (plane 1) == 0 maps to transparent + * (plane 0) maps to cursor colors 0 and 1 + */ + +static unsigned char * +I128IBMRealizeCursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) +{ + register int i, j; + unsigned char *pServMsk; + unsigned char *pServSrc; + int wsrc, h; + unsigned char *mem, *dst; + + mem = (unsigned char *)xcalloc(1,1024); /* 64x64x2 bits */ + dst = mem; + + if (!mem) + return NULL; + + pServSrc = (unsigned char *)pCurs->bits->source; + pServMsk = (unsigned char *)pCurs->bits->mask; + + h = pCurs->bits->height; + if (h > infoPtr->MaxHeight) + h = infoPtr->MaxHeight; + + wsrc = PixmapBytePad(pCurs->bits->width, 1); /* bytes per line */ + + for (i = 0; i < infoPtr->MaxHeight; i++,mem+=16) { + for (j = 0; j < infoPtr->MaxWidth / 8; j++) { + register unsigned char mask, source; + + if (i < h && j < wsrc) { + /* + * mask byte ABCDEFGH and source byte 12345678 map to two byte + * cursor data H8G7F6E5 D4C3B2A1 + */ + mask = *pServMsk++; + source = *pServSrc++ & mask; + + /* map 1 byte source and mask into two byte cursor data */ + mem[j*2] = ((mask&0x01) << 7) | ((source&0x01) << 6) | + ((mask&0x02) << 4) | ((source&0x02) << 3) | + ((mask&0x04) << 1) | (source&0x04) | + ((mask&0x08) >> 2) | ((source&0x08) >> 3) ; + mem[(j*2)+1] = ((mask&0x10) << 3) | ((source&0x10) << 2) | + (mask&0x20) | ((source&0x20) >> 1) | + ((mask&0x40) >> 3) | ((source&0x40) >> 4) | + ((mask&0x80) >> 6) | ((source&0x80) >> 7) ; + } else { + mem[j*2] = 0x00; + mem[(j*2)+1] = 0x00; + } + } + /* + * if we still have more bytes on this line (j < wsrc), + * we have to ignore the rest of the line. + */ + while (j++ < wsrc) pServMsk++,pServSrc++; + } + return dst; +} + + +static void +I128IBMShowCursor(ScrnInfoPtr pScrn) +{ + CARD32 tmpl, tmph; + I128Ptr pI128 = I128PTR(pScrn); + + /* Enable cursor - X11 mode */ + tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF; + tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF; + pI128->mem.rbase_g[IDXCTL_I] = 0; MB; + pI128->mem.rbase_g[IDXH_I] = 0; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs; MB; + pI128->mem.rbase_g[DATA_I] = 0x27; MB; + + pI128->mem.rbase_g[IDXH_I] = tmph; MB; + pI128->mem.rbase_g[IDXL_I] = tmpl; MB; + + return; +} + +static void +I128IBMHideCursor(ScrnInfoPtr pScrn) +{ + CARD32 tmpl, tmph, tmp1; + I128Ptr pI128 = I128PTR(pScrn); + + tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF; + tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF; + pI128->mem.rbase_g[IDXCTL_I] = 0; MB; + pI128->mem.rbase_g[IDXH_I] = 0; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs; MB; + tmp1 = pI128->mem.rbase_g[DATA_I] & 0xFC; + pI128->mem.rbase_g[DATA_I] = tmp1; MB; + + pI128->mem.rbase_g[IDXH_I] = tmph; MB; + pI128->mem.rbase_g[IDXL_I] = tmpl; MB; + + return; +} + +static void +I128IBMSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +{ + CARD32 tmpl, tmph; + I128Ptr pI128 = I128PTR(pScrn); + + x += 64; + y += 64; + + tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF; + tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF; + + pI128->mem.rbase_g[IDXH_I] = 0; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_hot_x; MB; + pI128->mem.rbase_g[DATA_I] = 0x3F; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_hot_y; MB; + pI128->mem.rbase_g[DATA_I] = 0x3F; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_xl; MB; + pI128->mem.rbase_g[DATA_I] = x & 0xFF; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_xh; MB; + pI128->mem.rbase_g[DATA_I] = (x >> 8) & 0x0F; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_yl; MB; + pI128->mem.rbase_g[DATA_I] = y & 0xFF; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_yh; MB; + pI128->mem.rbase_g[DATA_I] = (y >> 8) & 0x0F; MB; + + pI128->mem.rbase_g[IDXH_I] = tmph; MB; + pI128->mem.rbase_g[IDXL_I] = tmpl; MB; + + return; +} + +static void +I128IBMSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) +{ + CARD32 tmp; + I128Ptr pI128 = I128PTR(pScrn); + + tmp = pI128->mem.rbase_g[IDXL_I] & 0xFF; + + /* Background color */ + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col1_r; MB; + pI128->mem.rbase_g[DATA_I] = (bg & 0x00FF0000) >> 16; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col1_g; MB; + pI128->mem.rbase_g[DATA_I] = (bg & 0x0000FF00) >> 8; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col1_b; MB; + pI128->mem.rbase_g[DATA_I] = (bg & 0x000000FF); MB; + + /* Foreground color */ + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col2_r; MB; + pI128->mem.rbase_g[DATA_I] = (fg & 0x00FF0000) >> 16; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col2_g; MB; + pI128->mem.rbase_g[DATA_I] = (fg & 0x0000FF00) >> 8; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_col2_b; MB; + pI128->mem.rbase_g[DATA_I] = (fg & 0x000000FF); MB; + + pI128->mem.rbase_g[IDXL_I] = tmp; MB; + + return; +} + +static void +I128IBMLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) +{ + I128Ptr pI128 = I128PTR(pScrn); + register int i; + CARD32 tmph, tmpl, tmpc; + + tmpc = pI128->mem.rbase_g[IDXCTL_I] & 0xFF; + tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF; + tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF; + + pI128->BlockCursor = TRUE; + + pI128->mem.rbase_g[IDXCTL_I] = 0; MB; + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_hot_x; MB; + pI128->mem.rbase_g[DATA_I] = 0x00; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_hot_y; MB; + pI128->mem.rbase_g[DATA_I] = 0x00; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_xl; MB; + pI128->mem.rbase_g[DATA_I] = 0xFF; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_xh; MB; + pI128->mem.rbase_g[DATA_I] = 0x7F; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_yl; MB; + pI128->mem.rbase_g[DATA_I] = 0xFF; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_yh; MB; + pI128->mem.rbase_g[DATA_I] = 0x7F; MB; + + pI128->mem.rbase_g[IDXH_I] = (IBMRGB_curs_array >> 8) & 0xFF; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_curs_array & 0xFF; MB; + + pI128->mem.rbase_g[IDXCTL_I] = 1; /* enable auto-inc */ MB; + + /* + * Output the cursor data. The realize function has put the planes into + * their correct order, so we can just blast this out. + */ + for (i = 0; i < 1024; i++,src++) { + pI128->mem.rbase_g[DATA_I] = (CARD32 )*src; MB; + } + + pI128->mem.rbase_g[IDXCTL_I] = tmpc; MB; + pI128->mem.rbase_g[IDXH_I] = tmph; MB; + pI128->mem.rbase_g[IDXL_I] = tmpl; MB; + + pI128->BlockCursor = FALSE; + + return; +} + + +static Bool +I128IBMUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs) +{ + if( XF86SCRNINFO(pScrn)->currentMode->Flags & V_DBLSCAN ) + return FALSE; + return TRUE; +} + + +Bool I128TIHWCursorInit(ScrnInfoPtr pScrn) { return FALSE; } +Bool I128ProgramTi3025(ScrnInfoPtr pScrn, DisplayModePtr mode) { return FALSE; } + +Bool +I128ProgramIBMRGB(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + I128Ptr pI128 = I128PTR(pScrn); + unsigned char tmp2, m, n, df, best_m, best_n, best_df, max_n; + CARD32 tmpl, tmph, tmpc; + long f, vrf, outf, best_diff, best_outf = 0, diff; + long requested_freq; + int freq = mode->SynthClock; + int flags = mode->Flags; + +#define REF_FREQ 25175000 +#define MAX_VREF 3380000 +/* Actually, MIN_VREF can be as low as 1000000; + * this allows clock speeds down to 17 MHz */ +#define MIN_VREF 1500000 +#define MAX_VCO 220000000 +#define MIN_VCO 65000000 + + if (freq < 25000) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Specified dot clock (%.3f) too low for IBM RGB52x", + freq / 1000.0); + return(FALSE); + } else if (freq > MAX_VCO) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Specified dot clock (%.3f) too high for IBM RGB52x", + freq / 1000.0); + return(FALSE); + } + + requested_freq = freq * 1000; + + best_m = best_n = best_df = 0; + best_diff = requested_freq; /* worst case */ + + for (df=0; df<4; df++) { + max_n = REF_FREQ / MIN_VREF; + if (df < 3) + max_n >>= 1; + for (n=2; n<max_n; n++) + for (m=65; m<=128; m++) { + vrf = REF_FREQ / n; + if (df < 3) + vrf >>= 1; + if ((vrf > MAX_VREF) || (vrf < MIN_VREF)) + continue; + + f = vrf * m; + outf = f; + if (df < 2) + outf >>= 2 - df; + if ((f > MAX_VCO) || (f < MIN_VCO)) + continue; + + /* outf is a valid freq, pick the closest now */ + + if ((diff = (requested_freq - outf)) < 0) + diff = -diff;; + if (diff < best_diff) { + best_diff = diff; + best_m = m; + best_n = n; + best_df = df; + best_outf = outf; + } + } + } + + /* do we have an acceptably close frequency? (less than 1% diff) */ + + if (best_diff > (requested_freq/100)) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Specified dot clock (%.3f) too far (best %.3f) IBM RGB52x", + requested_freq / 1000.0, best_outf / 1000.0); + return(FALSE); + } + + pI128->mem.rbase_g[PEL_MASK] = 0xFF; MB; + + tmpc = pI128->mem.rbase_g[IDXCTL_I] & 0xFF; + tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF; + tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF; + + pI128->mem.rbase_g[IDXH_I] = 0; MB; + pI128->mem.rbase_g[IDXCTL_I] = 0; MB; + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc_clock; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF; + pI128->mem.rbase_g[DATA_I] = tmp2 | 0x81; MB; + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0+4; MB; + pI128->mem.rbase_g[DATA_I] = (best_df<<6) | (best_m&0x3f); MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_n0+4; MB; + pI128->mem.rbase_g[DATA_I] = best_n; MB; + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pll_ctrl1; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF; + pI128->mem.rbase_g[DATA_I] = (tmp2&0xf8) | 3; /* 8 M/N pairs in PLL */ MB; + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pll_ctrl2; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF; + pI128->mem.rbase_g[DATA_I] = (tmp2&0xf0) | 2; /* clock number 2 */ MB; + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc_clock; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf0; + pI128->mem.rbase_g[DATA_I] = tmp2 | ((flags & V_DBLCLK) ? 0x03 : 0x01); MB; + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sync; MB; + pI128->mem.rbase_g[DATA_I] = ((flags & V_PHSYNC) ? 0x10 : 0x00) + | ((flags & V_PVSYNC) ? 0x20 : 0x00); MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_hsync_pos; MB; + pI128->mem.rbase_g[DATA_I] = 0x01; /* Delay syncs by 1 pclock */ MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pwr_mgmt; MB; + pI128->mem.rbase_g[DATA_I] = 0x00; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_dac_op; MB; + tmp2 = (pI128->RamdacType == IBM528_DAC) ? 0x02 : 0x00; /* fast slew */ + if (pI128->DACSyncOnGreen) tmp2 |= 0x08; + pI128->mem.rbase_g[DATA_I] = tmp2; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pal_ctrl; MB; + pI128->mem.rbase_g[DATA_I] = 0x00; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk; MB; + pI128->mem.rbase_g[DATA_I] = 0x01; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc1; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xbc; + tmp2 |= 0x20; + if ((pI128->MemoryType != I128_MEMORY_DRAM) && + (pI128->MemoryType != I128_MEMORY_SGRAM)) + tmp2 |= (pI128->RamdacType == IBM528_DAC) ? 3 : 1; + pI128->mem.rbase_g[DATA_I] = tmp2; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc2; MB; + tmp2 = 0x03; + if (pI128->DAC8Bit) + tmp2 |= 0x04; + if (!((pI128->MemoryType == I128_MEMORY_DRAM) && + (pI128->bitsPerPixel > 16))) + tmp2 |= 0x40; + if ((pI128->MemoryType == I128_MEMORY_SGRAM) && + (pI128->bitsPerPixel > 16) && + (pI128->RamdacType != SILVER_HAMMER_DAC) ) + tmp2 &= 0x3F; + pI128->mem.rbase_g[DATA_I] = tmp2; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc3; MB; + pI128->mem.rbase_g[DATA_I] = 0x00; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc4; MB; + pI128->mem.rbase_g[DATA_I] = 0x00; MB; + + /* ?? There is no write to cursor control register */ + + if (pI128->RamdacType == IBM526_DAC) { + if (pI128->MemoryType == I128_MEMORY_SGRAM) { + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div; MB; + pI128->mem.rbase_g[DATA_I] = 0x09; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div; MB; + pI128->mem.rbase_g[DATA_I] = 0x83; MB; + } else { + /* program mclock to 52MHz */ + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div; MB; + pI128->mem.rbase_g[DATA_I] = 0x08; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div; MB; + pI128->mem.rbase_g[DATA_I] = 0x41; MB; + } + /* should delay at least a millisec so we'll wait 50 */ + usleep(50000); + } + + switch (pI128->depth) { + case 24: /* 32 bit */ + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8; + pI128->mem.rbase_g[DATA_I] = tmp2 | 0x06; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_32bpp; MB; + pI128->mem.rbase_g[DATA_I] = 0x03; MB; + break; + case 16: + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8; + pI128->mem.rbase_g[DATA_I] = tmp2 | 0x04; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_16bpp; MB; + pI128->mem.rbase_g[DATA_I] = 0xC7; MB; + break; + case 15: + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8; + pI128->mem.rbase_g[DATA_I] = tmp2 | 0x04; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_16bpp; MB; + pI128->mem.rbase_g[DATA_I] = 0xC5; MB; + break; + default: /* 8 bit */ + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8; + pI128->mem.rbase_g[DATA_I] = tmp2 | 0x03; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_8bpp; MB; + pI128->mem.rbase_g[DATA_I] = 0x00; MB; + break; + } + + pI128->mem.rbase_g[IDXCTL_I] = tmpc; MB; + pI128->mem.rbase_g[IDXH_I] = tmph; MB; + pI128->mem.rbase_g[IDXL_I] = tmpl; MB; + + return(TRUE); +} + + +Bool +I128ProgramSilverHammer(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + /* The SilverHammer DAC is essentially the same as the IBMRGBxxx DACs, + * but with fewer options and a different reference frequency. + */ + + I128Ptr pI128 = I128PTR(pScrn); + unsigned char tmp2, m, n, df, best_m, best_n, best_df, max_n; + CARD32 tmpl, tmph, tmpc; + long f, vrf, outf, best_diff, best_outf = 0, diff; + long requested_freq; + int freq = mode->SynthClock; + int flags = mode->Flags; + int skew = mode->HSkew; + +#undef REF_FREQ +#define REF_FREQ 37500000 +#undef MAX_VREF +#define MAX_VREF 9000000 +#define MIN_VREF 1500000 +#undef MAX_VCO +#define MAX_VCO 270000000 +#define MIN_VCO 65000000 + + if (freq < 25000) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Specified dot clock (%.3f) too low for SilverHammer", + freq / 1000.0); + return(FALSE); + } else if (freq > MAX_VCO) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Specified dot clock (%.3f) too high for SilverHammer", + freq / 1000.0); + return(FALSE); + } + + requested_freq = freq * 1000; + + best_m = best_n = best_df = 0; + best_diff = requested_freq; /* worst case */ + + for (df=0; df<4; df++) { + max_n = REF_FREQ / MIN_VREF; + if (df < 3) + max_n >>= 1; + for (n=2; n<max_n; n++) + for (m=65; m<=128; m++) { + vrf = REF_FREQ / n; + if (df < 3) + vrf >>= 1; + if ((vrf > MAX_VREF) || (vrf < MIN_VREF)) + continue; + + f = vrf * m; + outf = f; + if (df < 2) + outf >>= 2 - df; + if ((f > MAX_VCO) || (f < MIN_VCO)) + continue; + + /* outf is a valid freq, pick the closest now */ + + if ((diff = (requested_freq - outf)) < 0) + diff = -diff;; + if (diff < best_diff) { + best_diff = diff; + best_m = m; + best_n = n; + best_df = df; + best_outf = outf; + } + } + } + + /* do we have an acceptably close frequency? (less than 1% diff) */ + + if (best_diff > (requested_freq/100)) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Specified dot clock (%.3f) too far (best %.3f) SilverHammer", + requested_freq / 1000.0, best_outf / 1000.0); + return(FALSE); + } + + pI128->mem.rbase_g[PEL_MASK] = 0xFF; MB; + + tmpc = pI128->mem.rbase_g[IDXCTL_I] & 0xFF; + tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF; + tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF; + + pI128->mem.rbase_g[IDXH_I] = 0; MB; + pI128->mem.rbase_g[IDXCTL_I] = 0; MB; + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc_clock; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF; + pI128->mem.rbase_g[DATA_I] = tmp2 | 0x81; MB; + + if (!pI128->Primary) { + pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0; MB; + pI128->mem.rbase_g[DATA_I] = 0x15; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0+1; MB; + pI128->mem.rbase_g[DATA_I] = 0x10; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0+2; MB; + pI128->mem.rbase_g[DATA_I] = 0x2c; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0+3; MB; + pI128->mem.rbase_g[DATA_I] = 0x12; MB; + } + pI128->mem.rbase_g[IDXL_I] = IBMRGB_m0+4; MB; + pI128->mem.rbase_g[DATA_I] = (best_df<<6) | (best_m&0x3f); MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_n0+4; MB; + pI128->mem.rbase_g[DATA_I] = best_n; MB; + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pll_ctrl1; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF; + pI128->mem.rbase_g[DATA_I] = (tmp2&0xf8) | 3; /* 8 M/N pairs in PLL */ MB; + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pll_ctrl2; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xFF; + pI128->mem.rbase_g[DATA_I] = (tmp2&0xf0) | 2; /* clock number 2 */ MB; + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc_clock; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf0; + pI128->mem.rbase_g[DATA_I] = tmp2 | ((flags & V_DBLCLK) ? 0x03 : 0x01); MB; + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sync; MB; + pI128->mem.rbase_g[DATA_I] = ((flags & V_PHSYNC) ? 0x10 : 0x00) + | ((flags & V_PVSYNC) ? 0x20 : 0x00); MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_hsync_pos; MB; + pI128->mem.rbase_g[DATA_I] = ((flags & V_HSKEW) ? skew : 0x01); MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pwr_mgmt; MB; +/* Use 0x01 below with digital flat panel to conserve energy and reduce noise */ + pI128->mem.rbase_g[DATA_I] = (pI128->FlatPanel ? 0x01 : 0x00); MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_dac_op; MB; + pI128->mem.rbase_g[DATA_I] = (pI128->DACSyncOnGreen ? 0x08 : 0x00); MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pal_ctrl; MB; + pI128->mem.rbase_g[DATA_I] = 0x00; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk; MB; + pI128->mem.rbase_g[DATA_I] = 0x01; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc1; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xbc; + if ((pI128->MemoryType != I128_MEMORY_DRAM) && + (pI128->MemoryType != I128_MEMORY_SGRAM)) + tmp2 |= (pI128->RamdacType == IBM528_DAC) ? 3 : 1; + pI128->mem.rbase_g[DATA_I] = tmp2; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc2; MB; + tmp2 = 0x03; + if (pI128->DAC8Bit) + tmp2 |= 0x04; + if (!((pI128->MemoryType == I128_MEMORY_DRAM) && + (pI128->bitsPerPixel > 16))) + tmp2 |= 0x40; + if ((pI128->MemoryType == I128_MEMORY_SGRAM) && + (pI128->bitsPerPixel > 16) && + (pI128->RamdacType != SILVER_HAMMER_DAC) ) + tmp2 &= 0x3F; + pI128->mem.rbase_g[DATA_I] = tmp2; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc3; MB; + pI128->mem.rbase_g[DATA_I] = 0x00; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_misc4; MB; + pI128->mem.rbase_g[DATA_I] = 0x00; MB; + + /* ?? There is no write to cursor control register */ + + /* Set the memory clock speed to 95 MHz */ + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div; MB; + pI128->mem.rbase_g[DATA_I] = 0x08; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div; MB; + pI128->mem.rbase_g[DATA_I] = 0x50; MB; + + /* should delay at least a millisec so we'll wait 50 */ + usleep(50000); + + switch (pI128->depth) { + case 24: /* 32 bit */ + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8; + pI128->mem.rbase_g[DATA_I] = tmp2 | 0x06; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_32bpp; MB; + pI128->mem.rbase_g[DATA_I] = 0x03; MB; + break; + case 16: + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8; + pI128->mem.rbase_g[DATA_I] = tmp2 | 0x04; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_16bpp; MB; + pI128->mem.rbase_g[DATA_I] = 0xC7; MB; + break; + case 15: + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8; + pI128->mem.rbase_g[DATA_I] = tmp2 | 0x04; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_16bpp; MB; + pI128->mem.rbase_g[DATA_I] = 0xC5; MB; + break; + default: /* 8 bit */ + pI128->mem.rbase_g[IDXL_I] = IBMRGB_pix_fmt; MB; + tmp2 = pI128->mem.rbase_g[DATA_I] & 0xf8; + pI128->mem.rbase_g[DATA_I] = tmp2 | 0x03; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_8bpp; MB; + pI128->mem.rbase_g[DATA_I] = 0x00; MB; + break; + } + + pI128->mem.rbase_g[IDXCTL_I] = tmpc; MB; + pI128->mem.rbase_g[IDXH_I] = tmph; MB; + pI128->mem.rbase_g[IDXL_I] = tmpl; MB; + + return(TRUE); +} diff --git a/driver/xf86-video-i128/src/i128_driver.c b/driver/xf86-video-i128/src/i128_driver.c new file mode 100644 index 000000000..90beb30b2 --- /dev/null +++ b/driver/xf86-video-i128/src/i128_driver.c @@ -0,0 +1,2478 @@ +/* + * Copyright 1995-2000 by Robin Cutshaw <robin@XFree86.Org> + * Copyright 1998 by Number Nine Visual Technology, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Robin Cutshaw not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Robin Cutshaw and Number Nine make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * ROBIN CUTSHAW AND NUMBER NINE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL ROBIN CUTSHAW OR NUMBER NINE 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 + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128_driver.c,v 1.34tsi Exp $ */ + + +/* All drivers should typically include these */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" + +/* All drivers need this */ +#include "xf86_ansic.h" + +#include "compiler.h" + +/* Drivers for PCI hardware need this */ +#include "xf86PciInfo.h" + +/* Drivers that need to access the PCI config space directly need this */ +#include "xf86Pci.h" + +/* vgaHW module is only used to save/restore fonts by this driver */ +#include "vgaHW.h" + +/* All drivers initialising the SW cursor need this */ +#include "mipointer.h" + +/* All drivers implementing backing store need this */ +#include "mibstore.h" +#include "micmap.h" + +#include "xf86DDC.h" +#include "xf86RAC.h" +#include "vbe.h" + +#include "xaa.h" +#include "xf86cmap.h" +#include "fb.h" + +#include "xf86xv.h" +#include <X11/extensions/Xv.h> + +/* driver specific includes */ +#include "i128.h" +#include "i128reg.h" + +/* + * Forward definitions for the functions that make up the driver. + */ + +/* Mandatory functions */ +static const OptionInfoRec * I128AvailableOptions(int chipid, int busid); +static void I128Identify(int flags); +static Bool I128Probe(DriverPtr drv, int flags); +static Bool I128PreInit(ScrnInfoPtr pScrn, int flags); +static Bool I128ScreenInit(int Index, ScreenPtr pScreen, int argc, + char **argv); +static Bool I128EnterVT(int scrnIndex, int flags); +static void I128LeaveVT(int scrnIndex, int flags); +static Bool I128CloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool I128SaveScreen(ScreenPtr pScreen, int mode); + +static void I128DumpBaseRegisters(ScrnInfoPtr pScrn); +static void I128DumpIBMDACRegisters(ScrnInfoPtr pScrn, volatile CARD32 *vrbg); + +/* Optional functions */ +static void I128FreeScreen(int scrnIndex, int flags); +static ModeStatus I128ValidMode(int scrnIndex, DisplayModePtr mode, + Bool verbose, int flags); +static void I128DisplayPowerManagementSet(ScrnInfoPtr pScrn, + int PowerManagementMode, + int flags); + +/* Internally used functions */ +static Bool I128GetRec(ScrnInfoPtr pScrn); +static void I128FreeRec(ScrnInfoPtr pScrn); +static Bool I128MapMem(ScrnInfoPtr pScrn); +static Bool I128UnmapMem(ScrnInfoPtr pScrn); +static void I128Save(ScrnInfoPtr pScrn); +static void I128Restore(ScrnInfoPtr pScrn); +static Bool I128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static int I128CountRam(ScrnInfoPtr pScrn); +static void I128SoftReset(ScrnInfoPtr pScrn); +static Bool I128I2CInit(ScrnInfoPtr pScrn); +static xf86MonPtr I128getDDC(ScrnInfoPtr pScrn); +#if 0 +static unsigned int I128DDC1Read(ScrnInfoPtr pScrn); +#endif + +#define I128_VERSION 4000 +#define I128_NAME "I128" +#define I128_DRIVER_NAME "i128" +#define I128_MAJOR_VERSION 1 +#define I128_MINOR_VERSION 1 +#define I128_PATCHLEVEL 0 + +/* + * This contains the functions needed by the server after loading the + * driver module. It must be supplied, and gets added the driver list by + * the Module Setup funtion in the dynamic case. In the static case a + * reference to this is compiled in, and this requires that the name of + * this DriverRec be an upper-case version of the driver name. + */ + +_X_EXPORT DriverRec I128 = { + I128_VERSION, + I128_DRIVER_NAME, + I128Identify, + I128Probe, + I128AvailableOptions, + NULL, + 0 +}; + +#ifdef XFree86LOADER + +static MODULESETUPPROTO(i128Setup); + +static XF86ModuleVersionInfo i128VersRec = +{ + "i128", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + I128_MAJOR_VERSION, I128_MINOR_VERSION, I128_PATCHLEVEL, + ABI_CLASS_VIDEODRV, /* This is a video driver */ + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0,0,0,0} +}; + +/* + * XF86ModuleData structure is the first part of the driver that is used + * by the module loader. It provides the XF86ModuleVersionInfo structure + * used to verify that the module version is compatable with the loader + * version. It also provides a pointer to the module specific + * ModuleSetupProc() and ModuleTearDownProc() functions. + */ + +_X_EXPORT XF86ModuleData i128ModuleData = { &i128VersRec, i128Setup, NULL }; + +#endif + + +/* + * List of symbols from other modules that this module references. This + * list is used to tell the loader that it is OK for symbols here to be + * unresolved providing that it hasn't been told that they haven't been + * told that they are essential via a call to xf86LoaderReqSymbols() or + * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about + * unresolved symbols that are not required. These are provided to the + * LoaderRefSymLists() function in the module specific Setup() function. + */ + +static const char *vgahwSymbols[] = { + "vgaHWFreeHWRec", + "vgaHWGetHWRec", + "vgaHWGetIOBase", + "vgaHWGetIndex", + "vgaHWProtect", + "vgaHWRestore", + "vgaHWSave", + NULL +}; + +static const char *fbSymbols[] = { + "fbScreenInit", + "fbPictureInit", + NULL +}; + +static const char *exaSymbols[] = { + "exaDriverAlloc", + "exaDriverInit", + "exaDriverFini", + "exaGetPixmapOffset", + NULL +}; + +static const char *xaaSymbols[] = { + "XAACreateInfoRec", + "XAADestroyInfoRec", + "XAAInit", + NULL +}; + +static const char *ramdacSymbols[] = { + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + "xf86InitCursor", + NULL +}; + +static const char *ddcSymbols[] = { + "xf86DoEDID_DDC1", + "xf86DoEDID_DDC2", + "xf86PrintEDID", + "xf86SetDDCproperties", + NULL +}; + +static const char *i2cSymbols[] = { + "xf86CreateI2CBusRec", + "xf86I2CBusInit", + NULL +}; + +#ifdef XFree86LOADER +/* XXX The vbe module isn't currently loaded. */ +static const char *vbeSymbols[] = { + "VBEInit", + "vbeDoEDID", + NULL +}; + +/* XXX The int10 module isn't currently loaded. */ +static const char *int10Symbols[] = { + "xf86InitInt10", + "xf86FreeInt10", + NULL +}; +#endif + + +#ifdef XFree86LOADER + +/* Mandatory + * + * The Setup() function is the first entry point called once that the + * module has been linked into the server. It adds this driver to + * the driver list and lets the server know which symbols it might use. + * This is only called once, not called with each server generation. + * + * Arguments: + * pointer module - module being loaded, passed to xf86AddDriver() + * pointer opts - unused but contains options from config file + * int *errmaj - if function error returns major error value + * int *errmin - if function error returns minor error value + * Returns: + * pointer to TearDownData which is passed to TearDownProc() + * or NULL for failure. + */ + +static pointer +i128Setup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = FALSE; + + /* This module should be loaded only once, but check to be sure. */ + + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&I128, module, 0); + + /* + * Modules that this driver always requires may be loaded here + * by calling LoadSubModule(). + */ + + /* + * Tell the loader about symbols from other modules that this module + * might refer to. + */ + LoaderRefSymLists(fbSymbols, + exaSymbols, + xaaSymbols, + ramdacSymbols, + ddcSymbols, + ddcSymbols, + i2cSymbols, + vbeSymbols, + int10Symbols, + vgahwSymbols, + NULL); + + /* + * The return value must be non-NULL on success even though there + * is no TearDownProc. + */ + return (pointer)1; + } else { + if (errmaj) *errmaj = LDR_ONCEONLY; + return NULL; + } +} + +#endif /* XFree86LOADER */ + + +/* Define supported chipsets. Used by Probe(). */ + +static SymTabRec I128Chipsets[] = { + { PCI_CHIP_I128, "i128" }, + { PCI_CHIP_I128_2, "i128v2" }, + { PCI_CHIP_I128_T2R, "i128t2r" }, + { PCI_CHIP_I128_T2R4, "i128t2r4" }, + {-1, NULL } +}; + +static PciChipsets I128PciChipsets[] = { + { PCI_CHIP_I128, PCI_CHIP_I128, NULL }, + { PCI_CHIP_I128_2, PCI_CHIP_I128_2, NULL }, + { PCI_CHIP_I128_T2R, PCI_CHIP_I128_T2R, NULL }, + { PCI_CHIP_I128_T2R4, PCI_CHIP_I128_T2R4, NULL }, + { -1, -1, RES_UNDEFINED } +}; + +/* Mandatory + * + * The Probe() function is the second entry point called once that the + * module has been linked into the server. This function finds all + * instances of hardware that it supports and allocates a ScrnInfoRec + * using xf86ConfigPciEntity() for each unclaimed slot. This should be + * a minimal probe and under no circumstances should it leave the hardware + * state changed. No initialisations other than the required ScrnInfoRec + * should be done and no data structures should be allocated. + * + * Arguments: + * DriverPtr drv - pointer to the driver structure + * int flags - PROBE_DEFAULT for normal function + * PROBE_DETECT for use with "-config" and "-probe" + * Returns: + * Bool TRUE if a screen was allocated, FALSE otherwise + */ + +static Bool +I128Probe(DriverPtr drv, int flags) +{ + int i; + GDevPtr *devSections; + int *usedChips; + int numDevSections; + int numUsed; + Bool foundScreen = FALSE; + + /* + * 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(I128_DRIVER_NAME, + &devSections)) <= 0) { + /* + * There's no matching device section in the config file, so quit + * now. + */ + 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. + */ + + /* + * All of the cards this driver supports are PCI, so the "probing" just + * amounts to checking the PCI data that the server has already collected. + */ + if (xf86GetPciVideoInfo() == NULL) { + /* + * We won't let anything in the config file override finding no + * PCI video cards at all. This seems reasonable now, but we'll see. + */ + return FALSE; + } + + numUsed = xf86MatchPciInstances(I128_NAME, PCI_VENDOR_NUMNINE, + I128Chipsets, I128PciChipsets, devSections, + numDevSections, drv, &usedChips); + + /* Free it since we don't need that list after this */ + xfree(devSections); + + if (numUsed <= 0) + return FALSE; + + if (flags & PROBE_DETECT) { + xfree(usedChips); + return FALSE; + } + + for (i = 0; i < numUsed; i++) { + ScrnInfoPtr pScrn = NULL; + + /* Allocate a ScrnInfoRec and claim the slot */ + if ((pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[i], + I128PciChipsets, NULL, NULL, + NULL, NULL, NULL)) == NULL) + continue; + + + /* Fill in what we can of the ScrnInfoRec */ + pScrn->driverVersion = I128_VERSION; + pScrn->driverName = I128_DRIVER_NAME; + pScrn->name = I128_NAME; + pScrn->Probe = I128Probe; + pScrn->PreInit = I128PreInit; + pScrn->ScreenInit = I128ScreenInit; + pScrn->SwitchMode = I128SwitchMode; + pScrn->AdjustFrame = I128AdjustFrame; + pScrn->EnterVT = I128EnterVT; + pScrn->LeaveVT = I128LeaveVT; + pScrn->FreeScreen = I128FreeScreen; + pScrn->ValidMode = I128ValidMode; + foundScreen = TRUE; + } + + xfree(usedChips); + + return foundScreen; +} + + +/* Mandatory + * + * The Identify() function is the third entry point called once that the + * module has been linked into the server. This function prints driver + * identity information. + * + * Arguments: + * int flags - currently unused + * Returns: + * no return + */ + +static void +I128Identify(int flags) +{ + xf86PrintChipsets(I128_NAME, "driver for Number Nine I128 chipsets", + I128Chipsets); +} + + +/* + * Define options that this driver will accept. Used by AvailableOptions(). + */ + +typedef enum { + OPTION_FLATPANEL, + OPTION_SW_CURSOR, + OPTION_HW_CURSOR, + OPTION_SYNC_ON_GREEN, + OPTION_NOACCEL, + OPTION_SHOWCACHE, + OPTION_DAC6BIT, + OPTION_DEBUG, + OPTION_ACCELMETHOD +} I128Opts; + +static const OptionInfoRec I128Options[] = { + { OPTION_FLATPANEL, "FlatPanel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SYNC_ON_GREEN, "SyncOnGreen", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_DAC6BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_DEBUG, "Debug", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + + +/* Mandatory + * + * The AvailableOptions() function is called to provide the options that + * this driver will accept. This is used with the "-configure" server option. + * + * Arguments: + * int chipid - currently unused + * int busid - currently unused + * Returns: + * const OptionInfoRec * - all accepted options + */ + +static const OptionInfoRec * +I128AvailableOptions(int chipid, int busid) +{ + return I128Options; +} + + +/* Mandatory + * + * The PreInit() function called after the Probe() function once at + * server startup and not at each server generation. Only things that + * are persistent across server generations can be initialized here. + * This function determines if the configuration is usable and, if so, + * initializes those parts of the ScrnInfoRec that can be set at the + * beginning of the first server generation. This should be done in + * the least intrusive way possible. Note that although the ScrnInfoRec + * has been allocated, the ScreenRec has not. + * + * Use xf86AllocateScrnInfoPrivateIndex() for persistent data across + * screen generations and AllocateScreenprivateIndex() in ScreenInit() + * for per-generation data. + * + * Arguments: + * ScrnInfoPtr pScrn - + * int flags - PROBE_DEFAULT for normal function + * PROBE_DETECT for use with "-config" and "-probe" + * Returns: + * Bool TRUE if ScrnInfoRec was initialized, FALSE otherwise + */ + +static Bool +I128PreInit(ScrnInfoPtr pScrn, int flags) +{ + I128Ptr pI128; + vgaHWPtr hwp; + int i; + ClockRangePtr clockRanges; + MessageType from; + IOADDRESS iobase; + char *ramdac = NULL; + CARD32 tmpl, tmph, tmp; + unsigned char n, m, p, mdc, df; + float mclk; + xf86MonPtr mon; + + /* Check the number of entities, and fail if it isn't one. */ + if (pScrn->numEntities != 1) + return FALSE; + + /* Allocate the I128Rec driverPrivate */ + I128GetRec(pScrn); + + pI128 = I128PTR(pScrn); + + /* Get the entity, and make sure it is PCI. */ + pI128->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + if (pI128->pEnt->location.type != BUS_PCI) + return FALSE; + + if (flags & PROBE_DETECT) { + /* I128ProbeDDC(pScrn, pI128->pEnt->index); */ + return TRUE; + } + + /* Find the PCI info for this screen */ + pI128->PciInfo = xf86GetPciInfoForEntity(pI128->pEnt->index); + pI128->PciTag = pciTag(pI128->PciInfo->bus, pI128->PciInfo->device, + pI128->PciInfo->func); + + pI128->Primary = xf86IsPrimaryPci(pI128->PciInfo); + + /* The vgahw module should be allocated here when needed */ + if (!xf86LoadSubModule(pScrn, "vgahw")) + return FALSE; + + xf86LoaderReqSymLists(vgahwSymbols, NULL); + + /* + * Allocate a vgaHWRec + */ + if (!vgaHWGetHWRec(pScrn)) + return FALSE; + + hwp = VGAHWPTR(pScrn); + vgaHWGetIOBase(hwp); + + /* Set pScrn->monitor */ + pScrn->monitor = pScrn->confScreen->monitor; + + /* + * The first thing we should figure out is the depth, bpp, etc. + * Our default depth is 8, so pass it to the helper function. + * We support both 24bpp and 32bpp layouts, so indicate that. + */ + + if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) { + return FALSE; + } else { + /* Check that the returned depth is one we support */ + switch (pScrn->depth) { + case 8: + case 15: + case 16: + case 24: + /* OK */ + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by this driver\n", + pScrn->depth); + return FALSE; + } + } + xf86PrintDepthBpp(pScrn); + + /* + * This must happen after pScrn->display has been set because + * xf86SetWeight references it. + */ + if (pScrn->depth > 8) { + /* The defaults are OK for us */ + rgb zeros = {0, 0, 0}; + + if (!xf86SetWeight(pScrn, zeros, zeros)) { + return FALSE; + } else { + /* XXX check that weight returned is supported */ + ; + } + } + + if (!xf86SetDefaultVisual(pScrn, -1)) { + return FALSE; + } else { + /* We don't currently support DirectColor at > 8bpp */ + if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" + " (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + return FALSE; + } + } + + /* We use a programmable clock */ + pScrn->progClock = TRUE; + + /* Collect all of the relevant option flags (fill in pScrn->options) */ + xf86CollectOptions(pScrn, NULL); + + /* Process the options */ + if (!(pI128->Options = xalloc(sizeof(I128Options)))) + return FALSE; + memcpy(pI128->Options, I128Options, sizeof(I128Options)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pI128->Options); + + if (pScrn->depth == 8) + pScrn->rgbBits = 8; + + /* + * The preferred method is to use the "hw cursor" option as a tri-state + * option, with the default set above. + */ + from = X_DEFAULT; + pI128->HWCursor = TRUE; + if (xf86GetOptValBool(pI128->Options, OPTION_HW_CURSOR, &pI128->HWCursor)) { + from = X_CONFIG; + } + /* For compatibility, accept this too (as an override) */ + if (xf86ReturnOptValBool(pI128->Options, OPTION_SW_CURSOR, FALSE)) { + from = X_CONFIG; + pI128->HWCursor = FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", + pI128->HWCursor ? "HW" : "SW"); + if (xf86ReturnOptValBool(pI128->Options, OPTION_NOACCEL, FALSE)) { + pI128->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); + } else { + int from = X_DEFAULT; + char *s = xf86GetOptValString(pI128->Options, OPTION_ACCELMETHOD); + pI128->NoAccel = FALSE; + if (!xf86NameCmp(s, "EXA")) { + pI128->exa = TRUE; + from = X_CONFIG; + } + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration\n", + pI128->exa ? "EXA" : "XAA"); + } + if (xf86ReturnOptValBool(pI128->Options, OPTION_SYNC_ON_GREEN, FALSE)) { + pI128->DACSyncOnGreen = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Sync-on-Green enabled\n"); + } else pI128->DACSyncOnGreen = FALSE; + if (xf86ReturnOptValBool(pI128->Options, OPTION_SHOWCACHE, FALSE)) { + pI128->ShowCache = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache enabled\n"); + } else pI128->ShowCache = FALSE; + if (xf86ReturnOptValBool(pI128->Options, OPTION_DAC6BIT, FALSE)) { + pI128->DAC8Bit = FALSE; + pScrn->rgbBits = 6; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Dac6Bit enabled\n"); + } else pI128->DAC8Bit = TRUE; + if (xf86ReturnOptValBool(pI128->Options, OPTION_DEBUG, FALSE)) { + pI128->Debug = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Debug enabled\n"); + } else pI128->Debug = FALSE; + if (xf86ReturnOptValBool(pI128->Options, OPTION_FLATPANEL, FALSE)) { + pI128->FlatPanel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "FlatPanel forced\n"); + } else pI128->FlatPanel = FALSE; + + /* + * Set the Chipset and ChipRev. + */ + from = X_PROBED; + pI128->Chipset = pI128->PciInfo->chipType; + pScrn->chipset = (char *)xf86TokenToString(I128Chipsets, pI128->Chipset); + pI128->ChipRev = pI128->PciInfo->chipRev; + + /* + * This shouldn't happen because such problems should be caught in + * I128Probe(), but check it just in case. + */ + if (pScrn->chipset == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ChipID 0x%04X is not recognised\n", pI128->Chipset); + return FALSE; + } + if (pI128->Chipset < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Chipset \"%s\" is not recognised\n", pScrn->chipset); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); + if (pI128->PciInfo->subsysVendor == 0x105D) + xf86DrvMsg(pScrn->scrnIndex, from, "Subsystem Vendor: \"Number Nine\"\n"); + else if (pI128->PciInfo->subsysVendor == 0x10F0) + xf86DrvMsg(pScrn->scrnIndex, from, "Subsystem Vendor: \"Peritek\"\n"); + else + xf86DrvMsg(pScrn->scrnIndex, from, "Subsystem Vendor: \"%x\"\n", + pI128->PciInfo->subsysVendor); + + iobase = (pI128->PciInfo->ioBase[5] & 0xFFFFFF00) + hwp->PIOOffset; + pI128->RegRec.iobase = iobase; + + pI128->io.rbase_g = inl(iobase) & 0xFFFFFF00; + pI128->io.rbase_w = inl(iobase + 0x04) & 0xFFFFFF00; + pI128->io.rbase_a = inl(iobase + 0x08) & 0xFFFFFF00; + pI128->io.rbase_b = inl(iobase + 0x0C) & 0xFFFFFF00; + pI128->io.rbase_i = inl(iobase + 0x10) & 0xFFFFFF00; + pI128->io.rbase_e = inl(iobase + 0x14) & 0xFFFF8003; + pI128->io.id = inl(iobase + 0x18) & /* 0x7FFFFFFF */ 0xFFFFFFFF; + pI128->io.config1 = inl(iobase + 0x1C) & /* 0xF3333F1F */ 0xFF133706; + pI128->io.config2 = inl(iobase + 0x20) & 0xC1F70FFF; + pI128->io.sgram = inl(iobase + 0x24) & 0xFFFFFFFF; + pI128->io.soft_sw = inl(iobase + 0x28) & 0x0000FFFF; + pI128->io.vga_ctl = inl(iobase + 0x30) & 0x0000FFFF; + + if (pI128->Debug) + I128DumpBaseRegisters(pScrn); + + pI128->RegRec.config1 = pI128->io.config1; + pI128->RegRec.config2 = pI128->io.config2; + pI128->RegRec.sgram = pI128->io.sgram; + if (pI128->Chipset == PCI_CHIP_I128_T2R4) + pI128->io.sgram = 0x211BF030; + else + pI128->io.sgram = 0x21089030; + /* vga_ctl is saved later */ + + /* enable all of the memory mapped windows */ + + pI128->io.config1 &= 0x3300001F; + pI128->io.config1 |= 0x00331F10; + outl(iobase + 0x1C, pI128->io.config1); + + pI128->MemoryType = I128_MEMORY_UNKNOWN; + + if (pI128->Chipset == PCI_CHIP_I128_T2R4) + pI128->MemoryType = I128_MEMORY_SGRAM; + else if (pI128->Chipset == PCI_CHIP_I128_T2R) { + if ((pI128->io.config2&6) == 2) + pI128->MemoryType = I128_MEMORY_SGRAM; + else + pI128->MemoryType = I128_MEMORY_WRAM; + } else if (pI128->Chipset == PCI_CHIP_I128_2) { + if (((((pciConfigPtr)pI128->PciInfo->thisCard)->pci_command & 0x03) + == 0x03) && (pI128->PciInfo->subsysCard == 0x08)) + pI128->MemoryType = I128_MEMORY_DRAM; + } + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory type %s\n", + pI128->MemoryType == I128_MEMORY_SGRAM ? "SGRAM" : + pI128->MemoryType == I128_MEMORY_DRAM ? "DRAM" : + pI128->MemoryType == I128_MEMORY_WRAM ? "WRAM" : "UNKNOWN"); + + pI128->io.config2 &= 0xFF0FFF7F; + pI128->io.config2 |= 0x00100000; + if (pI128->MemoryType != I128_MEMORY_SGRAM) + pI128->io.config2 |= 0x00400000; + outl(pI128->RegRec.iobase + 0x20, pI128->io.config2); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Linear framebuffer at 0x%lX\n", + (unsigned long)pI128->PciInfo->memBase[0]); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MMIO registers at 0x%lX\n", + (unsigned long)pI128->PciInfo->ioBase[5]); + + if (xf86RegisterResources(pI128->pEnt->index, NULL, ResExclusive)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "xf86RegisterResources() found resource conflicts\n"); + I128FreeRec(pScrn); + return FALSE; + } + + /* HW bpp matches reported bpp */ + pI128->bitsPerPixel = pScrn->bitsPerPixel; + pI128->depth = pScrn->depth; + pI128->weight.red = pScrn->weight.red; + pI128->weight.green = pScrn->weight.green; + pI128->weight.blue = pScrn->weight.blue; + pI128->mode = pScrn->modes; + + pScrn->videoRam = I128CountRam(pScrn); + pI128->MemorySize = pScrn->videoRam; + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n", + pScrn->videoRam); + + + /* + * If the driver can do gamma correction, it should call xf86SetGamma() + * here. + */ + + { + Gamma zeros = {0.0, 0.0, 0.0}; + + if (!xf86SetGamma(pScrn, zeros)) { + return FALSE; + } + } + + if (!I128MapMem(pScrn)) + return FALSE; + + /* + * Reset card if it isn't primary one (must be done after config1 is set) + */ + if (!pI128->Primary) + I128SoftReset(pScrn); + + if (pI128->Chipset != PCI_CHIP_I128) { + pI128->ddc1Read = NULL /*I128DDC1Read*/; + pI128->i2cInit = I128I2CInit; + } + + /* Load DDC if we have the code to use it */ + /* This gives us DDC1 */ + if (pI128->ddc1Read || pI128->i2cInit) { + if (xf86LoadSubModule(pScrn, "ddc")) { + xf86LoaderReqSymLists(ddcSymbols, NULL); + } else { + /* ddc module not found, we can do without it */ + pI128->ddc1Read = NULL; + + /* Without DDC, we have no use for the I2C bus */ + pI128->i2cInit = NULL; + } + } + /* - DDC can use I2C bus */ + /* Load I2C if we have the code to use it */ + if (pI128->i2cInit) { + if ( xf86LoadSubModule(pScrn, "i2c") ) { + xf86LoaderReqSymLists(i2cSymbols,NULL); + } else { + /* i2c module not found, we can do without it */ + pI128->i2cInit = NULL; + pI128->I2C = NULL; + } + } + + /* Read and print the Monitor DDC info */ + mon = I128getDDC(pScrn); + pScrn->monitor->DDC = mon; + + /* see if we can find a flatpanel */ + if (!pI128->FlatPanel && mon) { + for (i=0; i<4; i++) + if (mon->det_mon[i].type == DS_NAME) { + if (strncmp((char *)mon->det_mon[i].section.name, + "SGI 1600SW FP", 13) == 0) { + pI128->FlatPanel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Found FlatPanel via DDC2\n"); + } + break; + } + } + + pI128->maxClock = 175000; + + switch (pI128->Chipset) { + case PCI_CHIP_I128: + if (pI128->io.id & 0x0400) /* 2 banks VRAM */ + pI128->RamdacType = IBM528_DAC; + else + pI128->RamdacType = TI3025_DAC; + break; + case PCI_CHIP_I128_2: + if (pI128->io.id & 0x0400) /* 2 banks VRAM */ + pI128->RamdacType = IBM528_DAC; + else + pI128->RamdacType = IBM526_DAC; + pI128->maxClock = 220000; + break; + case PCI_CHIP_I128_T2R: + pI128->RamdacType = IBM526_DAC; + pI128->maxClock = 220000; + break; + case PCI_CHIP_I128_T2R4: + pI128->RamdacType = SILVER_HAMMER_DAC; + pI128->maxClock = 270000; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Unknown I128 chipset: %d\n", + pI128->Chipset); + return(FALSE); + } + + if ((pI128->maxClock == 175000) && (pI128->MemorySize == 8192)) + pI128->maxClock = 220000; + + switch(pI128->RamdacType) { + case TI3025_DAC: + /* verify that the ramdac is a TVP3025 */ + + pI128->mem.rbase_g[INDEX_TI] = TI_ID; MB; + if ((pI128->mem.rbase_g[DATA_TI]&0xFF) != TI_VIEWPOINT25_ID) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Ti3025 Ramdac not found\n"); + return(FALSE); + } + ramdac = "TI3025"; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x00; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA; MB; + n = pI128->mem.rbase_g[DATA_TI]&0x7f; + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x01; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA; MB; + m = pI128->mem.rbase_g[DATA_TI]&0x7f; + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x02; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA; MB; + p = pI128->mem.rbase_g[DATA_TI]&0x03; + pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_DCLK_CONTROL; MB; + mdc = pI128->mem.rbase_g[DATA_TI]&0xFF; + if (mdc&0x08) + mdc = (mdc&0x07)*2 + 2; + else + mdc = 1; + mclk = ((1431818 * ((m+2) * 8)) / (n+2) / (1 << p) / mdc + 50) / 100; + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Using TI 3025 programmable clock (MCLK %1.3f MHz)\n", + mclk / 1000.0); + pI128->minClock = 20000; + pI128->ProgramDAC = I128ProgramTi3025; + break; + + case IBM524_DAC: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "IBM524 Ramdac not supported\n"); + return(FALSE); + + case IBM526_DAC: + /* verify that the ramdac is an IBM526 */ + + ramdac = "IBM526"; + tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF; + tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF; + pI128->mem.rbase_g[IDXH_I] = 0; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_id; MB; + tmp = pI128->mem.rbase_g[DATA_I] & 0xFF; + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div; MB; + n = pI128->mem.rbase_g[DATA_I] & 0x1f; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div; MB; + m = pI128->mem.rbase_g[DATA_I]; + df = m>>6; + m &= 0x3f; + if (n == 0) { m=0; n=1; } + mclk = ((2517500 * (m+65)) / n / (8>>df) + 50) / 100; + + pI128->mem.rbase_g[IDXL_I] = tmpl; MB; + pI128->mem.rbase_g[IDXH_I] = tmph; MB; + if (tmp != 2) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "IBM526 Ramdac not found\n"); + return(FALSE); + } + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Using IBM 526 programmable clock (MCLK %1.3f MHz)\n", + mclk / 1000.0); + pI128->minClock = 25000; + pI128->ProgramDAC = I128ProgramIBMRGB; + break; + + case IBM528_DAC: + /* verify that the ramdac is an IBM528 */ + + ramdac = "IBM528"; + tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF; + tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF; + pI128->mem.rbase_g[IDXH_I] = 0; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_id; MB; + tmp = pI128->mem.rbase_g[DATA_I] & 0xFF; + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div; MB; + n = pI128->mem.rbase_g[DATA_I] & 0x1f; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div; MB; + m = pI128->mem.rbase_g[DATA_I] & 0xFF; + df = m>>6; + m &= 0x3f; + if (n == 0) { m=0; n=1; } + mclk = ((2517500 * (m+65)) / n / (8>>df) + 50) / 100; + + pI128->mem.rbase_g[IDXL_I] = tmpl; MB; + pI128->mem.rbase_g[IDXH_I] = tmph; MB; + if (tmp != 2) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "IBM528 Ramdac not found\n"); + return(FALSE); + } + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Using IBM 528 programmable clock (MCLK %1.3f MHz)\n", + mclk / 1000.0); + pI128->minClock = 25000; + pI128->ProgramDAC = I128ProgramIBMRGB; + break; + + case SILVER_HAMMER_DAC: + /* verify that the ramdac is a Silver Hammer */ + + ramdac = "SilverHammer"; + tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF; + tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF; + tmp = pI128->mem.rbase_g[DATA_I] & 0xFF; + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div; MB; + n = pI128->mem.rbase_g[DATA_I] & 0x1f; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div; MB; + m = pI128->mem.rbase_g[DATA_I]; + df = m>>6; + m &= 0x3f; + if (n == 0) { m=0; n=1; } + mclk = ((3750000 * (m+65)) / n / (8>>df) + 50) / 100; + + pI128->mem.rbase_g[IDXL_I] = tmpl; MB; + pI128->mem.rbase_g[IDXH_I] = tmph; MB; + if (pI128->Chipset != PCI_CHIP_I128_T2R4) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SilverHammer Ramdac not found\n"); + return(FALSE); + } + + if (pI128->mem.rbase_g[CRT_1CON] & 0x00000100) { + pI128->FlatPanel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Digital flat panel detected\n"); + } else if (pI128->FlatPanel) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Digital flat panel forced\n"); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Using SilverHammer programmable clock (MCLK %1.3f MHz)\n", + mclk / 1000.0); + pI128->minClock = 25000; + pI128->ProgramDAC = I128ProgramSilverHammer; + break; + + default: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Ramdac Unknown\n"); + return(FALSE); + } + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Ramdac Type min/max speed: %s %d/%d MHz\n", + ramdac, pI128->minClock/1000, pI128->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 = pI128->minClock; + clockRanges->maxClock = pI128->maxClock; + clockRanges->clockIndex = -1; /* programmable */ + clockRanges->interlaceAllowed = TRUE; + clockRanges->doubleScanAllowed = TRUE; + clockRanges->ClockMulFactor = 1; + clockRanges->ClockDivFactor = 1; + + /* + * 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 I128ValidMode() already takes + * care of this, we don't worry about setting them here. + */ + { + int *linePitches = NULL; + int minPitch = 256; + int maxPitch = 2048; + int pitchAlignment = 256; + + if (pI128->MemoryType == I128_MEMORY_WRAM) + pitchAlignment = (128 * 8); + pitchAlignment /= pI128->bitsPerPixel; + + i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, + pScrn->display->modes, clockRanges, + linePitches, minPitch, maxPitch, + pitchAlignment * pI128->bitsPerPixel, + 128, 2048, + pScrn->display->virtualX, + pScrn->display->virtualY, + pI128->MemorySize, + LOOKUP_BEST_REFRESH); + + pI128->displayWidth = pScrn->virtualX; + + if ((pScrn->virtualX % pitchAlignment) != 0) + pI128->displayWidth += pitchAlignment - + (pScrn->virtualX % pitchAlignment); + } + + if (i == -1) { + I128FreeRec(pScrn); + return FALSE; + } + + /* Prune the modes marked as invalid */ + xf86PruneDriverModes(pScrn); + + if (i == 0 || pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); + I128FreeRec(pScrn); + return FALSE; + } + + if ((pI128->MemorySize > 4096) && + (pI128->MemoryType != I128_MEMORY_DRAM) && + (pI128->MemoryType != I128_MEMORY_SGRAM)) + pI128->displayOffset = 0x400000L % + (pI128->displayWidth * (pI128->bitsPerPixel/8)); + else + pI128->displayOffset = 0; + + pI128->MemoryPtr = + (pointer)&((char *)pI128->MemoryPtr)[pI128->displayOffset]; + + /* Set the current mode to the first in the list */ + pScrn->currentMode = pScrn->modes; + + /* Print the list of modes being used */ + xf86PrintModes(pScrn); + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + if (!xf86LoadSubModule(pScrn, "fb")) { + I128FreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(fbSymbols, NULL); + + /* Load the acceleration engine */ + if (!pI128->NoAccel) { + if (pI128->exa) { + XF86ModReqInfo req; + int errmaj, errmin; + + memset(&req, 0, sizeof(req)); + req.majorversion = 2; + req.minorversion = 0; + if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req, + &errmaj, &errmin)) + { + LoaderErrorMsg(NULL, "exa", errmaj, errmin); + I128FreeRec(pScrn); + return FALSE; + } else xf86LoaderReqSymLists(exaSymbols, NULL); + } else { + if (!xf86LoadSubModule(pScrn, "xaa")) { + I128FreeRec(pScrn); + return FALSE; + } else xf86LoaderReqSymLists(xaaSymbols, NULL); + } + } + + /* Load ramdac if needed */ + if (pI128->HWCursor) { + if (!xf86LoadSubModule(pScrn, "ramdac")) { + I128FreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(ramdacSymbols, NULL); + } + + I128UnmapMem(pScrn); + + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PreInit complete\n"); + return TRUE; +} + + +static Bool +I128GetRec(ScrnInfoPtr pScrn) +{ + /* + * Allocate an I128Rec, 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(I128Rec), 1); + + return TRUE; +} + +static void +I128FreeRec(ScrnInfoPtr pScrn) +{ + if (pScrn->driverPrivate == NULL) + return; + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; +} + + + +/* + * I128SoftReset -- + * + * Resets drawing engine + */ +static void +I128SoftReset(ScrnInfoPtr pScrn) +{ + I128Ptr pI128 = I128PTR(pScrn); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Performing soft reset\n"); + pI128->io.config1 |= 0x00000002; + outl(pI128->RegRec.iobase + 0x1C, pI128->io.config1); + usleep(10000); + pI128->io.config1 &= 0xFFFFFFFD; + outl(pI128->RegRec.iobase + 0x1C, pI128->io.config1); +} + +/* + * I128CountRAM -- + * + * Counts amount of installed RAM + */ +static int +I128CountRam(ScrnInfoPtr pScrn) +{ + I128Ptr pI128 = I128PTR(pScrn); + int SizeFound = 0; + + SizeFound = 0; + + switch(pI128->Chipset) { + case PCI_CHIP_I128_T2R4: + /* Use the subsystem ID to determine the memory size */ + switch ((pI128->PciInfo->subsysCard) & 0x0007) { + case 0x00: /* 4MB card */ + SizeFound = 4 * 1024; break; + case 0x01: /* 8MB card */ + SizeFound = 8 * 1024; break; + case 0x02: /* 12MB card */ + SizeFound = 12 * 1024; break; + case 0x03: /* 16MB card */ + SizeFound = 16 * 1024; break; + case 0x04: /* 20MB card */ + SizeFound = 20 * 1024; break; + case 0x05: /* 24MB card */ + SizeFound = 24 * 1024; break; + case 0x06: /* 28MB card */ + SizeFound = 28 * 1024; break; + case 0x07: /* 32MB card */ + SizeFound = 32 * 1024; break; + default: /* Unknown board... */ + break; + } + break; + case PCI_CHIP_I128_T2R: + switch ((pI128->PciInfo->subsysCard) & 0xFFF7) { + case 0x00: /* 4MB card, no daughtercard */ + SizeFound = 4 * 1024; break; + case 0x01: /* 4MB card, 4MB daughtercard */ + case 0x04: /* 8MB card, no daughtercard */ + SizeFound = 8 * 1024; break; + case 0x02: /* 4MB card, 8MB daughtercard */ + case 0x05: /* 8MB card, 4MB daughtercard */ + SizeFound = 12 * 1024; break; + case 0x06: /* 8MB card, 8MB daughtercard */ + SizeFound = 16 * 1024; break; + case 0x03: /* 4MB card, 16 daughtercard */ + SizeFound = 20 * 1024; break; + case 0x07: /* 8MB card, 16MB daughtercard */ + SizeFound = 24 * 1024; break; + default: + break; + } + } + + if (SizeFound == 0) { + SizeFound = 2048; /* default to 2MB */ + if (pI128->io.config1 & 0x04) /* 128 bit mode */ + SizeFound <<= 1; + if (pI128->io.id & 0x0400) /* 2 banks VRAM */ + SizeFound <<= 1; + } + return SizeFound; +} + + +/* + * Map the framebuffer and MMIO memory. + */ + +static Bool +I128MapMem(ScrnInfoPtr pScrn) +{ + I128Ptr pI128; + + pI128 = I128PTR(pScrn); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Mapping memory\n"); + + if (pI128->mem.rbase_g != NULL) + return TRUE; + + /* + * Map IO registers to virtual address space + */ + + pI128->mem.mw0_ad = (unsigned char *)xf86MapPciMem(pScrn->scrnIndex, + VIDMEM_FRAMEBUFFER, + pI128->PciTag, + pI128->PciInfo->memBase[0] & 0xFFC00000, + pI128->MemorySize*1024); + if (pI128->mem.mw0_ad == NULL) + return FALSE; + + pI128->MemoryPtr = pI128->mem.mw0_ad; + + pI128->mem.rbase_g = (CARD32 *)xf86MapPciMem(pScrn->scrnIndex, + VIDMEM_MMIO | VIDMEM_MMIO_32BIT, + pI128->PciTag, + pI128->PciInfo->memBase[4] & 0xFFFF0000, + 64*1024); + if (pI128->mem.rbase_g == NULL) + return FALSE; + + pI128->mem.rbase_w = pI128->mem.rbase_g + ( 8 * 1024)/4; + pI128->mem.rbase_a = pI128->mem.rbase_g + (16 * 1024)/4; + pI128->mem.rbase_b = pI128->mem.rbase_g + (24 * 1024)/4; + pI128->mem.rbase_i = pI128->mem.rbase_g + (32 * 1024)/4; + + return TRUE; +} + + +/* + * Unmap the framebuffer and MMIO memory. + */ + +static Bool +I128UnmapMem(ScrnInfoPtr pScrn) +{ + I128Ptr pI128 = I128PTR(pScrn); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Unmapping memory\n"); + + if (pI128->mem.rbase_g == NULL) + return TRUE; + + /* + * Unmap IO registers to virtual address space + */ + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pI128->mem.mw0_ad, + pI128->MemorySize*1024); + pI128->mem.mw0_ad = NULL; + pI128->MemoryPtr = NULL; + + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pI128->mem.rbase_g, 64*1024); + pI128->mem.rbase_g = NULL; + pI128->mem.rbase_w = NULL; + pI128->mem.rbase_a = NULL; + pI128->mem.rbase_b = NULL; + pI128->mem.rbase_i = NULL; + + return TRUE; +} + + +/* + * This function saves the video state. + */ +static void +I128Save(ScrnInfoPtr pScrn) +{ + I128Ptr pI128 = I128PTR(pScrn); + vgaHWPtr vgaHWP = VGAHWPTR(pScrn); + + if (pI128->Primary) + vgaHWSave(pScrn, &vgaHWP->SavedReg, VGA_SR_ALL); + + I128SaveState(pScrn); +} + +/* + * Restore the initial (text) mode. + */ +static void +I128Restore(ScrnInfoPtr pScrn) +{ + I128Ptr pI128 = I128PTR(pScrn); + vgaHWPtr vgaHWP = VGAHWPTR(pScrn); + + I128RestoreState(pScrn); + + if (pI128->Primary) { + vgaHWProtect(pScrn, TRUE); + vgaHWRestore(pScrn, &vgaHWP->SavedReg, VGA_SR_ALL); + vgaHWProtect(pScrn, FALSE); + } +} + +/* Usually mandatory */ +Bool +I128SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + return I128ModeInit(xf86Screens[scrnIndex], mode); +} + + +static Bool +I128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + I128Ptr pI128 = I128PTR(pScrn); + + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ModeInit start\n"); + + /* Initialise the ModeReg values */ + pScrn->vtSema = TRUE; + + if (!I128Init(pScrn, mode)) + return FALSE; + + pI128->ModeSwitched = TRUE; + + pI128->mode = mode; + + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ModeInit complete\n"); + + return TRUE; +} + + +/* Mandatory */ + +/* This gets called at the start of each server generation */ + +static Bool +I128ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn; + I128Ptr pI128; + int ret; + VisualPtr visual; + unsigned char *FBStart; + int width, height, displayWidth; + + /* + * First get the ScrnInfoRec + */ + pScrn = xf86Screens[pScreen->myNum]; + + pI128 = I128PTR(pScrn); + + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ScreenInit start\n"); + + /* Map the I128 memory and MMIO areas */ + if (!I128MapMem(pScrn)) + return FALSE; + + pI128->MemoryPtr = + (pointer)&((char *)pI128->MemoryPtr)[pI128->displayOffset]; + + /* Save the current state */ + I128Save(pScrn); + + /* Initialise the first mode */ + if (!I128ModeInit(pScrn, pScrn->currentMode)) + return FALSE; + + /* Darken the screen for aesthetic reasons and set the viewport */ + I128SaveScreen(pScreen, SCREEN_SAVER_ON); + pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + /* + * The next step is to setup the screen's visuals, and initialise the + * framebuffer code. In cases where the framebuffer's default + * choices for things like visual layouts and bits per RGB are OK, + * this may be as simple as calling the framebuffer's ScreenInit() + * function. If not, the visuals will need to be setup before calling + * a fb ScreenInit() function and fixed up after. + * + * For most PC hardware at depths >= 8, the defaults that fb uses + * are not appropriate. In this driver, we fixup the visuals after. + */ + + /* + * Reset the visual list. + */ + miClearVisualTypes(); + + /* Setup the visuals we support. */ + + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + + if (!miSetPixmapDepths()) + return FALSE; + + + /* + * Call the framebuffer layer's ScreenInit function, and fill in other + * pScreen fields. + */ + + width = pScrn->virtualX; + height = pScrn->virtualY; + displayWidth = pScrn->displayWidth; + + FBStart = pI128->MemoryPtr; + + ret = fbScreenInit(pScreen, FBStart, + width, height, + pScrn->xDpi, pScrn->yDpi, + displayWidth, pScrn->bitsPerPixel); + if (!ret) + return FALSE; + + fbPictureInit(pScreen, 0, 0); + + 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; + } + } + } + + xf86SetBlackWhitePixels(pScreen); + + if (!pI128->NoAccel) { + if (pI128->exa) + ret = I128ExaInit(pScreen); + else { + I128DGAInit(pScreen); + ret = I128XaaInit(pScreen); + } + } + + if (!ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Acceleration setup failed\n"); + return FALSE; + } + + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + xf86SetSilkenMouse(pScreen); + + /* Initialize software cursor. + Must precede creation of the default colormap */ + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + /* Initialize HW cursor layer. + Must follow software cursor initialization*/ + if (pI128->HWCursor) { + ret = TRUE; + switch(pI128->RamdacType) { + case TI3025_DAC: + ret = I128TIHWCursorInit(pScrn); break; + case IBM524_DAC: + case IBM526_DAC: + case IBM528_DAC: + ret = I128IBMHWCursorInit(pScrn); break; + case SILVER_HAMMER_DAC: + ret = I128IBMHWCursorInit(pScrn); break; + default: + break; + } + if(!ret) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + } + + /* Initialise default colourmap */ + if (!miCreateDefColormap(pScreen)) + return FALSE; + + /* Initialize colormap layer. + Must follow initialization of the default colormap */ + if(!xf86HandleColormaps(pScreen, 256, 8, + I128LoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) + return FALSE; + + xf86DPMSInit(pScreen, I128DisplayPowerManagementSet, 0); + + pScrn->memPhysBase = (unsigned long)pI128->MemoryPtr; + pScrn->fbOffset = 0; + + pScreen->SaveScreen = I128SaveScreen; + + /* Wrap the current CloseScreen function */ + pI128->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = I128CloseScreen; + + /* Report any unused options (only for the first generation) */ + if (serverGeneration == 1) { + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + } + + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ScreenInit complete\n"); + + /* Done */ + return TRUE; +} + + +/* + * This function is used to initialize the Start Address - the first + * displayed location in the video memory. + */ +/* Usually mandatory */ +void +I128AdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn; + int Base; + I128Ptr pI128; +#define I128_PAN_MASK 0x01FFFFE0 + + pScrn = xf86Screens[scrnIndex]; + pI128 = I128PTR(pScrn); + + if (pI128->ShowCache && y && pScrn->vtSema) + y += pScrn->virtualY - 1; + + if (x > (pI128->displayWidth - pI128->mode->HDisplay)) + x = pI128->displayWidth - pI128->mode->HDisplay; + + Base = ((y*pI128->displayWidth + x) * (pI128->bitsPerPixel/8)); + pI128->mem.rbase_g[DB_ADR] = + (Base & I128_PAN_MASK) + pI128->displayOffset; MB; + + /* now warp the cursor after the screen move */ + pI128->AdjustCursorXPos = (Base - (Base & I128_PAN_MASK)) + / (pI128->bitsPerPixel/8); +} + +/* + * This is called when VT switching back to the X server. Its job is + * to reinitialise the video mode. + * + */ + +/* Mandatory */ +static Bool +I128EnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + if (!I128ModeInit(pScrn, pScrn->currentMode)) + return FALSE; + I128AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + 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 +I128LeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + I128Restore(pScrn); +} + + +/* + * This is called at the end of each server generation. It restores the + * original (text) mode. It should also unmap the video memory, and free + * any per-generation data allocated by the driver. It should finish + * by unwrapping and calling the saved CloseScreen function. + */ + +/* Mandatory */ +static Bool +I128CloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + I128Ptr pI128 = I128PTR(pScrn); + + if (pScrn->vtSema) { + I128Restore(pScrn); + I128UnmapMem(pScrn); + } + if (pI128->XaaInfoRec) + XAADestroyInfoRec(pI128->XaaInfoRec); + if (pI128->ExaDriver) { + exaDriverFini(pScreen); + xfree(pI128->ExaDriver); + } + if (pI128->CursorInfoRec) + xf86DestroyCursorInfoRec(pI128->CursorInfoRec); + if (pI128->DGAModes) + xfree(pI128->DGAModes); + pScrn->vtSema = FALSE; + + pScreen->CloseScreen = pI128->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} + + +/* Free up any persistent data structures */ + +/* Optional */ +static void +I128FreeScreen(int scrnIndex, int flags) +{ + /* + * This only gets called when a screen is being deleted. It does not + * get called routinely at the end of a server generation. + */ + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(xf86Screens[scrnIndex]); + + I128FreeRec(xf86Screens[scrnIndex]); +} + + +/* Checks if a mode is suitable for the selected chipset. */ + +/* Optional */ +static ModeStatus +I128ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + int lace; + + lace = 1 + ((mode->Flags & V_INTERLACE) != 0); + + if ((mode->CrtcHDisplay <= 2048) && + (mode->CrtcHSyncStart <= 4096) && + (mode->CrtcHSyncEnd <= 4096) && + (mode->CrtcHTotal <= 4096) && + (mode->CrtcVDisplay <= 2048 * lace) && + (mode->CrtcVSyncStart <= 4096 * lace) && + (mode->CrtcVSyncEnd <= 4096 * lace) && + (mode->CrtcVTotal <= 4096 * lace)) { + return(MODE_OK); + } else { + return(MODE_BAD); + } +} + + +/* Do screen blanking */ + +/* Mandatory */ +static Bool +I128SaveScreen(ScreenPtr pScreen, int mode) +{ + ScrnInfoPtr pScrn = NULL; + I128Ptr pI128; + Bool on; + + if (pScreen != NULL) + pScrn = xf86Screens[pScreen->myNum]; + + on = xf86IsUnblank(mode); + + if ((pScrn != NULL) && pScrn->vtSema) { + pI128 = I128PTR(pScrn); + if (on) { + pI128->mem.rbase_g[CRT_1CON] |= 0x40; MB; + } else { + pI128->mem.rbase_g[CRT_1CON] &= ~0x40; MB; + } + } + return TRUE; +} + + +static const int DDC_SDA_IN_MASK = 1 << 1; +static const int DDC_SDA_OUT_MASK = 1 << 2; +static const int DDC_SCL_IN_MASK = 1 << 3; +static const int DDC_SCL_OUT_MASK = 1 << 0; + +static const int DDC_MODE_MASK = 3 << 8; +#if 0 +static const int DDC_MODE_DDC1 = 1 << 8; +#endif +static const int DDC_MODE_DDC2 = 2 << 8; + +#if 0 +static unsigned int +I128DDC1Read(ScrnInfoPtr pScrn) +{ + I128Ptr pI128 = I128PTR(pScrn); + unsigned char val; + unsigned long tmp, ddc; + IOADDRESS iobase; + + iobase = pI128->RegRec.iobase; + ddc = inl(iobase + 0x2C); + if ((ddc & DDC_MODE_MASK) != DDC_MODE_DDC1) { + outl(iobase + 0x2C, DDC_MODE_DDC1); + xf86usleep(40); + } + + /* wait for Vsync */ + do { + tmp = inl(iobase + 0x2C); + } while (tmp & 1); + do { + tmp = inl(iobase + 0x2C); + } while (!(tmp & 1)); + + /* Get the result */ + tmp = inl(iobase + 0x2C); + val = tmp & DDC_SDA_IN_MASK; + + if ((ddc & DDC_MODE_MASK) != DDC_MODE_DDC1) { + outl(iobase + 0x2C, ~DDC_MODE_MASK & ddc); + xf86usleep(40); + } + + return val; +} +#endif + +static void +I128I2CGetBits(I2CBusPtr b, int *clock, int *data) +{ + I128Ptr pI128 = I128PTR(xf86Screens[b->scrnIndex]); + unsigned long ddc; + IOADDRESS iobase; +#if 0 + static int lastclock = -1, lastdata = -1; +#endif + + /* Get the result. */ + iobase = pI128->RegRec.iobase; + ddc = inl(iobase + 0x2C); + + *clock = (ddc & DDC_SCL_IN_MASK) != 0; + *data = (ddc & DDC_SDA_IN_MASK) != 0; + +#if 0 + if (pI128->Debug && ((lastclock != *clock) || (lastdata != *data))) { + xf86DrvMsg(b->scrnIndex, X_INFO, "i2c> c %d d %d\n", *clock, *data); + lastclock = *clock; + lastdata = *data; + } +#endif +} + +static void +I128I2CPutBits(I2CBusPtr b, int clock, int data) +{ + I128Ptr pI128 = I128PTR(xf86Screens[b->scrnIndex]); + unsigned char drv, val; + unsigned long ddc; + unsigned long tmp; + IOADDRESS iobase; + + iobase = pI128->RegRec.iobase; + ddc = inl(iobase + 0x2C); + + val = (clock ? DDC_SCL_IN_MASK : 0) | (data ? DDC_SDA_IN_MASK : 0); + drv = ((clock) ? DDC_SCL_OUT_MASK : 0) | ((data) ? DDC_SDA_OUT_MASK : 0); + + tmp = (DDC_MODE_MASK & ddc) | val | drv; + outl(iobase + 0x2C, tmp); +#if 0 + if (pI128->Debug) + xf86DrvMsg(b->scrnIndex, X_INFO, "i2c> 0x%x\n", tmp); +#endif +} + + +static Bool +I128I2CInit(ScrnInfoPtr pScrn) +{ + I128Ptr pI128 = I128PTR(pScrn); + I2CBusPtr I2CPtr; + IOADDRESS iobase; + unsigned long soft_sw, ddc; + + I2CPtr = xf86CreateI2CBusRec(); + if(!I2CPtr) return FALSE; + + pI128->I2C = I2CPtr; + + I2CPtr->BusName = "DDC"; + I2CPtr->scrnIndex = pScrn->scrnIndex; + I2CPtr->I2CPutBits = I128I2CPutBits; + I2CPtr->I2CGetBits = I128I2CGetBits; + I2CPtr->BitTimeout = 4; + I2CPtr->ByteTimeout = 4; + I2CPtr->AcknTimeout = 4; + I2CPtr->StartTimeout = 4; + + /* soft switch register bits 1,0 control I2C channel */ + iobase = pI128->RegRec.iobase; + soft_sw = inl(iobase + 0x28); + soft_sw &= 0xfffffffc; + soft_sw |= 0x00000001; + outl(iobase + 0x28, soft_sw); + xf86usleep(1000); + + /* set default as ddc2 mode */ + ddc = inl(iobase + 0x2C); + ddc &= ~DDC_MODE_MASK; + ddc |= DDC_MODE_DDC2; + outl(iobase + 0x2C, ddc); + xf86usleep(40); + + if (!xf86I2CBusInit(I2CPtr)) { + return FALSE; + } + return TRUE; +} + + +static xf86MonPtr +I128getDDC(ScrnInfoPtr pScrn) +{ + I128Ptr pI128 = I128PTR(pScrn); + xf86MonPtr MonInfo = NULL; + + /* Initialize I2C bus - used by DDC if available */ + if (pI128->i2cInit) { + pI128->i2cInit(pScrn); + } + /* Read and output monitor info using DDC2 over I2C bus */ + if (pI128->I2C) { + MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, pI128->I2C); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I2C Monitor info: %p\n", + (void *)MonInfo); + xf86PrintEDID(MonInfo); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of I2C Monitor info\n"); + } + if (!MonInfo) { + /* Read and output monitor info using DDC1 */ + if (pI128->ddc1Read) { + MonInfo = xf86DoEDID_DDC1(pScrn->scrnIndex, NULL, pI128->ddc1Read ) ; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC Monitor info: %p\n", + (void *)MonInfo); + xf86PrintEDID(MonInfo); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of DDC Monitor info\n"); + } + } + + if (MonInfo) + xf86SetDDCproperties(pScrn, MonInfo); + + return MonInfo; +} + + +/* + * I128DisplayPowerManagementSet -- + * + * Sets VESA Display Power Management Signaling (DPMS) Mode. + */ +void +I128DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, + int flags) +{ + I128Ptr pI128 = I128PTR(pScrn); + CARD32 snc; + + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128DisplayPowerManagementSet: %d\n", PowerManagementMode); + + if (pI128->RamdacType == TI3025_DAC) return; + + snc = pI128->mem.rbase_g[CRT_1CON]; + + switch (PowerManagementMode) + { + case DPMSModeOn: + /* HSync: On, VSync: On */ + snc |= 0x30; + break; + case DPMSModeStandby: + /* HSync: Off, VSync: On */ + snc = (snc & ~0x10) | 0x20; + break; + case DPMSModeSuspend: + /* HSync: On, VSync: Off */ + snc = (snc & ~0x20) | 0x10; + break; + case DPMSModeOff: + /* HSync: Off, VSync: Off */ + snc &= ~0x30; + break; + } + pI128->mem.rbase_g[CRT_1CON] = snc; MB; +} + +static void +I128DumpBaseRegisters(ScrnInfoPtr pScrn) +{ + I128Ptr pI128 = I128PTR(pScrn); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " PCI Registers\n"); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " MW0_AD 0x%08lx addr 0x%08lx %spre-fetchable\n", + pI128->PciInfo->memBase[0], + pI128->PciInfo->memBase[0] & 0xFFC00000, + pI128->PciInfo->memBase[0] & 0x8 ? "" : "not-"); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " MW1_AD 0x%08lx addr 0x%08lx %spre-fetchable\n", + pI128->PciInfo->memBase[1], + pI128->PciInfo->memBase[1] & 0xFFC00000, + pI128->PciInfo->memBase[1] & 0x8 ? "" : "not-"); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " XYW_AD(A) 0x%08lx addr 0x%08lx\n", + pI128->PciInfo->memBase[2], + pI128->PciInfo->memBase[2] & 0xFFC00000); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " XYW_AD(B) 0x%08lx addr 0x%08lx\n", + pI128->PciInfo->memBase[3], + pI128->PciInfo->memBase[3] & 0xFFC00000); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " RBASE_G 0x%08lx addr 0x%08lx\n", + pI128->PciInfo->memBase[4], + pI128->PciInfo->memBase[4] & 0xFFFF0000); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " IO 0x%08lx addr 0x%08lx\n", + pI128->PciInfo->ioBase[5], + pI128->PciInfo->ioBase[5] & 0xFFFFFF00); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " SSC 0x%08x addr 0x%08x\n", + pI128->PciInfo->subsysCard, + pI128->PciInfo->subsysCard & 0xFFFFFF00); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " SSV 0x%08x addr 0x%08x\n", + pI128->PciInfo->subsysVendor, + pI128->PciInfo->subsysVendor & 0xFFFFFF00); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " RBASE_E 0x%08lx addr 0x%08lx %sdecode-enabled\n\n", + pI128->PciInfo->biosBase, + pI128->PciInfo->biosBase & 0xFFFF8000, + pI128->PciInfo->biosBase & 0x1 ? "" : "not-"); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " PCICMDST 0x%08x 0x%08x\n", + ((pciConfigPtr)pI128->PciInfo->thisCard)->pci_command, + ((pciConfigPtr)pI128->PciInfo->thisCard)->pci_status); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " IO Mapped Registers\n"); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " RBASE_G 0x%08lx addr 0x%08lx\n", + (unsigned long)pI128->io.rbase_g, pI128->io.rbase_g & 0xFFFFFF00UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " RBASE_W 0x%08lx addr 0x%08lx\n", + (unsigned long)pI128->io.rbase_w, pI128->io.rbase_w & 0xFFFFFF00UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " RBASE_A 0x%08lx addr 0x%08lx\n", + (unsigned long)pI128->io.rbase_a, pI128->io.rbase_a & 0xFFFFFF00UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " RBASE_B 0x%08lx addr 0x%08lx\n", + (unsigned long)pI128->io.rbase_b, pI128->io.rbase_b & 0xFFFFFF00UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " RBASE_I 0x%08lx addr 0x%08lx\n", + (unsigned long)pI128->io.rbase_i, pI128->io.rbase_i & 0xFFFFFF00UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " RBASE_E 0x%08lx addr 0x%08lx size 0x%lx\n\n", + (unsigned long)pI128->io.rbase_e, pI128->io.rbase_e & 0xFFFF8000UL, + pI128->io.rbase_e & 0x7UL); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " Miscellaneous IO Registers\n"); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " ID 0x%08lx\n", (unsigned long)pI128->io.id); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " CONFIG1 0x%08lx\n", (unsigned long)pI128->io.config1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " CONFIG2 0x%08lx\n", (unsigned long)pI128->io.config2); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " SGRAM 0x%08lx\n", (unsigned long)pI128->io.sgram); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " SOFT_SW 0x%08lx\n", (unsigned long)pI128->io.soft_sw); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " VGA_CTL 0x%08lx\n", (unsigned long)pI128->io.vga_ctl); +} + + +void +I128DumpActiveRegisters(ScrnInfoPtr pScrn) +{ + I128Ptr pI128 = I128PTR(pScrn); + IOADDRESS iobase; + unsigned long rbase_g, rbase_w, rbase_a, rbase_b, rbase_i, rbase_e; + unsigned long id, config1, config2, sgram, soft_sw, ddc, vga_ctl; + volatile CARD32 *vrba, *vrbg, *vrbw; + + vrba = pI128->mem.rbase_a; + vrbg = pI128->mem.rbase_g; + vrbw = pI128->mem.rbase_w; + + iobase = pI128->RegRec.iobase; + rbase_g = inl(iobase); + rbase_w = inl(iobase + 0x04); + rbase_a = inl(iobase + 0x08); + rbase_b = inl(iobase + 0x0C); + rbase_i = inl(iobase + 0x10); + rbase_e = inl(iobase + 0x14); + id = inl(iobase + 0x18); + config1 = inl(iobase + 0x1C); + config2 = inl(iobase + 0x20); + sgram = inl(iobase + 0x24); + soft_sw = inl(iobase + 0x28); + ddc = inl(iobase + 0x2C); + vga_ctl = inl(iobase + 0x30); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "IO Mapped Registers\n"); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " RBASE_G 0x%08lx addr 0x%08lx\n", + rbase_g, rbase_g & 0xFFFFFF00); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " RBASE_W 0x%08lx addr 0x%08lx\n", + rbase_w, rbase_w & 0xFFFFFF00); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " RBASE_A 0x%08lx addr 0x%08lx\n", + rbase_a, rbase_a & 0xFFFFFF00); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " RBASE_B 0x%08lx addr 0x%08lx\n", + rbase_b, rbase_b & 0xFFFFFF00); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " RBASE_I 0x%08lx addr 0x%08lx\n", + rbase_i, rbase_i & 0xFFFFFF00); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + " RBASE_E 0x%08lx addr 0x%08lx size 0x%lx\n", + rbase_e, rbase_e & 0xFFFF8000, rbase_e & 0x7); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Miscellaneous IO Registers\n"); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " ID 0x%08lx\n", id); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " REV %ld HBT %ld BASE0 %ld VDEN %ld VB %ld BASE1 %ld BASE2 %ld DS %ld\n", + id&7, (id>>3)&3, (id>>6)&3, (id>>8)&3, (id>>10)&1, + (id>>11)&3, (id>>13)&3, (id>>15)&1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " DDEN %ld DB %ld BASE3 %ld BASER %ld MDEN %ld TR %ld VS %ld\n", + (id>>16)&3, (id>>18)&1, (id>>19)&3, (id>>21)&7, (id>>24)&3, + (id>>26)&1, (id>>27)&1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CLASS %ld EE %ld\n", + (id>>28)&3, (id>>30)&1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CONFIG1 0x%08lx\n", config1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " VE %ld SFT_RST %ld ONE28 %ld VS %ld\n", + config1&1, (config1>>1)&1, + (config1>>2)&1, (config1>>3)&1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " G %ld W %ld A %ld B %ld I %ld E %ld W0 %ld W1 %ld XA %ld XB %ld\n", + (config1>>8)&1, (config1>>9)&1, + (config1>>10)&1, (config1>>11)&1, + (config1>>12)&1, (config1>>13)&1, + (config1>>16)&1, (config1>>17)&1, + (config1>>20)&1, (config1>>21)&1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " HBPRI %ld VBPRI %ld DE1PRI %ld ISAPRI %ld\n", + (config1>>24)&3, (config1>>26)&3, + (config1>>28)&3, (config1>>30)&3); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CONFIG2 0x%08lx\n", config2); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " DWT %lx EWS %lx DWS %lx MC %lx FBB %ld IOB %ld FST %ld CNT %ld DEC %ld\n", + config2&0x3, (config2>>8)&0xF, + (config2>>16)&0x7, (config2>>20)&0xF, + (config2>>24)&1, (config2>>25)&1, + (config2>>26)&1, (config2>>27)&1, + (config2>>28)&1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " PRE %ld RVD %ld SDAC %ld\n", + (config2>>29)&1, (config2>>30)&1, (config2>>31)&1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " SGRAM 0x%08lx\n", sgram); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " SOFT_SW 0x%08lx\n", soft_sw); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " DDC 0x%08lx\n", ddc); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " VGA_CTL 0x%08lx\n", vga_ctl); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " MEMMUX %ld VGADEC %ld VIDMUX %ld ENA %ld BUFSEL %ld STR %ld\n", + vga_ctl&1, (vga_ctl>>1)&1, + (vga_ctl>>2)&1, (vga_ctl>>3)&1, + (vga_ctl>>4)&1, (vga_ctl>>5)&1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " 3C2 %ld DACDEC %ld MSK 0x%02lx\n", + (vga_ctl>>6)&1, + (vga_ctl>>7)&1, + (vga_ctl>>8)&0xff); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT Registers\n"); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " INT_VCNT 0x%08lx (%ld)\n", + vrbg[0x20/4]&0x000000FFUL, vrbg[0x20/4]&0x000000FFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " INT_HCNT 0x%08lx (%ld)\n", + vrbg[0x24/4]&0x00000FFFUL, vrbg[0x24/4]&0x00000FFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " DB_ADR 0x%08lx (%ld)\n", + vrbg[0x28/4]&0x01FFFFF0UL, vrbg[0x28/4]&0x01FFFFF0UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " DB_PTCH 0x%08lx (%ld)\n", + vrbg[0x2C/4]&0x0000FFF0UL, vrbg[0x2C/4]&0x0000FFF0UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CRT_HAC 0x%08lx (%ld)\n", + vrbg[0x30/4]&0x00003FFFUL, vrbg[0x30/4]&0x00003FFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CRT_HBL 0x%08lx (%ld)\n", + vrbg[0x34/4]&0x00003FFFUL, vrbg[0x34/4]&0x00003FFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CRT_HFP 0x%08lx (%ld)\n", + vrbg[0x38/4]&0x00003FFFUL, vrbg[0x38/4]&0x00003FFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CRT_HS 0x%08lx (%ld)\n", + vrbg[0x3C/4]&0x00003FFFUL, vrbg[0x3C/4]&0x00003FFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CRT_VAC 0x%08lx (%ld)\n", + vrbg[0x40/4]&0x00000FFFUL, vrbg[0x40/4]&0x00000FFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CRT_VBL 0x%08lx (%ld)\n", + vrbg[0x44/4]&0x00000FFFUL, vrbg[0x44/4]&0x00000FFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CRT_VFP 0x%08lx (%ld)\n", + vrbg[0x48/4]&0x00000FFFUL, vrbg[0x48/4]&0x00000FFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CRT_VS 0x%08lx (%ld)\n", + vrbg[0x4C/4]&0x00000FFFUL, vrbg[0x4C/4]&0x00000FFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CRT_LCNT 0x%08lx\n", + vrbg[0x50/4]&0x00000FFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CRT_ZOOM 0x%08lx\n", + vrbg[0x54/4]&0x0000000FUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CRT_1CON 0x%08lx PH %ld PV %ld CS %ld INL %ld H/VSE %ld/%ld VE %ld BTS %ld\n", + (unsigned long)vrbg[0x58/4], + vrbg[0x58/4]&1UL, (vrbg[0x58/4]>>1)&1UL, (vrbg[0x58/4]>>2)&1UL, + (vrbg[0x58/4]>>3)&1UL, (vrbg[0x58/4]>>4)&1UL, (vrbg[0x58/4]>>5)&1UL, + (vrbg[0x58/4]>>6)&1UL, (vrbg[0x58/4]>>8)&1UL); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CRT_2CON 0x%08lx MEM %ld RFR %ld TRD %ld SPL %ld\n", + (unsigned long)vrbg[0x5C/4], + vrbg[0x5C/4]&7UL, (vrbg[0x5C/4]>>8)&1UL, + (vrbg[0x5C/4]>>16)&7UL, (vrbg[0x5C/4]>>24)&1UL); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory Windows Registers\n"); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " MW0_CTRL 0x%08lx\n", + (unsigned long)vrbw[0x00]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " AMV %ld MP %ld AMD %ld SEN %ld BSY %ld MDM %ld DEN %ld PSZ %ld\n", + (vrbw[0x00]>>1)&1UL, (vrbw[0x00]>>2)&1UL, (vrbw[0x00]>>3)&1UL, + (vrbw[0x00]>>4)&3UL, (vrbw[0x00]>>8)&1UL, (vrbw[0x00]>>21)&3UL, + (vrbw[0x00]>>24)&3UL, (vrbw[0x00]>>26)&3UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "M/V/DSE %ld/%ld/%ld\n", + (vrbw[0x00]>>28)&1UL, (vrbw[0x00]>>29)&1UL, (vrbw[0x00]>>30)&1UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " MW0_AD 0x%08lx MW0_SZ 0x%08lx MW0_PGE 0x%08lx\n", + vrbw[0x04/4]&0xFFFFF000UL, vrbw[0x08/4]&0x0000000FUL, + vrbw[0x0C/4]&0x000F001FUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " MW0_ORG10 0x%08lx MW0_ORG14 0x%08lx MW0_MSRC 0x%08lx\n", + vrbw[0x10/4]&0x01FFF000UL, vrbw[0x14/4]&0x01FFF000UL, + vrbw[0x18/4]&0x00FFFF00UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " MW0_WKEY 0x%08lx MW0_KYDAT 0x%08lx MW0_MASK 0x%08lx\n", + (unsigned long)vrbw[0x1C/4], vrbw[0x20/4]&0x000F000FUL, + (unsigned long)vrbw[0x24/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " MW1_CTRL 0x%08lx\n", + (unsigned long)vrbw[0x28/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " AMV %ld MP %ld AMD %ld SEN %ld BSY %ld MDM %ld DEN %ld PSZ %ld\n", + (vrbw[0x28/4]>>1)&1UL, (vrbw[0x28/4]>>2)&1UL, (vrbw[0x28/4]>>3)&1UL, + (vrbw[0x28/4]>>4)&3UL, (vrbw[0x28/4]>>8)&1UL, (vrbw[0x28/4]>>21)&3UL, + (vrbw[0x28/4]>>24)&3UL, (vrbw[0x28/4]>>26)&3UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "M/V/DSE %ld/%ld/%ld\n", + (vrbw[0x28/4]>>28)&1UL, (vrbw[0x28/4]>>29)&1UL, (vrbw[0x28/4]>>30)&1UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " MW1_AD 0x%08lx MW1_SZ 0x%08lx MW1_PGE 0x%08lx\n", + vrbw[0x2C/4]&0xFFFFF000UL, vrbw[0x30/4]&0x0000000FUL, + vrbw[0x34/4]&0x000F001FUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " MW1_ORG10 0x%08lx MW1_ORG14 0x%08lx MW1_MSRC 0x%08lx\n", + vrbw[0x38/4]&0x01FFF000UL, vrbw[0x3c/4]&0x01FFF000UL, + vrbw[0x40/4]&0x00FFFF00UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " MW1_WKEY 0x%08lx MW1_KYDAT 0x%08lx MW1_MASK 0x%08lx\n", + (unsigned long)vrbw[0x44/4], vrbw[0x48/4]&0x000F000FUL, + (unsigned long)vrbw[0x4C/4]); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Engine A Registers\n"); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " INTP 0x%08lx\n", + vrba[0x00/4]&0x03UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " INTM 0x%08lx\n", + vrba[0x04/4]&0x03UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " FLOW 0x%08lx\n", + vrba[0x08/4]&0x0FUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " BUSY 0x%08lx\n", + vrba[0x0C/4]&0x01UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " XYW_AD 0x%08lx SIZE 0x%lx ADDR 0x%lx\n", + vrba[0x10/4]&0xFFFFFF00UL, (vrba[0x10/4]>>8)&0x0000000FUL, + vrba[0x10/4]&0xFFFFF000UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " ZCTL 0x%08lx\n", + (unsigned long)vrba[0x18/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " BUF_CTRL 0x%08lx\n", + (unsigned long)vrba[0x20/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " AMV %ld MP %ld AMD %ld SEN %ld DEN %ld DSE %ld VSE %ld MSE %ld\n", + (vrba[0x20/4]>>1)&1UL, (vrba[0x20/4]>>2)&1UL, (vrba[0x20/4]>>3)&1UL, + (vrba[0x20/4]>>8)&3UL, (vrba[0x20/4]>>10)&3UL, (vrba[0x20/4]>>12)&1UL, + (vrba[0x20/4]>>13)&1UL, (vrba[0x20/4]>>14)&1UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " PS %ld MDM %ld PSIZE %ld CRCO %ld\n", + (vrba[0x20/4]>>16)&0x1FUL, + (vrba[0x20/4]>>21)&3UL, (vrba[0x20/4]>>24)&3UL, (vrba[0x20/4]>>30)&3UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " DE_PGE 0x%08lx DVPGE 0x%lx MPGE 0x%lx\n", + vrba[0x24/4]&0x000F001FUL, (vrba[0x24/4]>>8)&0x01FUL, + (vrba[0x24/4]&0x000F0000UL)>>16); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " DE_SORG 0x%08lx\n", + vrba[0x28/4]&0x0FFFFFFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " DE_DORG 0x%08lx\n", + vrba[0x2C/4]&0x0FFFFFFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " DE_MSRC 0x%08lx\n", + vrba[0x30/4]&0x03FFFFF0UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " DE_WKEY 0x%08lx\n", + (unsigned long)vrba[0x38/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " DE_ZPTCH 0x%08lx\n", + vrba[0x3C/4]&0x000FFFF0UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " DE_SPTCH 0x%08lx\n", + vrba[0x40/4]&0x0000FFF0UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " DE_DPTCH 0x%08lx\n", + vrba[0x44/4]&0x0000FFF0UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CMD 0x%08lx\n", + vrba[0x48/4]&0x7FFFFFFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " OPC 0x%02lx ROP 0x%02lx STYLE 0x%02lx CLP 0x%lx PATRN 0x%lx HDF %ld\n", + vrba[0x48/4]&0x00FFUL, (vrba[0x48/4]>>8)&0x00FFUL, (vrba[0x48/4]>>16)&0x001FUL, + (vrba[0x48/4]>>21)&7UL, (vrba[0x48/4]>>24)&0x0FUL, (vrba[0x48/4]>>28)&7UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CMD_SHADE 0x%02lx\n", + vrba[0x4C/4]&0x00FFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CMD_OPC 0x%02lx\n", + vrba[0x50/4]&0x00FFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CMD_ROP 0x%02lx\n", + vrba[0x54/4]&0x00FFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CMD_STYLE 0x%02lx\n", + vrba[0x58/4]&0x001FUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CMD_PATRN 0x%02lx\n", + vrba[0x5C/4]&0x000FUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CMD_CLP 0x%02lx\n", + vrba[0x60/4]&0x0007UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CMD_HDF 0x%02lx\n", + vrba[0x64/4]&0x0007UL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " FORE 0x%08lx\n", + (unsigned long)vrba[0x68/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " BACK 0x%08lx\n", + (unsigned long)vrba[0x6C/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " MASK 0x%08lx\n", + (unsigned long)vrba[0x70/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " RMSK 0x%08lx\n", + (unsigned long)vrba[0x74/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " LPAT 0x%08lx\n", + (unsigned long)vrba[0x78/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " PCTRL 0x%08lx\n", + (unsigned long)vrba[0x7C/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " PLEN 0x%02ld PSCL 0x%02ld SPTR 0x%02ld SSCL 0x%lx STATE 0x%04lx\n", + vrba[0x7C/4]&0x1FUL, (vrba[0x7C/4]>>5)&7UL, (vrba[0x7C/4]>>8)&0x1FUL, + (vrba[0x7C/4]>>13)&7UL, (vrba[0x7C/4]>>16)&0xFFFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CLPTL 0x%08lx CLPTLY 0x%04lx CLPTLX 0x%04lx\n", + (unsigned long)vrba[0x80/4], vrba[0x80/4]&0x00FFFFUL, (vrba[0x80/4]>>16)&0x00FFFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " CLPBR 0x%08lx CLPBRY 0x%04lx CLPBRX 0x%04lx\n", + (unsigned long)vrba[0x84/4], + vrba[0x84/4]&0x00FFFFUL, (vrba[0x84/4]>>16)&0x00FFFFUL); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " XY0 0x%08lx\n", + (unsigned long)vrba[0x88/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " XY1 0x%08lx\n", + (unsigned long)vrba[0x8C/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " XY2 0x%08lx\n", + (unsigned long)vrba[0x90/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " XY3 0x%08lx\n", + (unsigned long)vrba[0x94/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " XY4 0x%08lx\n", + (unsigned long)vrba[0x98/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " XY5 0x%08lx\n", + (unsigned long)vrba[0x9C/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " XY6 0x%08lx\n", + (unsigned long)vrba[0xA0/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " XY7 0x%08lx\n", + (unsigned long)vrba[0xA4/4]); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " XY8 0x%08lx\n", + (unsigned long)vrba[0xA8/4]); + if (pI128->RamdacType != TI3025_DAC) + I128DumpIBMDACRegisters(pScrn, vrbg); +} + +static const unsigned char ibm52Xmask[0xA0] = { +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 00-07 */ +0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* 08-0F */ +0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, /* 10-17 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18-1F */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, /* 20-27 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28-2F */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* 30-37 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38-3F */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 40-47 */ +0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 48-4F */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 58-5F */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 58-5F */ +0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, /* 60-67 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 68-6F */ +0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, /* 70-77 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78-7F */ +0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, /* 80-87 */ +0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, /* 88-8F */ +0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, /* 90-97 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 98-9F */ +}; + +static void +I128DumpIBMDACRegisters(ScrnInfoPtr pScrn, volatile CARD32 *vrbg) +{ + unsigned char ibmr[0x100]; + char buf[128], tbuf[10]; + int i; + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "IBM52X Registers\n"); + + vrbg[IDXH_I] = 0x00; + vrbg[IDXH_I] = 0x00; + vrbg[IDXCTL_I] = 0x01; + buf[0] = '\0'; + + for (i=0; i<0xA0; i++) { + if ((i%16 == 0) && (i != 0)) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%s\n", buf); + buf[0] = '\0'; + } + if (ibm52Xmask[i] == 0x00) { + strcat(buf, " .."); + } else { + vrbg[IDXL_I] = i; + ibmr[i] = vrbg[DATA_I] & 0xFF; + ibmr[i] &= ibm52Xmask[i]; + sprintf(tbuf, " %02x", ibmr[i]); + strcat(buf, tbuf); + } + } + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%s\n", buf); +} + diff --git a/driver/xf86-video-i128/src/i128accel.c b/driver/xf86-video-i128/src/i128accel.c new file mode 100644 index 000000000..da1f9af86 --- /dev/null +++ b/driver/xf86-video-i128/src/i128accel.c @@ -0,0 +1,520 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128accel.c,v 1.7 2000/12/06 01:07:34 robin Exp $ */ + +/* + * Copyright 1997-2000 by Robin Cutshaw <robin@XFree86.Org> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Robin Cutshaw not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Robin Cutshaw makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ROBIN CUTSHAW DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ROBIN CUTSHAW 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 "xaa.h" +#include "xaalocal.h" +#include "xf86fbman.h" +#include "miline.h" +#include "servermd.h" + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" + +#include "i128.h" +#include "i128reg.h" + +static void I128BitBlit(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, + int w, int h); +static void I128SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, + int ydir, int rop, unsigned planemask, int transparency_color); +static void I128SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h); +static void I128SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, + unsigned planemask); +static void I128SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, + int h); +static void I128SubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int flags); +static void I128SetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2); +static void I128FillSolidRects(ScrnInfoPtr pScrn, int fg, int rop, + unsigned int planemask, int nBox, register BoxPtr pBoxI); +static void I128ScreenToScreenBitBlt(ScrnInfoPtr pScrn, int nbox, + DDXPointPtr pptSrc, BoxPtr pbox, int xdir, int ydir, int alu, + unsigned planemask); + +#define ENG_PIPELINE_READY() { while (pI128->mem.rbase_a[BUSY] & BUSY_BUSY) ; } +#define ENG_DONE() { while (pI128->mem.rbase_a[FLOW] & (FLOW_DEB | FLOW_MCB | FLOW_PRV)) ;} + + +/* pre-shift rops and just or in as needed */ + +static const CARD32 i128alu[16] = +{ + CR_CLEAR<<8, + CR_AND<<8, + CR_AND_REV<<8, + CR_COPY<<8, + CR_AND_INV<<8, + CR_NOOP<<8, + CR_XOR<<8, + CR_OR<<8, + CR_NOR<<8, + CR_EQUIV<<8, + CR_INVERT<<8, + CR_OR_REV<<8, + CR_COPY_INV<<8, + CR_OR_INV<<8, + CR_NAND<<8, + CR_SET<<8 +}; + /* 8bpp 16bpp 32bpp unused */ +static const int min_size[] = { 0x62, 0x32, 0x1A, 0x00 }; +static const int max_size[] = { 0x80, 0x40, 0x20, 0x00 }; +static const int split_size[] = { 0x20, 0x10, 0x08, 0x00 }; + + +void +I128EngineDone(ScrnInfoPtr pScrn) +{ + I128Ptr pI128 = I128PTR(pScrn); + ENG_DONE(); +} + + +static void +I128BitBlit(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w, int h) +{ + I128Ptr pI128 = I128PTR(pScrn); + +#if 0 + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BB %d,%d %d,%d %d,%d 0x%x/0x%x\n", x1, y1, x2, y2, w, h, pI128->cmd); +#endif + + ENG_PIPELINE_READY(); + + pI128->mem.rbase_a[CMD] = pI128->cmd; + /*pI128->mem.rbase_a[XY3_DIR] = pI128->blitdir;*/ + + if (pI128->blitdir & DIR_RL_TB) { + x1 += w; x1--; + x2 += w; x2--; + } + if (pI128->blitdir & DIR_LR_BT) { + y1 += h; y1--; + y2 += h; y2--; + } + + + + if (pI128->Chipset == PCI_CHIP_I128) { + int bppi; + + static int first_time_through = 1; + + /* The I128-1 has a nasty bitblit bug + * that occurs when dest is exactly 8 pages wide + */ + + bppi = (pI128->mem.rbase_a[BUF_CTRL] & BC_PSIZ_MSK) >> 24; + + if ((w >= min_size[bppi]) && (w <= max_size[bppi])) { + if (first_time_through) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using I128-1 workarounds.\n"); + first_time_through = 0; + } + + bppi = split_size[bppi]; +#if 1 + /* split method */ + + pI128->mem.rbase_a[XY2_WH] = (bppi<<16) | h; + pI128->mem.rbase_a[XY0_SRC] = (x1<<16) | y1; MB; + pI128->mem.rbase_a[XY1_DST] = (x2<<16) | y2; MB; + + ENG_PIPELINE_READY(); + + w -= bppi; + + if (pI128->blitdir & DIR_RL_TB) { + /* right to left blit */ + x1 -= bppi; + x2 -= bppi; + } else { + /* left to right blit */ + x1 += bppi; + x2 += bppi; + } +#else + /* clip method */ + pI128->mem.rbase_a[CLPTL] = (x2<<16) | y2; + pI128->mem.rbase_a[CLPBR] = ((x2+w)<<16) | (y2+h); + w += bppi; +#endif + } + } + + pI128->mem.rbase_a[XY2_WH] = (w<<16) | h; + pI128->mem.rbase_a[XY0_SRC] = (x1<<16) | y1; MB; + pI128->mem.rbase_a[XY1_DST] = (x2<<16) | y2; MB; +} + +static void +I128SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, + int rop, unsigned planemask, int transparency_color) +{ + I128Ptr pI128 = I128PTR(pScrn); + +#if 0 + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SFSSC %d,%d %d 0x%x %d\n", xdir, ydir, rop, planemask, transparency_color); +#endif + + ENG_PIPELINE_READY(); + + if (planemask == -1) + pI128->mem.rbase_a[MASK] = -1; + else switch (pI128->bitsPerPixel) { + case 8: + pI128->mem.rbase_a[MASK] = planemask | + (planemask<<8) | + (planemask<<16) | + (planemask<<24); + break; + case 16: + pI128->mem.rbase_a[MASK] = planemask | (planemask<<16); + break; + case 24: + case 32: + default: + pI128->mem.rbase_a[MASK] = planemask; + break; + } + + + pI128->mem.rbase_a[CLPTL] = 0x00000000; + pI128->mem.rbase_a[CLPBR] = (4095<<16) | 2047; + + if (transparency_color != -1) + pI128->mem.rbase_a[BACK] = transparency_color; + + + if (xdir == -1) { + if (ydir == -1) pI128->blitdir = DIR_RL_BT; + else pI128->blitdir = DIR_RL_TB; + } else { + if (ydir == -1) pI128->blitdir = DIR_LR_BT; + else pI128->blitdir = DIR_LR_TB; + } + pI128->mem.rbase_a[XY3_DIR] = pI128->blitdir; + + pI128->rop = i128alu[rop]; + pI128->cmd = (transparency_color != -1 ? (CS_TRNSP<<16) : 0) | + pI128->rop | CO_BITBLT; + pI128->mem.rbase_a[CMD] = pI128->cmd; +} + +static void +I128SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h) +{ + I128BitBlit(pScrn, x1, y1, x2, y2, w, h); +} + +static void +I128SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, unsigned planemask) +{ + I128Ptr pI128 = I128PTR(pScrn); + +#if 0 + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SFSF color 0x%x rop 0x%x (I128rop 0x%x) pmask 0x%x\n", color, rop, i128alu[rop]>>8, planemask); +#endif + + ENG_PIPELINE_READY(); + + if (planemask == -1) + pI128->mem.rbase_a[MASK] = -1; + else switch (pI128->bitsPerPixel) { + case 8: + pI128->mem.rbase_a[MASK] = planemask | + (planemask<<8) | + (planemask<<16) | + (planemask<<24); + break; + case 16: + pI128->mem.rbase_a[MASK] = planemask | (planemask<<16); + break; + case 24: + case 32: + default: + pI128->mem.rbase_a[MASK] = planemask; + break; + } + + pI128->mem.rbase_a[FORE] = color; + + pI128->clptl = pI128->mem.rbase_a[CLPTL] = 0x00000000; + pI128->clpbr = pI128->mem.rbase_a[CLPBR] = (4095<<16) | 2047 ; + + pI128->mem.rbase_a[XY3_DIR] = pI128->blitdir = DIR_LR_TB; + + pI128->rop = i128alu[rop]; + pI128->cmd = (CS_SOLID<<16) | pI128->rop | CO_BITBLT; + pI128->mem.rbase_a[CMD] = pI128->cmd; +} + +static void +I128SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) +{ +#if 0 + I128Ptr pI128 = I128PTR(pScrn); + + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SSFR %d,%d %d,%d\n", x, y, w, h); +#endif + I128BitBlit(pScrn, 0, 0, x, y, w, h); +} + +static void +I128SubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, + int y2, int flags) +{ + I128Ptr pI128 = I128PTR(pScrn); + +#if 0 + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "STPL I128rop 0x%x %d,%d %d,%d clip %d,%d %d,%d\n", pI128->rop, x1, y1, x2, y2, pI128->clptl>>16, pI128->clptl&0xffff, (pI128->clpbr>>16)&0xffff, pI128->clpbr&0xffff); +#endif + + ENG_PIPELINE_READY(); + + pI128->mem.rbase_a[CMD] = + ((flags&0x0100) ? (CP_NLST<<24) : 0) | + (CC_CLPRECI<<21) | + (CS_SOLID<<16) | + pI128->rop | + CO_LINE; + + pI128->mem.rbase_a[CLPTL] = pI128->clptl; + pI128->mem.rbase_a[CLPBR] = pI128->clpbr; + + pI128->mem.rbase_a[XY0_SRC] = (x1<<16) | y1; MB; + pI128->mem.rbase_a[XY1_DST] = (x2<<16) | y2; MB; +} + +static void +I128SetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) +{ + I128Ptr pI128 = I128PTR(pScrn); + int tmp; + +#if 0 + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SCR %d,%d %d,%d\n", x1, y1, x2, y2); +#endif + + if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } + if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } + + pI128->clptl = (x1<<16) | y1; + pI128->clpbr = (x2<<16) | y2; +} + + +static void +I128FillSolidRects(ScrnInfoPtr pScrn, int fg, int rop, unsigned int planemask, + int nBox, register BoxPtr pBoxI) +{ + I128Ptr pI128 = I128PTR(pScrn); + register int w, h; + +#if 0 + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "FSR color 0x%x rop 0x%x (I128rop 0x%x) pmask 0x%x\n", fg, rop, i128alu[rop]>>8, planemask); +#endif + + ENG_PIPELINE_READY(); + + if (planemask != -1) { + if (pI128->bitsPerPixel == 8) { + planemask |= (planemask<<8) | + (planemask<<16) | + (planemask<<24); + } else if (pI128->bitsPerPixel == 16) + planemask |= planemask<<16; + } + + pI128->mem.rbase_a[MASK] = planemask; + pI128->mem.rbase_a[FORE] = fg; + pI128->mem.rbase_a[CMD] = (CS_SOLID<<16) | i128alu[rop] | CO_BITBLT; + pI128->mem.rbase_a[CLPTL] = 0x00000000; + pI128->mem.rbase_a[CLPBR] = (4095<<16) | 2047; + + pI128->mem.rbase_a[XY3_DIR] = DIR_LR_TB; + pI128->mem.rbase_a[XY0_SRC] = 0x00000000; + + while (nBox > 0) { + w = pBoxI->x2 - pBoxI->x1; + h = pBoxI->y2 - pBoxI->y1; + if (w > 0 && h > 0) { + pI128->mem.rbase_a[XY2_WH] = (w<<16) | h; MB; + pI128->mem.rbase_a[XY1_DST] = + (pBoxI->x1<<16) | pBoxI->y1; MB; + + ENG_PIPELINE_READY(); +#if 0 + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "FSR x,y %d,%d w,h %d,%d\n", pBoxI->x1, pBoxI->y1, w, h); +#endif + + } + pBoxI++; + nBox--; + } + + ENG_DONE(); + +} + + +static void +I128ScreenToScreenBitBlt(ScrnInfoPtr pScrn, int nbox, DDXPointPtr pptSrc, + BoxPtr pbox, int xdir, int ydir, int alu, unsigned planemask) +{ + I128Ptr pI128 = I128PTR(pScrn); + I128SetupForScreenToScreenCopy(pScrn, xdir, ydir, alu, planemask, -1); + for (; nbox; pbox++, pptSrc++, nbox--) + I128SubsequentScreenToScreenCopy(pScrn, pptSrc->x, pptSrc->y, + pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); + ENG_DONE(); +} + + +Bool +I128XaaInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I128Ptr pI128 = I128PTR(pScrn); + BoxRec AvailFBArea; + CARD32 buf_ctrl; + int maxlines; + + pI128->XaaInfoRec = infoPtr = XAACreateInfoRec(); + if (!infoPtr) return FALSE; + + infoPtr->Flags = PIXMAP_CACHE | + OFFSCREEN_PIXMAPS | + LINEAR_FRAMEBUFFER ; + + infoPtr->Sync = I128EngineDone; + + /* screen to screen copy */ + infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY; + if (pI128->Chipset == PCI_CHIP_I128_T2R) + infoPtr->ScreenToScreenCopyFlags |= ONLY_LEFT_TO_RIGHT_BITBLT; + + infoPtr->SetupForScreenToScreenCopy = I128SetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = + I128SubsequentScreenToScreenCopy; + +#if 0 + /* screen to screen color expansion */ + if (pI128->Chipset == PCI_CHIP_I128_T2R) + infoPtr->ScreenToScreenColorExpandFillFlags |= + ONLY_LEFT_TO_RIGHT_BITBLT; + + infoPtr->SetupForScreenToScreenColorExpandFill = + I128SetupForScreenToScreenColorExpandFill; + infoPtr->SubsequentScreenToScreenColorExpandFill = + I128SubsequentScreenToScreenColorExpandFill; +#endif + + /* solid fills */ + infoPtr->SetupForSolidFill = I128SetupForSolidFill; + infoPtr->SubsequentSolidFillRect = I128SubsequentSolidFillRect; + + infoPtr->FillSolidRects = I128FillSolidRects; + + /* solid lines */ + infoPtr->SubsequentSolidTwoPointLine = I128SubsequentSolidTwoPointLine; + + /* clipping */ + infoPtr->ClippingFlags = HARDWARE_CLIP_LINE; + infoPtr->SetClippingRectangle = I128SetClippingRectangle; + + infoPtr->PolyFillRectSolidFlags = 0; + + maxlines = ((pI128->MemorySize * 1024) - 1024) / + (pScrn->displayWidth * pI128->bitsPerPixel / 8); + AvailFBArea.x1 = 0; + AvailFBArea.x2 = pI128->displayWidth; + AvailFBArea.y1 = 0; + AvailFBArea.y2 = maxlines; + xf86InitFBManager(pScreen, &AvailFBArea); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d lines for offscreen memory\n", + maxlines - pScrn->virtualY); + + switch (pI128->bitsPerPixel) { + case 8: buf_ctrl = BC_PSIZ_8B; break; + case 16: buf_ctrl = BC_PSIZ_16B; break; + case 24: + case 32: buf_ctrl = BC_PSIZ_32B; break; + default: buf_ctrl = 0; break; /* error */ + } + if (pI128->Chipset == PCI_CHIP_I128_T2R) { + if (pI128->MemoryType == I128_MEMORY_SGRAM) + buf_ctrl |= BC_MDM_PLN; + else + buf_ctrl |= BC_BLK_ENA; + } + pI128->mem.rbase_a[BUF_CTRL] = buf_ctrl; + + pI128->mem.rbase_a[DE_PGE] = 0x00; + pI128->mem.rbase_a[DE_SORG] = pI128->displayOffset; + pI128->mem.rbase_a[DE_DORG] = pI128->displayOffset; + pI128->mem.rbase_a[DE_MSRC] = 0x00; + pI128->mem.rbase_a[DE_WKEY] = 0x00; + pI128->mem.rbase_a[DE_SPTCH] = pI128->mem.rbase_g[DB_PTCH]; + pI128->mem.rbase_a[DE_DPTCH] = pI128->mem.rbase_g[DB_PTCH]; + if (pI128->Chipset == PCI_CHIP_I128_T2R4) + pI128->mem.rbase_a[DE_ZPTCH] = pI128->mem.rbase_g[DB_PTCH]; + pI128->mem.rbase_a[RMSK] = 0x00000000; + pI128->mem.rbase_a[XY4_ZM] = ZOOM_NONE; + pI128->mem.rbase_a[LPAT] = 0xffffffff; /* for lines */ + pI128->mem.rbase_a[PCTRL] = 0x00000000; /* for lines */ + pI128->mem.rbase_a[CLPTL] = 0x00000000; + pI128->mem.rbase_a[CLPBR] = (4095<<16) | 2047 ; + pI128->mem.rbase_a[ACNTRL] = 0x00000000; + pI128->mem.rbase_a[INTM] = 0x03; + + if (pI128->Debug) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I128XaaInit done\n"); + I128DumpActiveRegisters(pScrn); + } + + return(XAAInit(pScreen, infoPtr)); +} diff --git a/driver/xf86-video-i128/src/i128dga.c b/driver/xf86-video-i128/src/i128dga.c new file mode 100644 index 000000000..1ceae5fbd --- /dev/null +++ b/driver/xf86-video-i128/src/i128dga.c @@ -0,0 +1,278 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128dga.c,v 1.3tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" +#include "xaa.h" +#include "xaalocal.h" +#include "i128.h" +#include "dgaproc.h" + + +static Bool I128_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, + int *, int *, int *); +static Bool I128_SetMode(ScrnInfoPtr, DGAModePtr); +static int I128_GetViewport(ScrnInfoPtr); +static void I128_SetViewport(ScrnInfoPtr, int, int, int); +static void I128_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); +static void I128_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); +#if 0 +static void I128_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, + unsigned long); +#endif + +static +DGAFunctionRec I128_DGAFuncs = { + I128_OpenFramebuffer, + NULL, + I128_SetMode, + I128_SetViewport, + I128_GetViewport, + I128EngineDone, + I128_FillRect, + I128_BlitRect, +#if 0 + I128_BlitTransRect +#else + NULL +#endif +}; + + +Bool +I128DGAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I128Ptr pI128 = I128PTR(pScrn); + DGAModePtr modes = NULL, newmodes = NULL, currentMode; + DisplayModePtr pMode, firstMode; + int Bpp = pScrn->bitsPerPixel >> 3; + int num = 0; + Bool oneMore; + + pMode = firstMode = pScrn->modes; + + while(pMode) { + + if(0 /*pScrn->displayWidth != pMode->HDisplay*/) { + newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec)); + oneMore = TRUE; + } else { + newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec)); + oneMore = FALSE; + } + + if(!newmodes) { + xfree(modes); + return FALSE; + } + modes = newmodes; + +SECOND_PASS: + + currentMode = modes + num; + num++; + + currentMode->mode = pMode; + currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; + currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; + if(pMode->Flags & V_DBLSCAN) + currentMode->flags |= DGA_DOUBLESCAN; + if(pMode->Flags & V_INTERLACE) + currentMode->flags |= DGA_INTERLACED; + currentMode->byteOrder = pScrn->imageByteOrder; + currentMode->depth = pScrn->depth; + currentMode->bitsPerPixel = pScrn->bitsPerPixel; + currentMode->red_mask = pScrn->mask.red; + currentMode->green_mask = pScrn->mask.green; + currentMode->blue_mask = pScrn->mask.blue; + currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; + currentMode->viewportWidth = pMode->HDisplay; + currentMode->viewportHeight = pMode->VDisplay; + currentMode->xViewportStep = 1; + currentMode->yViewportStep = 1; + currentMode->viewportFlags = DGA_FLIP_RETRACE; + currentMode->offset = 0; + currentMode->address = pI128->MemoryPtr; + + if(oneMore) { /* first one is narrow width */ + currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; + currentMode->imageWidth = pMode->HDisplay; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + oneMore = FALSE; + goto SECOND_PASS; + } else { + currentMode->bytesPerScanline = + ((pScrn->displayWidth * Bpp) + 3) & ~3L; + currentMode->imageWidth = pScrn->displayWidth; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + } + + pMode = pMode->next; + if(pMode == firstMode) + break; + } + + pI128->numDGAModes = num; + pI128->DGAModes = modes; + + return DGAInit(pScreen, &I128_DGAFuncs, modes, num); +} + + +static Bool +I128_SetMode( + ScrnInfoPtr pScrn, + DGAModePtr pMode +){ + static int OldDisplayWidth[MAXSCREENS]; + int index = pScrn->pScreen->myNum; + + I128Ptr pI128 = I128PTR(pScrn); + + if(!pMode) { /* restore the original mode */ + /* put the ScreenParameters back */ + + pScrn->displayWidth = OldDisplayWidth[index]; + + I128SwitchMode(index, pScrn->currentMode, 0); + pI128->DGAactive = FALSE; + } else { + if(!pI128->DGAactive) { /* save the old parameters */ + OldDisplayWidth[index] = pScrn->displayWidth; + + pI128->DGAactive = TRUE; + } + + pScrn->displayWidth = pMode->bytesPerScanline / + (pMode->bitsPerPixel >> 3); + + I128SwitchMode(index, pMode->mode, 0); + } + + return TRUE; +} + + + +static int +I128_GetViewport( + ScrnInfoPtr pScrn +){ + I128Ptr pI128 = I128PTR(pScrn); + + return pI128->DGAViewportStatus; +} + +static void +I128_SetViewport( + ScrnInfoPtr pScrn, + int x, int y, + int flags +){ + I128Ptr pI128 = I128PTR(pScrn); + + I128AdjustFrame(pScrn->pScreen->myNum, x, y, flags); + pI128->DGAViewportStatus = 0; /* I128AdjustFrame loops until finished */ +} + +static void +I128_FillRect ( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned long color +){ + I128Ptr pI128 = I128PTR(pScrn); + + if(pI128->XaaInfoRec) { + (*pI128->XaaInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); + (*pI128->XaaInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); + SET_SYNC_FLAG(pI128->XaaInfoRec); + } +} + +static void +I128_BlitRect( + ScrnInfoPtr pScrn, + int srcx, int srcy, + int w, int h, + int dstx, int dsty +){ + I128Ptr pI128 = I128PTR(pScrn); + + if(pI128->XaaInfoRec) { + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + + (*pI128->XaaInfoRec->SetupForScreenToScreenCopy)( + pScrn, xdir, ydir, GXcopy, ~0, -1); + (*pI128->XaaInfoRec->SubsequentScreenToScreenCopy)( + pScrn, srcx, srcy, dstx, dsty, w, h); + SET_SYNC_FLAG(pI128->XaaInfoRec); + } +} + +#if 0 +static void +I128_BlitTransRect( + ScrnInfoPtr pScrn, + int srcx, int srcy, + int w, int h, + int dstx, int dsty, + unsigned long color +){ + I128Ptr pI128 = I128PTR(pScrn); + + if(pI128->XaaInfoRec) { + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + + (*pI128->XaaInfoRec->SetupForScreenToScreenCopy)( + pScrn, xdir, ydir, GXcopy, ~0, color); + (*pI128->XaaInfoRec->SubsequentScreenToScreenCopy)( + pScrn, srcx, srcy, dstx, dsty, w, h); + SET_SYNC_FLAG(pI128->XaaInfoRec); + } +} +#endif + +static Bool +I128_OpenFramebuffer( + ScrnInfoPtr pScrn, + char **name, + unsigned char **mem, + int *size, + int *offset, + int *flags +){ + I128Ptr pI128 = I128PTR(pScrn); + unsigned long FbAddress = pI128->PciInfo->memBase[0] & 0xFFC00000; + + *name = NULL; /* no special device */ + *mem = (unsigned char*)FbAddress; + *size = pI128->MemorySize*1024; + *offset = 0; + *flags = DGA_NEED_ROOT; + + return TRUE; +} diff --git a/driver/xf86-video-i128/src/i128exa.c b/driver/xf86-video-i128/src/i128exa.c new file mode 100644 index 000000000..a2d6c7eef --- /dev/null +++ b/driver/xf86-video-i128/src/i128exa.c @@ -0,0 +1,683 @@ +/* + * Copyright 1997-2000 by Robin Cutshaw <robin@XFree86.Org> + * Copyright 2005 Adam Jackson <ajax@nwnk.net> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of the authors not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* Solid and Copy support derived from the i128 XAA code */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "exa.h" +#include "miline.h" +#include "servermd.h" +#include "picture.h" + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" + +#include "i128.h" +#include "i128reg.h" + +#define PI128_FROM_PIXMAP(x) \ + I128Ptr pI128 = I128PTR(xf86Screens[x->drawable.pScreen->myNum]) +#define PI128_FROM_SCREEN(x) \ + I128Ptr pI128 = I128PTR(xf86Screens[x->myNum]) +#define PI128_FROM_PICTURE(x) \ + I128Ptr pI128 = I128PTR(xf86Screens[x->pDrawable->pScreen->myNum]) + +/* we might be able to do something smarter than this */ +#define ENG_PIPELINE_READY() \ + while (pI128->mem.rbase_a[BUSY] & BUSY_BUSY) +#define ENG_DONE() \ + while (pI128->mem.rbase_a[FLOW] & (FLOW_DEB | FLOW_MCB | FLOW_PRV)) + +#if 1 +#define I128_EXA_DEBUG(x) +#else +#define I128_EXA_DEBUG(x) ErrorF x +#endif + +/* technically we should set the caches to bogus things during init... */ +#define CACHE_DEBUG 0 + +#define CACHED_UPDATE(val, reg) \ + do if (pI128->val != val) { \ + if (CACHE_DEBUG) I128_EXA_DEBUG(("Updated cache for " #reg "\n")); \ + pI128->mem.rbase_a[reg] = pI128->val = val; \ + } while (0) + +static void +i128SetBufCtrl(I128Ptr pI128, int dest_bpp) +{ + unsigned int buf_ctrl; + + switch (dest_bpp) { + case 8: buf_ctrl = BC_PSIZ_8B; break; + case 16: buf_ctrl = BC_PSIZ_16B; break; + case 24: + case 32: buf_ctrl = BC_PSIZ_32B; break; + default: buf_ctrl = 0; break; /* error */ + } + if (pI128->Chipset == PCI_CHIP_I128_T2R) { + if (pI128->MemoryType == I128_MEMORY_SGRAM) + buf_ctrl |= BC_MDM_PLN; + else + buf_ctrl |= BC_BLK_ENA; + } + + CACHED_UPDATE(buf_ctrl, BUF_CTRL); +} + +static const CARD32 i128alu[16] = +{ + CR_CLEAR << 8, + CR_AND << 8, + CR_AND_REV << 8, + CR_COPY << 8, + CR_AND_INV << 8, + CR_NOOP << 8, + CR_XOR << 8, + CR_OR << 8, + CR_NOR << 8, + CR_EQUIV << 8, + CR_INVERT << 8, + CR_OR_REV << 8, + CR_COPY_INV << 8, + CR_OR_INV << 8, + CR_NAND << 8, + CR_SET << 8 +}; + +/* 8bpp 16bpp 32bpp unused */ +static const int min_size[] = { 0x62, 0x32, 0x1A, 0x00 }; +static const int max_size[] = { 0x80, 0x40, 0x20, 0x00 }; +static const int split_size[] = { 0x20, 0x10, 0x08, 0x00 }; + +/* + * this is the workhorse for our solid and copy routines. this works because + * when CS_SOLID is set, the color comes from the FORE register regardless of + * the source pixmap coords. + */ + +static void +i128ExaBlit(PixmapPtr dst, int x1, int y1, int x2, int y2, int w, int h) +{ + int wh; + PI128_FROM_PIXMAP(dst); + + I128_EXA_DEBUG(("Blit: %d %d %d %d %d %d\n", x1, y1, x2, y2, w, h)); + ENG_PIPELINE_READY(); + + /* + * this deserves explanation. XY3_DIR == 0 means left to right, top to + * bottom. setting bit zero (DIR_LR_BT) switches to bottom to top, and + * setting bit one (DIR_RL_TB) switches to right to left. XXX rewrite me. + */ + if (pI128->blitdir & DIR_RL_TB) { /* right-to-left */ + x1 += w; x1--; + x2 += w; x2--; + } + if (pI128->blitdir & DIR_LR_BT) { /* bottom-to-top */ + y1 += h; y1--; + y2 += h; y2--; + } + + if (pI128->Chipset == PCI_CHIP_I128) { + int bppi; + + /* The I128-1 has a nasty bitblit bug + * that occurs when dest is exactly 8 pages wide + */ + + bppi = (pI128->mem.rbase_a[BUF_CTRL] & BC_PSIZ_MSK) >> 24; + + if ((w >= min_size[bppi]) && (w <= max_size[bppi])) { + bppi = split_size[bppi]; +#if 1 + /* split method */ + + wh = (bppi << 16) | h; + CACHED_UPDATE(wh, XY2_WH); + pI128->mem.rbase_a[XY0_SRC] = (x1 << 16) | y1; MB; + pI128->mem.rbase_a[XY1_DST] = (x2 << 16) | y2; MB; + + ENG_PIPELINE_READY(); + + w -= bppi; + + if (pI128->blitdir & DIR_RL_TB) { + /* right to left blit */ + x1 -= bppi; + x2 -= bppi; + } else { + /* left to right blit */ + x1 += bppi; + x2 += bppi; + } +#else + /* clip method */ + pI128->mem.rbase_a[CLPTL] = (x2 << 16) | y2; + pI128->mem.rbase_a[CLPBR] = ((x2 + w) << 16) | (y2 + h); + w += bppi; +#endif + } + } + + /* this is overkill, but you can never have too much overkill */ + wh = (w << 16) | h; + CACHED_UPDATE(wh, XY2_WH); + + pI128->mem.rbase_a[XY0_SRC] = (x1 << 16) | y1; MB; + pI128->mem.rbase_a[XY1_DST] = (x2 << 16) | y2; MB; +} + +static void +i128WaitMarker(ScreenPtr pScreen, int Marker) +{ + PI128_FROM_SCREEN(pScreen); + ENG_DONE(); +} + +static void +i128SetPlanemask(I128Ptr pI128, Pixel p) +{ + Pixel planemask; + I128_EXA_DEBUG(("SetPlanemask: %d\n", (int)p)); + if (p == -1) + planemask = -1; + else switch (pI128->bitsPerPixel) { + case 8: + planemask = p * 0x01010101; break; + case 16: + planemask = p * 0x00010001; break; + default: + planemask = p; break; + } + + CACHED_UPDATE(planemask, MASK); +} + +/* this should be superfluous... */ +static void +i128SetClip(I128Ptr pI128) +{ +#if 0 + pI128->clptl = pI128->mem.rbase_a[CLPTL] = 0x00000000; + pI128->clpbr = pI128->mem.rbase_a[CLPBR] = (4095 << 16) | 2047; +#endif +} + +static void +i128SetBlitDirection(I128Ptr pI128, int dx, int dy) +{ + int blitdir; + + I128_EXA_DEBUG(("SetBlitDirection: %d %d\n", dx, dy)); + + if (dx < 0) { + if (dy < 0) blitdir = DIR_RL_BT; + else blitdir = DIR_RL_TB; + } else { + if (dy < 0) blitdir = DIR_LR_BT; + else blitdir = DIR_LR_TB; + } + + CACHED_UPDATE(blitdir, XY3_DIR); +} + +static void +i128SetRop(I128Ptr pI128, int alu, int solid) +{ + int cmd; + + I128_EXA_DEBUG(("SetRop: %d %d\n", alu, solid)); + + cmd = i128alu[alu] | CO_BITBLT | (solid ? (CS_SOLID << 16) : 0); + + CACHED_UPDATE(cmd, CMD); +} + +static void +i128SetSourcePixmap(I128Ptr pI128, PixmapPtr src) +{ + unsigned int sorg = exaGetPixmapOffset(src); + unsigned int sptch = exaGetPixmapPitch(src); + + I128_EXA_DEBUG(("SetSourcePixmap: %x, %d\n", sorg, sptch)); + + CACHED_UPDATE(sorg, DE_SORG); + CACHED_UPDATE(sptch, DE_SPTCH); +} + +static void +i128SetDestPixmap(I128Ptr pI128, PixmapPtr dst) +{ + unsigned int dorg = exaGetPixmapOffset(dst); + unsigned int dptch = exaGetPixmapPitch(dst); + + I128_EXA_DEBUG(("SetDestPixmap: %x, %d\n", dorg, dptch)); + + CACHED_UPDATE(dorg, DE_DORG); + CACHED_UPDATE(dptch, DE_DPTCH); +} + +static void +i128SetTexture(I128Ptr pI128, PixmapPtr tex) +{ + unsigned int torg = exaGetPixmapOffset(tex); + unsigned int tptch = exaGetPixmapPitch(tex); + + I128_EXA_DEBUG(("SetTexture: %x, %d\n", torg, tptch)); + + CACHED_UPDATE(torg, LOD0_ORG); + CACHED_UPDATE(tptch, DE_TPTCH); +} + +static const int func_tab[13][2] = { + /* source function, destination function */ + { ABLEND_SRC_ZERO, ABLEND_DST_ZERO }, /* clear */ + { ABLEND_SRC_ONE, ABLEND_DST_ZERO }, /* src */ + { ABLEND_SRC_ZERO, ABLEND_DST_ONE }, /* dst */ + { ABLEND_SRC_ONE, ABLEND_DST_OMSRC_ALPHA }, /* over */ + { ABLEND_SRC_OMDST_ALPHA, ABLEND_DST_ONE }, /* overreverse */ + { ABLEND_SRC_DST_ALPHA, ABLEND_DST_ZERO }, /* in */ + { ABLEND_SRC_ZERO, ABLEND_DST_SRC_ALPHA }, /* inreverse */ + { ABLEND_SRC_OMDST_ALPHA, ABLEND_DST_ZERO }, /* out */ + { ABLEND_SRC_ZERO, ABLEND_DST_OMSRC_ALPHA }, /* outreverse */ + { ABLEND_SRC_DST_ALPHA, ABLEND_DST_OMSRC_ALPHA }, /* atop */ + { ABLEND_SRC_OMDST_ALPHA, ABLEND_DST_SRC_ALPHA }, /* atopreverse */ + { ABLEND_SRC_OMDST_ALPHA, ABLEND_DST_OMSRC_ALPHA }, /* xor */ + { ABLEND_SRC_ONE, ABLEND_DST_ONE } /* add */ +}; + +static void +i128SetAlphaForOp(I128Ptr pI128, int op, int enable) +{ + int acntrl = 0; + + if (enable) { + acntrl |= ACTL_BE; /* blend enable */ + acntrl |= func_tab[op][0]; /* source factor */ + acntrl |= func_tab[op][1]; /* dest_factor */ + acntrl |= 0; /* ACTL_AMD; / * modulate alpha */ + } else { + acntrl = 0; + } + + I128_EXA_DEBUG(("SetAlphaForOp: %d, %d\n", op, enable)); + + CACHED_UPDATE(acntrl, ACNTRL); +} + +/* we don't need a finalizer, yet */ +static void +i128Done(PixmapPtr p) { + I128_EXA_DEBUG(("Done\n\n")); + return; +} + +/* Solid */ + +static Bool +i128PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) +{ + PI128_FROM_PIXMAP(pPixmap); + + ENG_PIPELINE_READY(); + + i128SetPlanemask(pI128, planemask); + + if (alu != GXclear && alu != GXset) + pI128->mem.rbase_a[FORE] = fg; + + i128SetClip(pI128); + i128SetBlitDirection(pI128, 1, 1); /* probably unnecessary/ignored */ + + i128SetAlphaForOp(pI128, 0, 0); + i128SetRop(pI128, alu, 1); + + /* no need to set the source, the chip ignores it */ + i128SetDestPixmap(pI128, pPixmap); + + return TRUE; +} + +static void +i128Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) +{ + i128ExaBlit(pPixmap, 0, 0, x1, y1, x2 - x1, y2 - y1); +} + +/* Copy */ + +static Bool +i128PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int dx, int dy, + int alu, Pixel planemask) +{ + PI128_FROM_PIXMAP(pSrcPixmap); + + ENG_PIPELINE_READY(); + + i128SetPlanemask(pI128, planemask); + i128SetClip(pI128); + i128SetBlitDirection(pI128, dx, dy); + + i128SetAlphaForOp(pI128, 0, 0); + i128SetRop(pI128, alu, 0); + + i128SetSourcePixmap(pI128, pSrcPixmap); + i128SetDestPixmap(pI128, pDstPixmap); + + return TRUE; +} + +static void +i128Copy(PixmapPtr pDstPixmap, int x1, int y1, int x2, int y2, int w, int h) +{ + i128ExaBlit(pDstPixmap, x1, y1, x2, y2, w, h); +} + +/* Composite */ + +static const struct source_format source_formats[] = { + /* 32bpp */ + { PICT_a8r8g8b8, 0x14, 0, 0 }, + { PICT_x8r8g8b8, 0x14, 0, 1 }, +#if 0 + { PICT_a8b8g8r8, 0x14, 0, 0 }, + { PICT_x8b8g8r8, 0x14, 0, 1 }, + /* no direct 24bpp formats */ + /* 16bpp */ + { PICT_r5g6b5, 0x12, 0, 0 }, + { PICT_b5g6r5, 0x12, 0, 0 }, + { PICT_a1r5g5b5, 0x11, 0, 0 }, + { PICT_x1r5g5b5, 0x11, 0, 1 }, + { PICT_a1b5g5r5, 0x11, 0, 0 }, + { PICT_x1b5g5r5, 0x11, 0, 1 }, + { PICT_a4r4g4b4, 0x10, 0, 0 }, + { PICT_x4r4g4b4, 0x10, 0, 1 }, + { PICT_a4b4g4r4, 0x10, 0, 0 }, + { PICT_x4b4g4r4, 0x10, 0, 1 }, + /* 8bpp */ + { PICT_a8, 0x21, 0, 0 }, + { PICT_r3g3b2, 0x0D, 0, 0 }, + { PICT_b2g3r3, 0x0D, 0, 0 }, + { PICT_a2r2g2b2, 0x30, 0, 0 }, + { PICT_a2b2g2r2, 0x30, 0, 0 }, + /* 4bpp */ + { PICT_a4, 0x20, 0, 0 }, +#endif + /* terminator */ + { 0, 0, 0, 0 } +}; + +static struct source_format * +i128MapSourceFormat(int fmt) +{ + struct source_format *f; + for (f = (struct source_format *)source_formats; f->render_format; f++) + if (f->render_format == fmt) + return f; + return NULL; +} + +struct dest_format { + int render_format; + int i128_format; +}; + +static const struct dest_format dest_formats[] = { + { 0, 0 } +}; + +static struct dest_format * +i128MapDestFormat(int fmt) +{ + return NULL; +} + +/* Composite is probably t2r and t2r4 only */ +static Bool +i128CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, + PicturePtr pDstPicture) +{ + PI128_FROM_PICTURE(pDstPicture); + + if (op >= PictOpSaturate) return FALSE; + + /* + * no direct alpha mask support. we only have one TMU, so while we + * can emulate it, we should emulate it in the generic EXA layer. + */ + if (pMaskPicture) return FALSE; + + /* when transforms added, be sure to check for linear/nearest */ + /* if (pSrcPicture->transform) return FALSE; */ + + /* no support for external alpha */ + if (pSrcPicture->alphaMap || pDstPicture->alphaMap) return FALSE; + + pI128->source = i128MapSourceFormat(pSrcPicture->format); + if (!pI128->source) + return FALSE; +#if 0 + if (!i128MapDestFormat(pDstPicture->format)) return FALSE; +#endif + + return TRUE; +} + +static Bool +i128PrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, + PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, + PixmapPtr pDst) +{ + unsigned int cmd; + unsigned int tex_ctl = 0; + unsigned int threedctl = 0; + PI128_FROM_PIXMAP(pDst); + + /* 2D setup */ + i128SetBufCtrl(pI128, pDst->drawable.bitsPerPixel); + i128SetPlanemask(pI128, -1); + i128SetSourcePixmap(pI128, pSrc); + i128SetDestPixmap(pI128, pDst); + + /* TEX_INV command here? */ + + cmd = CO_TRIAN3D; + CACHED_UPDATE(cmd, CMD); + + /* 3D setup */ + i128SetTexture(pI128, pSrc); + + i128SetAlphaForOp(pI128, op, 1); + + /* it looks pointless to cache these, but we'll need it for DRI */ + + tex_ctl |= TEX_TM; /* enable texture mapping */ + tex_ctl |= TEX_NMG | TEX_NMN; /* nearest interpolation */ + tex_ctl |= 0; /* TEX_RM; / * modulate RGB */ + CACHED_UPDATE(tex_ctl, TEX_CTL); + + threedctl |= 0; /* COMP_TRUE << TCTL_ZOP_SHIFT; / * always pass Z check */ + threedctl |= TCTL_ABS; /* enable alpha blend */ + threedctl |= TCTL_TBS; /* enable texture blend */ + threedctl |= TCTL_RT; /* draw textured rectangle */ + CACHED_UPDATE(threedctl, THREEDCTL); + + return TRUE; +} + +static void +i128Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + PI128_FROM_PIXMAP(pDst); + + /* + * vertex setup. vertex layout must be: + * V0 V1 + * V2 (V3 is implicit) + */ + + pI128->mem.rbase_af[V0_X] = 0.0; + pI128->mem.rbase_af[V0_Y] = 0.0; + pI128->mem.rbase_af[V0_W] = 1.0; + pI128->mem.rbase_af[V0_U] = 0.0; + pI128->mem.rbase_af[V0_V] = 0.0; + pI128->mem.rbase_af[V1_X] = 300.0; + pI128->mem.rbase_af[V1_Y] = 0.0; + pI128->mem.rbase_af[V1_W] = 1.0; + pI128->mem.rbase_af[V1_U] = 1.0; + pI128->mem.rbase_af[V1_V] = 0.0; + pI128->mem.rbase_af[V2_X] = 0.0; + pI128->mem.rbase_af[V2_Y] = 300.0; + pI128->mem.rbase_af[V2_W] = 1.0; + pI128->mem.rbase_af[V2_U] = 0.0; + pI128->mem.rbase_af[V2_V] = 1.0; + + /* and fire */ + pI128->mem.rbase_a[TRIGGER3D] = 1; MB; + +#if 0 + static int i = 0; + /* test for raster */ + if (!(i = (i + 1) % 32)) { + ErrorF("Composite test: %d %d %d %d %d %d\n", srcX, srcY, dstX, dstY, + width, height); + } + i128SetRop(pI128, GXxor, 0); + i128ExaBlit(pDst, srcX, srcY, dstX, dstY, width, height); +#endif +} + +#if 0 +/* + * upload and download will require a DRM. AGP DMA only works on T2R4, and + * then only for upload. we could probably use memory windows on other chips, + * but those have goofy alignment restrictions and need to be disabled when + * not in use. + */ +static Bool +i128DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, + int dst_pitch) +{ +} + +static Bool +i128UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, + int src_pitch) +{ +} +#endif + +Bool +I128ExaInit(ScreenPtr pScreen) +{ + ExaDriverPtr pExa; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I128Ptr pI128 = I128PTR(pScrn); + + if (!(pExa = exaDriverAlloc())) { + pI128->NoAccel = TRUE; + return FALSE; + } + pI128->ExaDriver = pExa; + + pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_OFFSCREEN_ALIGN_POT; + pExa->memoryBase = pI128->MemoryPtr; + pExa->memorySize = pI128->MemorySize * 1024; + pExa->offScreenBase = (pScrn->virtualX * pScrn->virtualY) * + (pScrn->bitsPerPixel / 8) + 4096; + /* these two are probably right */ + pExa->pixmapOffsetAlign = 16; + pExa->pixmapPitchAlign = 16; + /* these two are guesses */ + pExa->maxX = 2048; + pExa->maxY = 2048; + + pExa->WaitMarker = i128WaitMarker; + + pExa->PrepareSolid = i128PrepareSolid; + pExa->Solid = i128Solid; + pExa->DoneSolid = i128Done; + + pExa->PrepareCopy = i128PrepareCopy; + pExa->Copy = i128Copy; + pExa->DoneCopy = i128Done; + + if (0 && (pI128->Chipset == PCI_CHIP_I128_T2R || + pI128->Chipset == PCI_CHIP_I128_T2R4)) + { +#if 0 + pExa->DownloadFromScreen = i128DownloadFromScreen; + pExa->UploadToScreen = i128UploadToScreen; +#endif + pExa->CheckComposite = i128CheckComposite; + pExa->PrepareComposite = i128PrepareComposite; + pExa->Composite = i128Composite; + pExa->DoneComposite = i128Done; + } + + /* + * XXX much of this is duplicated from the XAA code, but I expect the XAA + * support to disappear eventually. + */ + pI128->buf_ctrl = 0; /* force write */ + i128SetBufCtrl(pI128, pI128->bitsPerPixel); + + /* all of this needs to be properly documented */ + { + pI128->mem.rbase_a[DE_PGE] = 0x00; + pI128->mem.rbase_a[DE_SORG] = pI128->displayOffset; + pI128->mem.rbase_a[DE_DORG] = pI128->displayOffset; + pI128->mem.rbase_a[DE_MSRC] = 0x00; + pI128->mem.rbase_a[DE_WKEY] = 0x00; + pI128->mem.rbase_a[DE_SPTCH] = pI128->mem.rbase_g[DB_PTCH]; + pI128->mem.rbase_a[DE_DPTCH] = pI128->mem.rbase_g[DB_PTCH]; + if (pI128->Chipset == PCI_CHIP_I128_T2R4) + pI128->mem.rbase_a[DE_ZPTCH] = pI128->mem.rbase_g[DB_PTCH]; + pI128->mem.rbase_a[RMSK] = 0x00000000; + pI128->mem.rbase_a[XY4_ZM] = ZOOM_NONE; + pI128->mem.rbase_a[LPAT] = 0xffffffff; /* for lines */ + pI128->mem.rbase_a[PCTRL] = 0x00000000; /* for lines */ + pI128->mem.rbase_a[CLPTL] = 0x00000000; + pI128->mem.rbase_a[CLPBR] = (4095 << 16) | 2047 ; + pI128->mem.rbase_a[ACNTRL] = 0x00000000; + pI128->mem.rbase_a[INTM] = 0x03; + } + + /* need this as a float * for vertex setup */ + pI128->mem.rbase_af = (float *)pI128->mem.rbase_a; + + if (pI128->Debug) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I128ExaInit done\n"); + I128DumpActiveRegisters(pScrn); + } + + return(exaDriverInit(pScreen, pExa)); +} diff --git a/driver/xf86-video-i128/src/i128init.c b/driver/xf86-video-i128/src/i128init.c new file mode 100644 index 000000000..00ec646bb --- /dev/null +++ b/driver/xf86-video-i128/src/i128init.c @@ -0,0 +1,580 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128init.c,v 1.5 2000/11/03 00:50:53 robin Exp $ */ +/* + * Copyright 1995-2000 by Robin Cutshaw <robin@XFree86.Org> + * Copyright 1998 by Number Nine Visual Technology, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Robin Cutshaw not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Robin Cutshaw and Number Nine make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * ROBIN CUTSHAW AND NUMBER NINE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL ROBIN CUTSHAW OR NUMBER NINE 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 + +/* $XConsortium: $ */ + + +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "i128.h" +#include "i128reg.h" +#include "Ti302X.h" +#include "IBMRGB.h" + +static void I128SavePalette(I128Ptr pI128); +static void I128RestorePalette(I128Ptr pI128); + + +void +I128SaveState(ScrnInfoPtr pScrn) +{ + I128Ptr pI128 = I128PTR(pScrn); + I128RegPtr iR = &pI128->RegRec; + + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128SaveState start\n"); + + if (pI128->Debug) { + unsigned long tmp1 = inl(iR->iobase + 0x1C); + unsigned long tmp2 = inl(iR->iobase + 0x20); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128SaveState saving, config1/2 = 0x%lx/0x%lx\n", tmp1, tmp2); + I128DumpActiveRegisters(pScrn); + } + + /* iobase is filled in during the device probe (as well as config 1&2)*/ + + if ((pI128->io.id&0x7) > 0) { + iR->vga_ctl = inl(iR->iobase + 0x30); + } + + iR->i128_base_g[INT_VCNT] = pI128->mem.rbase_g[INT_VCNT]; /* 0x0020 */ + iR->i128_base_g[INT_HCNT] = pI128->mem.rbase_g[INT_HCNT]; /* 0x0024 */ + iR->i128_base_g[DB_ADR] = pI128->mem.rbase_g[DB_ADR]; /* 0x0028 */ + iR->i128_base_g[DB_PTCH] = pI128->mem.rbase_g[DB_PTCH]; /* 0x002C */ + iR->i128_base_g[CRT_HAC] = pI128->mem.rbase_g[CRT_HAC]; /* 0x0030 */ + iR->i128_base_g[CRT_HBL] = pI128->mem.rbase_g[CRT_HBL]; /* 0x0034 */ + iR->i128_base_g[CRT_HFP] = pI128->mem.rbase_g[CRT_HFP]; /* 0x0038 */ + iR->i128_base_g[CRT_HS] = pI128->mem.rbase_g[CRT_HS]; /* 0x003C */ + iR->i128_base_g[CRT_VAC] = pI128->mem.rbase_g[CRT_VAC]; /* 0x0040 */ + iR->i128_base_g[CRT_VBL] = pI128->mem.rbase_g[CRT_VBL]; /* 0x0044 */ + iR->i128_base_g[CRT_VFP] = pI128->mem.rbase_g[CRT_VFP]; /* 0x0048 */ + iR->i128_base_g[CRT_VS] = pI128->mem.rbase_g[CRT_VS]; /* 0x004C */ + iR->i128_base_g[CRT_LCNT] = pI128->mem.rbase_g[CRT_LCNT]; /* 0x0050 */ + iR->i128_base_g[CRT_ZOOM] = pI128->mem.rbase_g[CRT_ZOOM]; /* 0x0054 */ + iR->i128_base_g[CRT_1CON] = pI128->mem.rbase_g[CRT_1CON]; /* 0x0058 */ + iR->i128_base_g[CRT_2CON] = pI128->mem.rbase_g[CRT_2CON]; /* 0x005C */ + + iR->i128_base_w[MW0_CTRL] = pI128->mem.rbase_w[MW0_CTRL]; /* 0x0000 */ + iR->i128_base_w[MW0_SZ] = pI128->mem.rbase_w[MW0_SZ]; /* 0x0008 */ + iR->i128_base_w[MW0_PGE] = pI128->mem.rbase_w[MW0_PGE]; /* 0x000C */ + iR->i128_base_w[MW0_ORG] = pI128->mem.rbase_w[MW0_ORG]; /* 0x0010 */ + iR->i128_base_w[MW0_MSRC] = pI128->mem.rbase_w[MW0_MSRC]; /* 0x0018 */ + iR->i128_base_w[MW0_WKEY] = pI128->mem.rbase_w[MW0_WKEY]; /* 0x001C */ + iR->i128_base_w[MW0_KDAT] = pI128->mem.rbase_w[MW0_KDAT]; /* 0x0020 */ + iR->i128_base_w[MW0_MASK] = pI128->mem.rbase_w[MW0_MASK]; /* 0x0024 */ + + if (pI128->RamdacType == TI3025_DAC) { + pI128->mem.rbase_g[INDEX_TI] = TI_CURS_CONTROL; MB; + iR->Ti302X[TI_CURS_CONTROL] = pI128->mem.rbase_g[DATA_TI]; + pI128->mem.rbase_g[INDEX_TI] = TI_TRUE_COLOR_CONTROL; MB; + iR->Ti302X[TI_TRUE_COLOR_CONTROL] = pI128->mem.rbase_g[DATA_TI]; + pI128->mem.rbase_g[INDEX_TI] = TI_VGA_SWITCH_CONTROL; MB; + iR->Ti302X[TI_VGA_SWITCH_CONTROL] = pI128->mem.rbase_g[DATA_TI]; + pI128->mem.rbase_g[INDEX_TI] = TI_MUX_CONTROL_1; MB; + iR->Ti302X[TI_MUX_CONTROL_1] = pI128->mem.rbase_g[DATA_TI]; + pI128->mem.rbase_g[INDEX_TI] = TI_MUX_CONTROL_2; MB; + iR->Ti302X[TI_MUX_CONTROL_2] = pI128->mem.rbase_g[DATA_TI]; + pI128->mem.rbase_g[INDEX_TI] = TI_INPUT_CLOCK_SELECT; MB; + iR->Ti302X[TI_INPUT_CLOCK_SELECT] = pI128->mem.rbase_g[DATA_TI]; + pI128->mem.rbase_g[INDEX_TI] = TI_OUTPUT_CLOCK_SELECT; MB; + iR->Ti302X[TI_OUTPUT_CLOCK_SELECT] = pI128->mem.rbase_g[DATA_TI]; + pI128->mem.rbase_g[INDEX_TI] = TI_PALETTE_PAGE; MB; + iR->Ti302X[TI_PALETTE_PAGE] = pI128->mem.rbase_g[DATA_TI]; + pI128->mem.rbase_g[INDEX_TI] = TI_GENERAL_CONTROL; MB; + iR->Ti302X[TI_GENERAL_CONTROL] = pI128->mem.rbase_g[DATA_TI]; + pI128->mem.rbase_g[INDEX_TI] = TI_MISC_CONTROL; MB; + iR->Ti302X[TI_MISC_CONTROL] = pI128->mem.rbase_g[DATA_TI]; + pI128->mem.rbase_g[INDEX_TI] = TI_AUXILIARY_CONTROL; MB; + iR->Ti302X[TI_AUXILIARY_CONTROL] = pI128->mem.rbase_g[DATA_TI]; + pI128->mem.rbase_g[INDEX_TI] = TI_GENERAL_IO_CONTROL; MB; + iR->Ti302X[TI_GENERAL_IO_CONTROL] = pI128->mem.rbase_g[DATA_TI]; + pI128->mem.rbase_g[INDEX_TI] = TI_GENERAL_IO_DATA; MB; + iR->Ti302X[TI_GENERAL_IO_DATA] = pI128->mem.rbase_g[DATA_TI]; + pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_DCLK_CONTROL; MB; + iR->Ti302X[TI_MCLK_DCLK_CONTROL] = pI128->mem.rbase_g[DATA_TI]; + pI128->mem.rbase_g[INDEX_TI] = TI_COLOR_KEY_CONTROL; MB; + iR->Ti302X[TI_COLOR_KEY_CONTROL] = pI128->mem.rbase_g[DATA_TI]; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x00; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_PIXEL_CLOCK_PLL_DATA; MB; + iR->Ti3025[0] = pI128->mem.rbase_g[DATA_TI]; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x01; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_PIXEL_CLOCK_PLL_DATA; MB; + iR->Ti3025[1] = pI128->mem.rbase_g[DATA_TI]; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x02; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_PIXEL_CLOCK_PLL_DATA; MB; + iR->Ti3025[2] = pI128->mem.rbase_g[DATA_TI]; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x00; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA; MB; + iR->Ti3025[3] = pI128->mem.rbase_g[DATA_TI]; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x01; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA; MB; + iR->Ti3025[4] = pI128->mem.rbase_g[DATA_TI]; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x02; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA; MB; + iR->Ti3025[5] = pI128->mem.rbase_g[DATA_TI]; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x00; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_LOOP_CLOCK_PLL_DATA; MB; + iR->Ti3025[6] = pI128->mem.rbase_g[DATA_TI]; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x01; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_LOOP_CLOCK_PLL_DATA; MB; + iR->Ti3025[7] = pI128->mem.rbase_g[DATA_TI]; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x02; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_LOOP_CLOCK_PLL_DATA; MB; + iR->Ti3025[8] = pI128->mem.rbase_g[DATA_TI]; + } else if ((pI128->RamdacType == IBM526_DAC) || + (pI128->RamdacType == IBM528_DAC) || + (pI128->RamdacType == SILVER_HAMMER_DAC)) { + CARD32 i; + + for (i=0; i<0x94; i++) { + pI128->mem.rbase_g[IDXL_I] = i; MB; + iR->IBMRGB[i] = pI128->mem.rbase_g[DATA_I]; + } + } + + I128SavePalette(pI128); + + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128SaveState complete\n"); + +} + + +void +I128RestoreState(ScrnInfoPtr pScrn) +{ + I128Ptr pI128 = I128PTR(pScrn); + I128RegPtr iR = &pI128->RegRec; + + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128RestoreState start\n"); + + if (pI128->RamdacType == TI3025_DAC) { + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x00; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_PIXEL_CLOCK_PLL_DATA; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[0]; MB; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x01; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_PIXEL_CLOCK_PLL_DATA; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[1]; MB; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x02; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_PIXEL_CLOCK_PLL_DATA; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[2]; MB; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x00; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[3]; MB; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x01; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[4]; MB; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x02; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[5]; MB; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x00; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_LOOP_CLOCK_PLL_DATA; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[6]; MB; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x01; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_LOOP_CLOCK_PLL_DATA; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[7]; MB; + + pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = 0x02; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_LOOP_CLOCK_PLL_DATA; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[8]; MB; + + pI128->mem.rbase_g[INDEX_TI] = TI_CURS_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_CURS_CONTROL];MB; + pI128->mem.rbase_g[INDEX_TI] = TI_TRUE_COLOR_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_TRUE_COLOR_CONTROL]; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_VGA_SWITCH_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_VGA_SWITCH_CONTROL]; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_MUX_CONTROL_1; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_MUX_CONTROL_1];MB; + pI128->mem.rbase_g[INDEX_TI] = TI_MUX_CONTROL_2; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_MUX_CONTROL_2];MB; + pI128->mem.rbase_g[INDEX_TI] = TI_INPUT_CLOCK_SELECT; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_INPUT_CLOCK_SELECT]; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_OUTPUT_CLOCK_SELECT; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_OUTPUT_CLOCK_SELECT];MB; + pI128->mem.rbase_g[INDEX_TI] = TI_PALETTE_PAGE; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_PALETTE_PAGE];MB; + pI128->mem.rbase_g[INDEX_TI] = TI_GENERAL_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_GENERAL_CONTROL]; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_MISC_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_MISC_CONTROL];MB; + pI128->mem.rbase_g[INDEX_TI] = TI_AUXILIARY_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_AUXILIARY_CONTROL]; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_GENERAL_IO_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_GENERAL_IO_CONTROL]; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_GENERAL_IO_DATA; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_GENERAL_IO_DATA]; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_DCLK_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_MCLK_DCLK_CONTROL]; MB; + pI128->mem.rbase_g[INDEX_TI] = TI_COLOR_KEY_CONTROL; MB; + pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_COLOR_KEY_CONTROL]; MB; + } else if ((pI128->RamdacType == IBM526_DAC) || + (pI128->RamdacType == IBM528_DAC) || + (pI128->RamdacType == SILVER_HAMMER_DAC)) { + CARD32 i; + + if (pI128->Debug) { + unsigned long tmp1 = inl(iR->iobase + 0x1C); + unsigned long tmp2 = inl(iR->iobase + 0x20); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128RestoreState restoring, config1/2 = 0x%lx/0x%lx\n", tmp1, tmp2); + I128DumpActiveRegisters(pScrn); + } + + for (i=0; i<0x94; i++) { + if ((i == IBMRGB_sysclk_vco_div) || + (i == IBMRGB_sysclk_ref_div)) + continue; + pI128->mem.rbase_g[IDXL_I] = i; MB; + pI128->mem.rbase_g[DATA_I] = iR->IBMRGB[i]; MB; + } + + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div; MB; + pI128->mem.rbase_g[DATA_I] = + iR->IBMRGB[IBMRGB_sysclk_ref_div]; MB; + pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div; MB; + pI128->mem.rbase_g[DATA_I] = + iR->IBMRGB[IBMRGB_sysclk_vco_div]; MB; + usleep(50000); + } + + /* iobase is filled in during the device probe (as well as config 1&2)*/ + + if (((pI128->io.id&0x7) > 0) || + (pI128->Chipset == PCI_CHIP_I128_T2R) || + (pI128->Chipset == PCI_CHIP_I128_T2R4)) { + outl(iR->iobase + 0x30, iR->vga_ctl); + } + + I128RestorePalette(pI128); + + pI128->mem.rbase_w[MW0_CTRL] = iR->i128_base_w[MW0_CTRL]; /* 0x0000 */ + pI128->mem.rbase_w[MW0_SZ] = iR->i128_base_w[MW0_SZ]; /* 0x0008 */ + pI128->mem.rbase_w[MW0_PGE] = iR->i128_base_w[MW0_PGE]; /* 0x000C */ + pI128->mem.rbase_w[MW0_ORG] = iR->i128_base_w[MW0_ORG]; /* 0x0010 */ + pI128->mem.rbase_w[MW0_MSRC] = iR->i128_base_w[MW0_MSRC]; /* 0x0018 */ + pI128->mem.rbase_w[MW0_WKEY] = iR->i128_base_w[MW0_WKEY]; /* 0x001C */ + pI128->mem.rbase_w[MW0_KDAT] = iR->i128_base_w[MW0_KDAT]; /* 0x0020 */ + pI128->mem.rbase_w[MW0_MASK] = iR->i128_base_w[MW0_MASK]; /* 0x0024 */ + MB; + + pI128->mem.rbase_g[INT_VCNT] = iR->i128_base_g[INT_VCNT]; /* 0x0020 */ + pI128->mem.rbase_g[INT_HCNT] = iR->i128_base_g[INT_HCNT]; /* 0x0024 */ + pI128->mem.rbase_g[DB_ADR] = iR->i128_base_g[DB_ADR]; /* 0x0028 */ + pI128->mem.rbase_g[DB_PTCH] = iR->i128_base_g[DB_PTCH]; /* 0x002C */ + pI128->mem.rbase_g[CRT_HAC] = iR->i128_base_g[CRT_HAC]; /* 0x0030 */ + pI128->mem.rbase_g[CRT_HBL] = iR->i128_base_g[CRT_HBL]; /* 0x0034 */ + pI128->mem.rbase_g[CRT_HFP] = iR->i128_base_g[CRT_HFP]; /* 0x0038 */ + pI128->mem.rbase_g[CRT_HS] = iR->i128_base_g[CRT_HS]; /* 0x003C */ + pI128->mem.rbase_g[CRT_VAC] = iR->i128_base_g[CRT_VAC]; /* 0x0040 */ + pI128->mem.rbase_g[CRT_VBL] = iR->i128_base_g[CRT_VBL]; /* 0x0044 */ + pI128->mem.rbase_g[CRT_VFP] = iR->i128_base_g[CRT_VFP]; /* 0x0048 */ + pI128->mem.rbase_g[CRT_VS] = iR->i128_base_g[CRT_VS]; /* 0x004C */ + pI128->mem.rbase_g[CRT_LCNT] = iR->i128_base_g[CRT_LCNT]; /* 0x0050 */ + pI128->mem.rbase_g[CRT_ZOOM] = iR->i128_base_g[CRT_ZOOM]; /* 0x0054 */ + pI128->mem.rbase_g[CRT_1CON] = iR->i128_base_g[CRT_1CON]; /* 0x0058 */ + pI128->mem.rbase_g[CRT_2CON] = iR->i128_base_g[CRT_2CON]; /* 0x005C */ + MB; + + if (pI128->Debug) { + unsigned long tmp1 = inl(iR->iobase + 0x1C); + unsigned long tmp2 = inl(iR->iobase + 0x20); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128RestoreState resetting config1/2 from 0x%lx/0x%lx to 0x%lx/0x%lx\n", tmp1, tmp2, (unsigned long)iR->config1, (unsigned long)iR->config2); + I128DumpActiveRegisters(pScrn); + } + + if (pI128->MemoryType == I128_MEMORY_SGRAM) { + outl(iR->iobase + 0x24, iR->sgram & 0x7FFFFFFF); + outl(iR->iobase + 0x24, iR->sgram | 0x80000000); + } + + outl(iR->iobase + 0x20, iR->config2); + outl(iR->iobase + 0x1C, iR->config1); + + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128RestoreState complete\n"); +} + + +Bool +I128Init(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + I128Ptr pI128; + I128RegPtr iR; + int pitch_multiplier, iclock; + Bool ret; + CARD32 tmp; + int doubled = 1; + + if (mode->Flags & V_DBLSCAN) + doubled = 2; + + pI128 = I128PTR(pScrn); + iR = &pI128->RegRec; + pI128->HDisplay = mode->HDisplay; + + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128Init start\n"); + + /* config 1 and 2 were saved in Probe() + * we reset here again in case there was a VT switch + */ + + outl(iR->iobase + 0x1C, pI128->io.config1); + outl(iR->iobase + 0x20, pI128->io.config2); + + if (pI128->MemoryType == I128_MEMORY_SGRAM) { + outl(iR->iobase + 0x24, pI128->io.sgram & 0x7FFFFFFF); + outl(iR->iobase + 0x24, pI128->io.sgram | 0x80000000); + } + + + if (pI128->bitsPerPixel == 32) pitch_multiplier = 4; + else if (pI128->bitsPerPixel == 16) pitch_multiplier = 2; + else pitch_multiplier = 1; + + if (pI128->RamdacType == TI3025_DAC) + iclock = 4; + else if (pI128->RamdacType == IBM528_DAC) + iclock = 128 / pI128->bitsPerPixel; + else if (pI128->RamdacType == SILVER_HAMMER_DAC) + iclock = 64 / pI128->bitsPerPixel; + else if ((pI128->MemoryType == I128_MEMORY_DRAM) || + (pI128->MemoryType == I128_MEMORY_SGRAM)) + iclock = 32 / pI128->bitsPerPixel; /* IBM526 DAC 32b bus */ + else + iclock = 64 / pI128->bitsPerPixel; /* IBM524/526 DAC */ + + pI128->mem.rbase_g[INT_VCNT] = 0x00; + pI128->mem.rbase_g[INT_HCNT] = 0x00; + pI128->mem.rbase_g[DB_ADR] = pI128->displayOffset; + pI128->mem.rbase_g[DB_PTCH] = pI128->displayWidth * pitch_multiplier; + pI128->mem.rbase_g[CRT_HAC] = mode->HDisplay/iclock; + pI128->mem.rbase_g[CRT_HBL] = (mode->HTotal - mode->HDisplay)/iclock; + pI128->mem.rbase_g[CRT_HFP] = (mode->HSyncStart - mode->HDisplay)/iclock; + pI128->mem.rbase_g[CRT_HS] = (mode->HSyncEnd - mode->HSyncStart)/iclock; + pI128->mem.rbase_g[CRT_VAC] = mode->VDisplay * doubled; + pI128->mem.rbase_g[CRT_VBL] = (mode->VTotal - mode->VDisplay) * doubled; + pI128->mem.rbase_g[CRT_VFP] = (mode->VSyncStart - mode->VDisplay)* doubled; + pI128->mem.rbase_g[CRT_VS] = (mode->VSyncEnd - mode->VSyncStart) * doubled; + tmp = 0x00000070; + if (pI128->Chipset == PCI_CHIP_I128_T2R) + tmp |= 0x00000100; + if (pI128->Chipset == PCI_CHIP_I128_T2R4) { + if (pI128->FlatPanel) + tmp |= 0x00000100; /* Turn on digital flat panel */ + else + tmp &= 0xfffffeff; /* Turn off digital flat panel */ + } + if (pI128->DACSyncOnGreen || (mode->Flags & V_CSYNC)) + tmp |= 0x00000004; + pI128->mem.rbase_g[CRT_1CON] = tmp; + if ((pI128->MemoryType == I128_MEMORY_DRAM) || + (pI128->MemoryType == I128_MEMORY_SGRAM)) + tmp = 0x20000100; + else if (pI128->MemoryType == I128_MEMORY_WRAM) + tmp = 0x00040100; + else { + tmp = 0x00040101; + if (pI128->MemorySize == 2048) + tmp |= 0x00000002; + if ((pI128->displayWidth & (pI128->displayWidth-1)) || + ((pI128->displayWidth * pI128->bitsPerPixel) > 32768L)) + tmp |= 0x01000000; /* split transfer */ + } + pI128->mem.rbase_g[CRT_2CON] = tmp; + if (mode->Flags & V_DBLSCAN) + pI128->DoubleScan = TRUE; + else + pI128->DoubleScan = FALSE; + pI128->mem.rbase_g[CRT_ZOOM] = (pI128->DoubleScan ? 0x00000001 : 0x00000000); + + pI128->mem.rbase_w[MW0_CTRL] = 0x00000000; + switch (pI128->MemorySize) { + case 2048: + pI128->mem.rbase_w[MW0_SZ] = 0x00000009; + break; + case 8192: + pI128->mem.rbase_w[MW0_SZ] = 0x0000000B; + break; + case 8192+4096: + /* no break */ + case 16384: + pI128->mem.rbase_w[MW0_SZ] = 0x0000000C; + break; + case 16384+4096: + /* no break */ + case 16384+8192: + /* no break */ + case 16384+8192+4096: + /* no break */ + case 32768: + pI128->mem.rbase_w[MW0_SZ] = 0x0000000D; + break; + case 4096: + /* no break */ + default: + pI128->mem.rbase_w[MW0_SZ] = 0x0000000A;/* default 4MB */ + break; + } + pI128->mem.rbase_w[MW0_PGE] = 0x00000000; + pI128->mem.rbase_w[MW0_ORG] = 0x00000000; + pI128->mem.rbase_w[MW0_MSRC] = 0x00000000; + pI128->mem.rbase_w[MW0_WKEY] = 0x00000000; + pI128->mem.rbase_w[MW0_KDAT] = 0x00000000; + pI128->mem.rbase_w[MW0_MASK] = 0xFFFFFFFF; + MB; + + if ((pI128->io.id&0x7) > 0 || pI128->Chipset == PCI_CHIP_I128_T2R + || pI128->Chipset == PCI_CHIP_I128_T2R4) { + + pI128->io.vga_ctl &= 0x0000FF00; + pI128->io.vga_ctl |= 0x00000082; + if (pI128->FlatPanel && (mode->Flags & V_DBLSCAN)) + pI128->io.vga_ctl |= 0x00000020; /* Stretch horizontally */ + outl(iR->iobase + 0x30, pI128->io.vga_ctl); + + if (pI128->Chipset == PCI_CHIP_I128_T2R4) { + outl(iR->iobase + 0x24, 0x211BF030); + usleep(5000); + outl(iR->iobase + 0x24, 0xA11BF030); + } else if (pI128->MemoryType == I128_MEMORY_SGRAM) { + outl(iR->iobase + 0x24, 0x21089030); + usleep(5000); + outl(iR->iobase + 0x24, 0xA1089030); + } + } + + ret = pI128->ProgramDAC(pScrn, mode); + + pI128->InitCursorFlag = TRUE; + pI128->Initialized = 1; + + if (pI128->Debug) + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128Init complete\n"); + + return(ret); +} + + +static void +I128SavePalette(I128Ptr pI128) +{ + short i; + + pI128->mem.rbase_g[PEL_MASK] = 0xff; MB; + + if (!pI128->LUTSaved) { + pI128->mem.rbase_g[RD_ADR] = 0x00; MB; + for (i=0; i<256; i++) { + pI128->lutorig[i].r = pI128->mem.rbase_g[PAL_DAT]; MB; + pI128->lutorig[i].g = pI128->mem.rbase_g[PAL_DAT]; MB; + pI128->lutorig[i].b = pI128->mem.rbase_g[PAL_DAT]; MB; + } + pI128->LUTSaved = TRUE; + } + +} + + +static void +I128RestorePalette(I128Ptr pI128) +{ + int i; + /* restore the LUT */ + + pI128->mem.rbase_g[PEL_MASK] = 0xff; MB; + pI128->mem.rbase_g[WR_ADR] = 0x00; MB; + + for (i=0; i<256; i++) { + pI128->mem.rbase_g[PAL_DAT] = pI128->lutorig[i].r; MB; + pI128->mem.rbase_g[PAL_DAT] = pI128->lutorig[i].g; MB; + pI128->mem.rbase_g[PAL_DAT] = pI128->lutorig[i].b; MB; + } +} + + +void +I128LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, + VisualPtr pVisual) +{ + I128Ptr pI128; + + if (pVisual->nplanes != 8) + return; + + pI128 = I128PTR(pScrn); + + pI128->mem.rbase_g[PEL_MASK] = 0xff; MB; + + while (numColors--) { + pI128->mem.rbase_g[WR_ADR] = *indices; MB; + pI128->mem.rbase_g[PAL_DAT] = colors[*indices].red; MB; + pI128->mem.rbase_g[PAL_DAT] = colors[*indices].green; MB; + pI128->mem.rbase_g[PAL_DAT] = colors[*indices].blue; MB; + indices++; + } +} diff --git a/driver/xf86-video-i128/src/i128reg.h b/driver/xf86-video-i128/src/i128reg.h new file mode 100644 index 000000000..01e2f41e4 --- /dev/null +++ b/driver/xf86-video-i128/src/i128reg.h @@ -0,0 +1,730 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128reg.h,v 1.2 2000/10/23 14:11:39 robin Exp $ */ +/* + * Copyright 1994 by Robin Cutshaw <robin@XFree86.Org> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Robin Cutshaw not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Robin Cutshaw makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ROBIN CUTSHAW DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ROBIN CUTSHAW 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. + * + */ +/* $XConsortium: i128reg.h /main/4 1996/05/12 20:56:19 kaleb $ */ + +#ifndef I128REG_H +#define I128REG_H + +#include "xf86Pci.h" + +struct i128pci { + CARD32 devicevendor; + CARD32 statuscommand; + CARD32 classrev; + CARD32 bhlc; + CARD32 base0; + CARD32 base1; + CARD32 base2; + CARD32 base3; + CARD32 base4; + CARD32 base5; + CARD32 rsvd0; + CARD32 rsvd1; + CARD32 baserom; + CARD32 rsvd2; + CARD32 rsvd3; + CARD32 lgii; +}; + +struct i128io { + CARD32 rbase_g; + CARD32 rbase_w; + CARD32 rbase_a; + CARD32 rbase_b; + CARD32 rbase_i; + CARD32 rbase_e; + CARD32 id; + CARD32 config1; + CARD32 config2; + CARD32 sgram; + CARD32 soft_sw; + CARD32 vga_ctl; +}; + +struct i128mem { + unsigned char *mw0_ad; + unsigned char *mw1_ad; + unsigned char *xyw_ada; + unsigned char *xyw_adb; + CARD32 *rbase_g; + CARD32 *rbase_w; + CARD32 *rbase_a; + CARD32 *rbase_b; + CARD32 *rbase_i; + float *rbase_af; +}; + +/* save the registers needed for restoration in this structure */ +typedef struct { + IOADDRESS iobase; /* saved only for iobase indexing */ + CARD32 config1; /* iobase+0x1C register */ + CARD32 config2; /* iobase+0x20 register */ + CARD32 sgram; /* iobase+0x24 register */ + CARD32 vga_ctl; /* iobase+0x30 register */ + CARD32 i128_base_g[0x60/4]; /* base g registers */ + CARD32 i128_base_w[0x28/4]; /* base w registers */ + CARD32 intm; /* base a+0x04 register */ + unsigned char Ti302X[0x40]; /* Ti302[05] registers */ + unsigned char Ti3025[9]; /* Ti3025 N,M,P for PCLK, MCLK, LCLK */ + unsigned char IBMRGB[0x101]; /* IBMRGB registers */ +} I128RegRec, *I128RegPtr; + + +/* display list processor instruction formats */ +typedef union { + struct { + CARD8 aad; + CARD8 bad; + CARD8 cad; + CARD8 control; + CARD32 rad; + CARD32 rbd; + CARD32 rcd; + } f0; + struct { + CARD32 xy0; + CARD32 xy2; + CARD32 xy3; + CARD32 xy1; + } f1; + CARD32 f4[4]; +} I128dlpu; + +#define UNKNOWN_DAC -1 +#define TI3025_DAC 0 +#define IBM524_DAC 1 +#define IBM526_DAC 2 +#define IBM528_DAC 3 +#define SILVER_HAMMER_DAC 4 + +#define I128_MEMORY_UNKNOWN 0x01 +#define I128_MEMORY_DRAM 0x02 +#define I128_MEMORY_WRAM 0x04 +#define I128_MEMORY_SGRAM 0x08 + +/* RBASE_I register offsets */ + +#define GINTP 0x0000 +#define GINTM 0x0004 +#define SGRAM 0x00A4 + +/* DMA regs, relative to RBASE_I. T2R4 only. */ +#define DMA_SRC 0x00D0/4 +#define DMA_SRC_MASK 0x07 +#define DMA_DST 0x00D4/4 +#define DMA_DST_MASK 0xFC000007 +#define DMA_CMD 0x00D8/4 +#define DMA_QWORDS_MASK 0x0001FFFF +#define DMA_REQ_LENGTH_4Q 0x00000000 +#define DMA_REQ_LENGTH_8Q 0x01000000 +#define DMA_REQ_LENGTH_16Q 0x02000000 +#define DMA_REQ_LENGTH_32Q 0x03000000 +#define DMA_PIPELINE_READY 0x10000000 +#define DMA_IDLE 0x20000000 +#define DMA_EXPEDITE 0x40000000 + +/* RBASE_G register offsets (divided by four for double word indexing */ + +#define WR_ADR 0x0000/4 +#define PAL_DAT 0x0004/4 +#define PEL_MASK 0x0008/4 +#define RD_ADR 0x000C/4 +#define INDEX_TI 0x0018/4 /* TI ramdac */ +#define DATA_TI 0x001C/4 /* TI ramdac */ +#define IDXL_I 0x0010/4 /* IBM ramdac */ +#define IDXH_I 0x0014/4 /* IBM ramdac */ +#define DATA_I 0x0018/4 /* IBM ramdac */ +#define IDXCTL_I 0x001C/4 /* IBM ramdac */ +#define INT_VCNT 0x0020/4 +#define INT_HCNT 0x0024/4 +#define DB_ADR 0x0028/4 +#define DB_PTCH 0x002C/4 +#define CRT_HAC 0x0030/4 +#define CRT_HBL 0x0034/4 +#define CRT_HFP 0x0038/4 +#define CRT_HS 0x003C/4 +#define CRT_VAC 0x0040/4 +#define CRT_VBL 0x0044/4 +#define CRT_VFP 0x0048/4 +#define CRT_VS 0x004C/4 +#define CRT_LCNT 0x0050/4 +#define CRT_ZOOM 0x0054/4 +#define CRT_1CON 0x0058/4 +#define CRT_2CON 0x005C/4 + + +/* RBASE_W register offsets (divided by four for double word indexing */ +/* MW1_* are probably T2R and T2R4 only */ + +#define MW0_CTRL 0x0000/4 +#define MW0_AD 0x0004/4 +#define MW0_SZ 0x0008/4 /* 2MB = 0x9, 4MB = 0xA, 8MB = 0xB */ +#define MW0_PGE 0x000C/4 +#define MW0_ORG 0x0010/4 +#define MW0_MSRC 0x0018/4 +#define MW0_WKEY 0x001C/4 +#define MW0_KDAT 0x0020/4 +#define MW0_MASK 0x0024/4 +#define MW1_CTRL 0x0028/4 +#define MW1_AD 0x002C/4 +#define MW1_SZ 0x0030/4 +#define MW1_PGE 0x0034/4 +#define MW1_ORG 0x0038/4 +#define MW1_MSRC 0x0040/4 +#define MW1_WKEY 0x0044/4 +#define MW1_KDAT 0x0048/4 +#define MW1_MASK 0x004C/4 + +/* RBASE_[AB] register offsets (divided by four for double word indexing */ + +#define INTP 0x0000/4 +#define INTP_DD_INT 0x01 /* drawing op completed */ +#define INTP_CL_INT 0x02 +#define INTM 0x0004/4 +#define INTM_DD_MSK 0x01 +#define INTM_CL_MSK 0x02 +#define FLOW 0x0008/4 +#define FLOW_DEB 0x01 /* drawing engine busy */ +#define FLOW_MCB 0x02 /* mem controller busy */ +#define FLOW_CLP 0x04 +#define FLOW_PRV 0x08 /* prev cmd still running or cache ready */ +#define BUSY 0x000C/4 +#define BUSY_BUSY 0x01 /* command pipeline busy */ +#define XYW_AD 0x0010/4 +#define Z_CTRL 0x0018/4 +#define BUF_CTRL 0x0020/4 +#define BC_AMV 0x02 +#define BC_MP 0x04 +#define BC_AMD 0x08 +#define BC_SEN_MSK 0x0300 +#define BC_SEN_DB 0x0000 +#define BC_SEN_VB 0x0100 +#define BC_SEN_MB 0x0200 +#define BC_SEN_CB 0x0300 +#define BC_DEN_MSK 0x0C00 +#define BC_DEN_DB 0x0000 +#define BC_DEN_VB 0x0400 +#define BC_DEN_MB 0x0800 +#define BC_DEN_CB 0x0C00 +#define BC_DSE 0x1000 +#define BC_VSE 0x2000 +#define BC_MSE 0x4000 +#define BC_PS_MSK 0x001F0000 +#define BC_MDM_MSK 0x00600000 +#define BC_MDM_KEY 0x00200000 +#define BC_MDM_PLN 0x00400000 +#define BC_BLK_ENA 0x00800000 +#define BC_PSIZ_MSK 0x03000000 +#define BC_PSIZ_8B 0x00000000 +#define BC_PSIZ_16B 0x01000000 +#define BC_PSIZ_32B 0x02000000 +#define BC_PSIZ_NOB 0x03000000 +#define BC_CO 0x40000000 +#define BC_CR 0x80000000 +#define DE_PGE 0x0024/4 +#define DP_DVP_MSK 0x0000001F +#define DP_MP_MSK 0x000F0000 +#define DE_SORG 0x0028/4 +#define DE_DORG 0x002C/4 +#define DE_MSRC 0x0030/4 +/* these next two sound bogus */ +#define DE_WKEY 0x0038/4 +#define DE_KYDAT 0x003C/4 +#define DE_TPTCH 0x0038/4 +#define DE_ZPTCH 0x003C/4 +#define DE_SPTCH 0x0040/4 +#define DE_DPTCH 0x0044/4 +#define CMD 0x0048/4 +#define CMD_OPC_MSK 0x000000FF +#define CMD_ROP_MSK 0x0000FF00 +#define CMD_STL_MSK 0x001F0000 +#define CMD_CLP_MSK 0x00E00000 +#define CMD_PAT_MSK 0x0F000000 +#define CMD_HDF_MSK 0x70000000 +#define CMD_OPC 0x0050/4 +#define CO_NOOP 0x00 +#define CO_BITBLT 0x01 +#define CO_LINE 0x02 +#define CO_ELINE 0x03 +#define CO_TRIAN 0x04 +#define CO_PLINE 0x05 +#define CO_RXFER 0x06 +#define CO_WXFER 0x07 +#define CO_LINE3D 0x08 +#define CO_TRIAN3D 0x09 +#define CO_TEXINV 0x0A +#define CO_LOADPAL 0x0B +#define CMD_ROP 0x0054/4 +#define CR_CLEAR 0x00 +#define CR_NOR 0x01 +#define CR_AND_INV 0x02 +#define CR_COPY_INV 0x03 +#define CR_AND_REV 0x04 +#define CR_INVERT 0x05 +#define CR_XOR 0x06 +#define CR_NAND 0x07 +#define CR_AND 0x08 +#define CR_EQUIV 0x09 +#define CR_NOOP 0x0A +#define CR_OR_INV 0x0B +#define CR_COPY 0x0C +#define CR_OR_REV 0x0D +#define CR_OR 0x0E +#define CR_SET 0x0F +#define CMD_STYLE 0x0058/4 +#define CS_SOLID 0x01 +#define CS_TRNSP 0x02 +#define CS_STP_NO 0x00 +#define CS_STP_PL 0x04 +#define CS_STP_PA32 0x08 +#define CS_STP_PA8 0x0C +#define CS_EDI 0x10 +#define CMD_PATRN 0x005C/4 +#define CP_APAT_NO 0x00 +#define CP_APAT_8X 0x01 +#define CP_APAT_32X 0x02 +#define CP_NLST 0x04 +#define CP_PRST 0x08 +#define CMD_CLP 0x0060/4 +#define CC_NOCLP 0x00 +#define CC_CLPRECI 0x02 +#define CC_CLPRECO 0x03 +#define CC_CLPSTOP 0x04 +#define CMD_HDF 0x0064/4 +#define CH_BIT_SWP 0x01 +#define CH_BYT_SWP 0x02 +#define CH_WRD_SWP 0x04 +#define FORE 0x0068/4 +#define BACK 0x006C/4 +#define MASK 0x0070/4 +#define RMSK 0x0074/4 +#define LPAT 0x0078/4 +#define PCTRL 0x007C/4 +#define PC_PLEN_MSK 0x0000001F +#define PC_PSCL_MSK 0x000000E0 +#define PC_SPTR_MSK 0x00001F00 +#define PC_SSCL_MSK 0x0000E000 +#define PC_STATE_MSK 0xFFFF0000 +#define CLPTL 0x0080/4 +#define CLPTLY_MSK 0x0000FFFF +#define CLPTLX_MSK 0xFFFF0000 +#define CLPBR 0x0084/4 +#define CLPBRY_MSK 0x0000FFFF +#define CLPBRX_MSK 0xFFFF0000 +#define XY0_SRC 0x0088/4 +#define XY1_DST 0x008C/4 /* trigger */ +#define XY2_WH 0x0090/4 +#define XY3_DIR 0x0094/4 +#define DIR_LR_TB 0x00000000 +#define DIR_LR_BT 0x00000001 +#define DIR_RL_TB 0x00000002 +#define DIR_RL_BT 0x00000003 +#define XY4_ZM 0x0098/4 +#define ZOOM_NONE 0x00000000 +#define XY_Y_DATA 0x0000FFFF +#define XY_X_DATA 0xFFFF0000 +#define XY_I_DATA1 0x0000FFFF +#define XY_I_DATA2 0xFFFF0000 +#define LOD0_ORG 0x00D0/4 +#define LOD1_ORG 0x00D4/4 +#define LOD2_ORG 0x00D8/4 +#define LOD3_ORG 0x00DC/4 +#define LOD4_ORG 0x00E0/4 +#define LOD5_ORG 0x00E4/4 +#define LOD6_ORG 0x00E8/4 +#define LOD7_ORG 0x00EC/4 +#define LOD8_ORG 0x00F0/4 +#define LOD9_ORG 0x00F4/4 + +#define DL_ADR 0x00F8/4 +#define DL_CNTRL 0x00FC/4 +#define ACNTRL 0x016C/4 +#define ASRC_FUNC 0x0000000F +#define ADST_FUNC 0x000000F0 +#define ACTL_SRE 0x00000100 /* 0: pixel alpha, 1: srca reg */ +#define ACTL_DRE 0x00000200 /* likewise */ +#define ACTL_BE 0x00000400 +#define ACTL_AOP 0x000F0000 +#define ACTL_AEN 0x00100000 /* alpha compare enable */ +#define ACTL_ASL 0x01000000 /* 0: texture alpha, 1: vertex alpha */ +#define ACTL_AMD 0x02000000 +#define ACTL_DAB 0x04000000 +#define THREEDCTL 0x0170/4 +#define TCTL_ZE 0x00000001 +#define TCTL_ZRO 0x00000002 +#define TCTL_FIS 0x00000008 +#define TCTL_FSL 0x00000010 +#define TCTL_ZOP 0x000000E0 +#define TCTL_ZOP_SHIFT 5 +#define TCTL_YOP 0x00000800 +#define TCTL_HOP 0x00003100 +#define TCTL_KYP 0x00004000 +#define TCTL_KYE 0x00008000 +#define TCTL_DOP 0x00010000 +#define TCTL_ABS 0x00020000 +#define TCTL_TBS 0x00040000 +#define TCTL_RSL 0x00080000 +#define TCTL_SSC 0x00200000 +#define TCTL_CW 0x00400000 +#define TCTL_BCE 0x00800000 +#define TCTL_SH 0x01000000 +#define TCTL_SPE 0x02000000 +#define TCTL_RSC 0x04000000 +#define TCTL_FEN 0x08000000 +#define TCTL_RT 0x10000000 +#define TCTL_P8 0x20000000 +#define TCTL_ZS 0x40000000 +#define TEX_CTL 0x0174/4 +#define TEX_TM 0x00000001 +#define TEX_MM 0x00000002 +#define TEX_NMG 0x00000004 +#define TEX_MLM 0x00000008 +#define TEX_NMN 0x00000010 +#define TEX_RM 0x00000020 +#define TEX_PM 0x00000040 +#define TEX_CCS 0x00000080 +#define TEX_TCU 0x00000100 +#define TEX_TCV 0x00000200 +#define TEX_MLP2 0x00000400 +#define TEX_MMN 0x0000F000 +#define TEX_MMSIZEX 0x000F0000 +#define TEX_MMSIZEY 0x00F00000 +#define TEX_FMT 0x3F000000 +#define TEX_TCT 0x40000000 +#define TEX_UVS 0x80000000 +#define PPTR 0x0178/4 +/* for each vertex: x, y, z, w, color, specular color, u, v */ +#define V0_X 0x017C/4 +#define V0_Y 0x0180/4 +#define V0_Z 0x0184/4 +#define V0_W 0x0188/4 +#define V0_C 0x018C/4 +#define V0_S 0x0190/4 +#define V0_U 0x0194/4 +#define V0_V 0x0198/4 +#define V1_X 0x019C/4 +#define V1_Y 0x01A0/4 +#define V1_Z 0x01A4/4 +#define V1_W 0x01A8/4 +#define V1_C 0x01AC/4 +#define V1_S 0x01B0/4 +#define V1_U 0x01B4/4 +#define V1_V 0x01B8/4 +#define V2_X 0x01BC/4 +#define V2_Y 0x01C0/4 +#define V2_Z 0x01C4/4 +#define V2_W 0x01C8/4 +#define V2_C 0x01CC/4 +#define V2_S 0x01D0/4 +#define V2_U 0x01D4/4 +#define V2_V 0x01D8/4 +#define TRIGGER3D 0x01DC/4 + +/* alpha blend functions */ +#define ABLEND_SRC_ZERO 0 +#define ABLEND_SRC_ONE 1 +#define ABLEND_SRC_DST_COLOR 2 +#define ABLEND_SRC_OMDST_COLOR 3 +#define ABLEND_SRC_SRC_ALPHA 4 +#define ABLEND_SRC_OMSRC_ALPHA 5 +#define ABLEND_SRC_DST_ALPHA 6 +#define ABLEND_SRC_OMDST_ALPHA 7 +#define ABLEND_DST_ZERO 0 << 4 +#define ABLEND_DST_ONE 1 << 4 +#define ABLEND_DST_SRC_COLOR 2 << 4 +#define ABLEND_DST_OMSRC_COLOR 3 << 4 +#define ABLEND_DST_SRC_ALPHA 4 << 4 +#define ABLEND_DST_OMSRC_ALPHA 5 << 4 +#define ABLEND_DST_DST_ALPHA 6 << 4 +#define ABLEND_DST_OMDST_ALPHA 7 << 4 + +/* comparison functions */ +#define COMP_FALSE 0 +#define COMP_TRUE 1 +#define COMP_LT 2 +#define COMP_LE 3 +#define COMP_EQ 4 +#define COMP_GE 5 +#define COMP_GT 6 +#define COMP_NE 7 + + +#define I128_WAIT_READY 1 +#define I128_WAIT_DONE 2 + +typedef struct { + unsigned char r, b, g; +} LUTENTRY; + +#define RGB8_PSEUDO (-1) +#define RGB16_565 0 +#define RGB16_555 1 +#define RGB32_888 2 + +#define MB mem_barrier() + + +/* TI ramdac indirect indexed registers */ + +#define TI_CURS_X_LOW 0x00 +#define TI_CURS_X_HIGH 0x01 /* only lower 4 bits are used */ +#define TI_CURS_Y_LOW 0x02 +#define TI_CURS_Y_HIGH 0x03 /* only lower 4 bits are used */ +#define TI_SPRITE_ORIGIN_X 0x04 +#define TI_SPRITE_ORIGIN_Y 0x05 +#define TI_CURS_CONTROL 0x06 +#define TI_PLANAR_ACCESS 0x80 /* 3025 only - 80 == BT485 mode */ +#define TI_CURS_SPRITE_ENABLE 0x40 +#define TI_CURS_X_WINDOW_MODE 0x10 +#define TI_CURS_CTRL_MASK (TI_CURS_SPRITE_ENABLE | TI_CURS_X_WINDOW_MODE) +#define TI_CURS_RAM_ADDR_LOW 0x08 +#define TI_CURS_RAM_ADDR_HIGH 0x09 +#define TI_CURS_RAM_DATA 0x0A +#define TI_TRUE_COLOR_CONTROL 0x0E /* 3025 only */ +#define TI_TC_BTMODE 0x04 /* on = BT485 mode, off = TI3020 mode */ +#define TI_TC_NONVGAMODE 0x02 /* on = nonvgamode, off = vgamode */ +#define TI_TC_8BIT 0x01 /* on = 8/4bit, off = 16/32bit */ +#define TI_VGA_SWITCH_CONTROL 0x0F /* 3025 only */ +#define TI_LATCH_CONTROL 0x0F /* 3026 only */ +#define TI_WINDOW_START_X_LOW 0x10 +#define TI_WINDOW_START_X_HIGH 0x11 +#define TI_WINDOW_STOP_X_LOW 0x12 +#define TI_WINDOW_STOP_X_HIGH 0x13 +#define TI_WINDOW_START_Y_LOW 0x14 +#define TI_WINDOW_START_Y_HIGH 0x15 +#define TI_WINDOW_STOP_Y_LOW 0x16 +#define TI_WINDOW_STOP_Y_HIGH 0x17 +#define TI_MUX_CONTROL_1 0x18 +#define TI_MUX1_PSEUDO_COLOR 0x80 +#define TI_MUX1_DIRECT_888 0x06 +#define TI_MUX1_DIRECT_565 0x05 +#define TI_MUX1_DIRECT_555 0x04 +#define TI_MUX1_DIRECT_664 0x03 +#define TI_MUX1_TRUE_888 0x46 +#define TI_MUX1_TRUE_565 0x45 +#define TI_MUX1_TRUE_555 0x44 +#define TI_MUX1_TRUE_664 0x43 +#define TI_MUX1_3025D_888 0x0E /* 3025 only */ +#define TI_MUX1_3025D_565 0x0D /* 3025 only */ +#define TI_MUX1_3025D_555 0x0C /* 3025 only */ +#define TI_MUX1_3025T_888 0x4E /* 3025 only */ +#define TI_MUX1_3025T_565 0x4D /* 3025 only */ +#define TI_MUX1_3025T_555 0x4C /* 3025 only */ +#define TI_MUX1_3026D_888 0x06 /* 3026 only */ +#define TI_MUX1_3026D_565 0x05 /* 3026 only */ +#define TI_MUX1_3026D_555 0x04 /* 3026 only */ +#define TI_MUX1_3026D_888_P8 0x16 /* 3026 only */ +#define TI_MUX1_3026D_888_P5 0x1e /* 3026 only */ +#define TI_MUX1_3026T_888 0x46 /* 3026 only */ +#define TI_MUX1_3026T_565 0x45 /* 3026 only */ +#define TI_MUX1_3026T_555 0x44 /* 3026 only */ +#define TI_MUX1_3026T_888_P8 0x56 /* 3026 only */ +#define TI_MUX1_3026T_888_P5 0x5e /* 3026 only */ +#define TI_MUX_CONTROL_2 0x19 +#define TI_MUX2_BUS_VGA 0x98 +#define TI_MUX2_BUS_PC_D8P64 0x1C +#define TI_MUX2_BUS_DC_D24P64 0x1C +#define TI_MUX2_BUS_DC_D16P64 0x04 +#define TI_MUX2_BUS_DC_D15P64 0x04 +#define TI_MUX2_BUS_TC_D24P64 0x04 +#define TI_MUX2_BUS_TC_D16P64 0x04 +#define TI_MUX2_BUS_TC_D15P64 0x04 +#define TI_MUX2_BUS_3026PC_D8P64 0x4C +#define TI_MUX2_BUS_3026DC_D24P64 0x5C +#define TI_MUX2_BUS_3026DC_D16P64 0x54 +#define TI_MUX2_BUS_3026DC_D15P64 0x54 +#define TI_MUX2_BUS_3026TC_D24P64 0x5c +#define TI_MUX2_BUS_3026TC_D16P64 0x54 +#define TI_MUX2_BUS_3026TC_D15P64 0x54 +#define TI_MUX2_BUS_3030PC_D8P128 0x4d +#define TI_MUX2_BUS_3030DC_D24P128 0x5d +#define TI_MUX2_BUS_3030DC_D16P128 0x55 +#define TI_MUX2_BUS_3030DC_D15P128 0x55 +#define TI_MUX2_BUS_3030TC_D24P128 0x5d +#define TI_MUX2_BUS_3030TC_D16P128 0x55 +#define TI_MUX2_BUS_3030TC_D15P128 0x55 +#define TI_INPUT_CLOCK_SELECT 0x1A +#define TI_ICLK_CLK0 0x00 +#define TI_ICLK_CLK0_DOUBLE 0x10 +#define TI_ICLK_CLK1 0x01 +#define TI_ICLK_CLK1_DOUBLE 0x11 +#define TI_ICLK_CLK2 0x02 /* 3025 only */ +#define TI_ICLK_CLK2_DOUBLE 0x12 /* 3025 only */ +#define TI_ICLK_CLK2_I 0x03 /* 3025 only */ +#define TI_ICLK_CLK2_I_DOUBLE 0x13 /* 3025 only */ +#define TI_ICLK_CLK2_E 0x04 /* 3025 only */ +#define TI_ICLK_CLK2_E_DOUBLE 0x14 /* 3025 only */ +#define TI_ICLK_PLL 0x05 /* 3025 only */ +#define TI_OUTPUT_CLOCK_SELECT 0x1B +#define TI_OCLK_VGA 0x3E +#define TI_OCLK_S 0x40 +#define TI_OCLK_NS 0x80 /* 3025 only */ +#define TI_OCLK_V1 0x00 +#define TI_OCLK_V2 0x08 +#define TI_OCLK_V4 0x10 +#define TI_OCLK_V8 0x18 +#define TI_OCLK_R1 0x00 +#define TI_OCLK_R2 0x01 +#define TI_OCLK_R4 0x02 +#define TI_OCLK_R8 0x03 +#define TI_OCLK_S_V1_R8 (TI_OCLK_S | TI_OCLK_V1 | TI_OCLK_R8) +#define TI_OCLK_S_V2_R8 (TI_OCLK_S | TI_OCLK_V2 | TI_OCLK_R8) +#define TI_OCLK_S_V4_R8 (TI_OCLK_S | TI_OCLK_V4 | TI_OCLK_R8) +#define TI_OCLK_S_V8_R8 (TI_OCLK_S | TI_OCLK_V8 | TI_OCLK_R8) +#define TI_OCLK_S_V2_R4 (TI_OCLK_S | TI_OCLK_V2 | TI_OCLK_R4) +#define TI_OCLK_S_V4_R4 (TI_OCLK_S | TI_OCLK_V4 | TI_OCLK_R4) +#define TI_OCLK_S_V1_R2 (TI_OCLK_S | TI_OCLK_V1 | TI_OCLK_R2) +#define TI_OCLK_S_V2_R2 (TI_OCLK_S | TI_OCLK_V2 | TI_OCLK_R2) +#define TI_OCLK_NS_V1_R1 (TI_OCLK_NS | TI_OCLK_V1 | TI_OCLK_R1) +#define TI_OCLK_NS_V2_R2 (TI_OCLK_NS | TI_OCLK_V2 | TI_OCLK_R2) +#define TI_OCLK_NS_V4_R4 (TI_OCLK_NS | TI_OCLK_V4 | TI_OCLK_R4) +#define TI_PALETTE_PAGE 0x1C +#define TI_GENERAL_CONTROL 0x1D +#define TI_MISC_CONTROL 0x1E /* 3025 only */ +#define TI_MC_POWER_DOWN 0x01 +#define TI_MC_DOTCLK_DISABLE 0x02 +#define TI_MC_INT_6_8_CONTROL 0x04 /* 00 == external 6/8 pin */ +#define TI_MC_8_BPP 0x08 /* 00 == 6bpp */ +#define TI_MC_PSEL_POLARITY 0x20 /* 3026 only, PSEL polarity select */ +#define TI_MC_VCLK_POLARITY 0x20 +#define TI_MC_LCLK_LATCH 0x40 /* VCLK == 00, default */ +#define TI_MC_LOOP_PLL_RCLK 0x80 +#define TI_OVERSCAN_COLOR_RED 0x20 +#define TI_OVERSCAN_COLOR_GREEN 0x21 +#define TI_OVERSCAN_COLOR_BLUE 0x22 +#define TI_CURSOR_COLOR_0_RED 0x23 +#define TI_CURSOR_COLOR_0_GREEN 0x24 +#define TI_CURSOR_COLOR_0_BLUE 0x25 +#define TI_CURSOR_COLOR_1_RED 0x26 +#define TI_CURSOR_COLOR_1_GREEN 0x27 +#define TI_CURSOR_COLOR_1_BLUE 0x28 +#define TI_AUXILIARY_CONTROL 0x29 +#define TI_AUX_SELF_CLOCK 0x08 +#define TI_AUX_W_CMPL 0x01 +#define TI_GENERAL_IO_CONTROL 0x2A +#define TI_GIC_ALL_BITS 0x1F +#define TI_GENERAL_IO_DATA 0x2B +#define TI_GID_W2000_6BIT 0x00 +#define TI_GID_N9_964 0x01 +#define TI_GID_ELSA_SOG 0x04 +#define TI_GID_W2000_8BIT 0x08 +#define TI_GID_S3_DAC_6BIT 0x1C +#define TI_GID_S3_DAC_8BIT 0x1E +#define TI_GID_TI_DAC_6BIT 0x1D +#define TI_GID_TI_DAC_8BIT 0x1F +#define TI_PLL_CONTROL 0x2C /* 3025 only */ +#define TI_PIXEL_CLOCK_PLL_DATA 0x2D /* 3025 only */ +#define TI_PLL_ENABLE 0x08 /* 3025 only */ +#define TI_MCLK_PLL_DATA 0x2E /* 3025 only */ +#define TI_LOOP_CLOCK_PLL_DATA 0x2F /* 3025 only */ +#define TI_COLOR_KEY_OLVGA_LOW 0x30 +#define TI_COLOR_KEY_OLVGA_HIGH 0x31 +#define TI_COLOR_KEY_RED_LOW 0x32 +#define TI_COLOR_KEY_RED_HIGH 0x33 +#define TI_COLOR_KEY_GREEN_LOW 0x34 +#define TI_COLOR_KEY_GREEN_HIGH 0x35 +#define TI_COLOR_KEY_BLUE_LOW 0x36 +#define TI_COLOR_KEY_BLUE_HIGH 0x37 +#define TI_COLOR_KEY_CONTROL 0x38 +#define TI_COLOR_KEY_CMPL 0x10 +#define TI_MCLK_DCLK_CONTROL 0x39 /* 3025 only */ +#define TI_MCLK_LCLK_CONTROL 0x39 /* 3026 only */ +#define TI_SENSE_TEST 0x3A +#define TI_TEST_DATA 0x3B +#define TI_CRC_LOW 0x3C +#define TI_CRC_HIGH 0x3D +#define TI_CRC_CONTROL 0x3E +#define TI_ID 0x3F +#define TI_VIEWPOINT20_ID 0x20 +#define TI_VIEWPOINT25_ID 0x25 +#define TI_MODE_85_CONTROL 0xD5 /* 3025 only */ + +#define TI_REF_FREQ 14.31818 /* 3025 only */ + +/* + * which clocks should be set (just flags...) + */ +#define TI_BOTH_CLOCKS 1 +#define TI_LOOP_CLOCK 2 + +/* IBM ramdac registers */ + +#define IBMRGB_rev 0x00 +#define IBMRGB_id 0x01 +#define IBMRGB_misc_clock 0x02 +#define IBMRGB_sync 0x03 +#define IBMRGB_hsync_pos 0x04 +#define IBMRGB_pwr_mgmt 0x05 +#define IBMRGB_dac_op 0x06 +#define IBMRGB_pal_ctrl 0x07 +#define IBMRGB_sysclk 0x08 /* not RGB525 */ +#define IBMRGB_pix_fmt 0x0a +#define IBMRGB_8bpp 0x0b +#define IBMRGB_16bpp 0x0c +#define IBMRGB_24bpp 0x0d +#define IBMRGB_32bpp 0x0e +#define IBMRGB_pll_ctrl1 0x10 +#define IBMRGB_pll_ctrl2 0x11 +#define IBMRGB_pll_ref_div_fix 0x14 +#define IBMRGB_sysclk_ref_div 0x15 /* not RGB525 */ +#define IBMRGB_sysclk_vco_div 0x16 /* not RGB525 */ +#define IBMRGB_f0 0x20 +#define IBMRGB_m0 0x20 +#define IBMRGB_n0 0x21 +#define IBMRGB_curs 0x30 +#define IBMRGB_curs_xl 0x31 +#define IBMRGB_curs_xh 0x32 +#define IBMRGB_curs_yl 0x33 +#define IBMRGB_curs_yh 0x34 +#define IBMRGB_curs_hot_x 0x35 +#define IBMRGB_curs_hot_y 0x36 +#define IBMRGB_curs_col1_r 0x40 +#define IBMRGB_curs_col1_g 0x41 +#define IBMRGB_curs_col1_b 0x42 +#define IBMRGB_curs_col2_r 0x43 +#define IBMRGB_curs_col2_g 0x44 +#define IBMRGB_curs_col2_b 0x45 +#define IBMRGB_curs_col3_r 0x46 +#define IBMRGB_curs_col3_g 0x47 +#define IBMRGB_curs_col3_b 0x48 +#define IBMRGB_border_col_r 0x60 +#define IBMRGB_border_col_g 0x61 +#define IBMRGB_botder_col_b 0x62 +#define IBMRGB_misc1 0x70 +#define IBMRGB_misc2 0x71 +#define IBMRGB_misc3 0x72 +#define IBMRGB_misc4 0x73 /* not RGB525 */ +#define IBMRGB_dac_sense 0x82 +#define IBMRGB_misr_r 0x84 +#define IBMRGB_misr_g 0x86 +#define IBMRGB_misr_b 0x88 +#define IBMRGB_pll_vco_div_in 0x8e +#define IBMRGB_pll_ref_div_in 0x8f +#define IBMRGB_vram_mask_0 0x90 +#define IBMRGB_vram_mask_1 0x91 +#define IBMRGB_vram_mask_2 0x92 +#define IBMRGB_vram_mask_3 0x93 +#define IBMRGB_curs_array 0x100 + +#endif |