diff options
Diffstat (limited to 'xorg-server/hw/kdrive/i810')
-rw-r--r-- | xorg-server/hw/kdrive/i810/Makefile.am | 39 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/i810/Makefile.in | 721 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/i810/i810.c | 2112 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/i810/i810.h | 511 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/i810/i810_cursor.c | 435 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/i810/i810_reg.h | 695 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/i810/i810_video.c | 1136 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/i810/i810draw.c | 352 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/i810/i810draw.h | 46 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/i810/i810stub.c | 92 |
10 files changed, 6139 insertions, 0 deletions
diff --git a/xorg-server/hw/kdrive/i810/Makefile.am b/xorg-server/hw/kdrive/i810/Makefile.am new file mode 100644 index 000000000..30919fad9 --- /dev/null +++ b/xorg-server/hw/kdrive/i810/Makefile.am @@ -0,0 +1,39 @@ +INCLUDES = \ + @KDRIVE_INCS@ \ + @KDRIVE_CFLAGS@ + +bin_PROGRAMS = Xi810 + +noinst_LIBRARIES = libi810.a + + +libi810_a_SOURCES = \ + i810_cursor.c \ + i810_video.c \ + i810draw.c \ + i810draw.h \ + i810_reg.h \ + i810.c \ + i810.h + +Xi810_SOURCES = \ + i810stub.c + +I810_LIBS = \ + libi810.a \ + @KDRIVE_LIBS@ + +if GLX +Xi810_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) +endif + +Xi810_LDADD = \ + $(I810_LIBS) \ + @KDRIVE_LIBS@ + +Xi810_DEPENDENCIES = \ + libi810.a \ + @KDRIVE_LOCAL_LIBS@ + +relink: + rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS) diff --git a/xorg-server/hw/kdrive/i810/Makefile.in b/xorg-server/hw/kdrive/i810/Makefile.in new file mode 100644 index 000000000..ba05704b7 --- /dev/null +++ b/xorg-server/hw/kdrive/i810/Makefile.in @@ -0,0 +1,721 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = Xi810$(EXEEXT) +subdir = hw/kdrive/i810 +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/do-not-use-config.h \ + $(top_builddir)/include/xorg-server.h \ + $(top_builddir)/include/dix-config.h \ + $(top_builddir)/include/xgl-config.h \ + $(top_builddir)/include/xorg-config.h \ + $(top_builddir)/include/xkb-config.h \ + $(top_builddir)/include/xwin-config.h \ + $(top_builddir)/include/kdrive-config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libi810_a_AR = $(AR) $(ARFLAGS) +libi810_a_LIBADD = +am_libi810_a_OBJECTS = i810_cursor.$(OBJEXT) i810_video.$(OBJEXT) \ + i810draw.$(OBJEXT) i810.$(OBJEXT) +libi810_a_OBJECTS = $(am_libi810_a_OBJECTS) +am__installdirs = "$(DESTDIR)$(bindir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +am_Xi810_OBJECTS = i810stub.$(OBJEXT) +Xi810_OBJECTS = $(am_Xi810_OBJECTS) +am__DEPENDENCIES_1 = libi810.a +Xi810_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(Xi810_LDFLAGS) \ + $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libi810_a_SOURCES) $(Xi810_SOURCES) +DIST_SOURCES = $(libi810_a_SOURCES) $(Xi810_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@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +APPDEFAULTDIR = @APPDEFAULTDIR@ +APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ +APP_MAN_DIR = @APP_MAN_DIR@ +APP_MAN_SUFFIX = @APP_MAN_SUFFIX@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASE_FONT_PATH = @BASE_FONT_PATH@ +BUILD_DATE = @BUILD_DATE@ +BUILD_TIME = @BUILD_TIME@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DARWIN_LIBS = @DARWIN_LIBS@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ +DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ +DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DGA_CFLAGS = @DGA_CFLAGS@ +DGA_LIBS = @DGA_LIBS@ +DIX_CFLAGS = @DIX_CFLAGS@ +DLLTOOL = @DLLTOOL@ +DMXEXAMPLES_DEP_CFLAGS = @DMXEXAMPLES_DEP_CFLAGS@ +DMXEXAMPLES_DEP_LIBS = @DMXEXAMPLES_DEP_LIBS@ +DMXMODULES_CFLAGS = @DMXMODULES_CFLAGS@ +DMXMODULES_LIBS = @DMXMODULES_LIBS@ +DMXXIEXAMPLES_DEP_CFLAGS = @DMXXIEXAMPLES_DEP_CFLAGS@ +DMXXIEXAMPLES_DEP_LIBS = @DMXXIEXAMPLES_DEP_LIBS@ +DMXXMUEXAMPLES_DEP_CFLAGS = @DMXXMUEXAMPLES_DEP_CFLAGS@ +DMXXMUEXAMPLES_DEP_LIBS = @DMXXMUEXAMPLES_DEP_LIBS@ +DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ +DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ +DRIPROTO_CFLAGS = @DRIPROTO_CFLAGS@ +DRIPROTO_LIBS = @DRIPROTO_LIBS@ +DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ +DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ +DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ +DSYMUTIL = @DSYMUTIL@ +DTRACE = @DTRACE@ +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@ +FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ +FREETYPE_LIBS = @FREETYPE_LIBS@ +GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ +GLX_DEFINES = @GLX_DEFINES@ +GL_CFLAGS = @GL_CFLAGS@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +HAL_CFLAGS = @HAL_CFLAGS@ +HAL_LIBS = @HAL_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KDRIVE_CFLAGS = @KDRIVE_CFLAGS@ +KDRIVE_INCS = @KDRIVE_INCS@ +KDRIVE_LIBS = @KDRIVE_LIBS@ +KDRIVE_LOCAL_LIBS = @KDRIVE_LOCAL_LIBS@ +KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ +KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ +LAUNCHD = @LAUNCHD@ +LDFLAGS = @LDFLAGS@ +LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ +LIBDRM_LIBS = @LIBDRM_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_MAN_DIR = @LIB_MAN_DIR@ +LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ +LINUXDOC = @LINUXDOC@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MAKE_HTML = @MAKE_HTML@ +MAKE_PDF = @MAKE_PDF@ +MAKE_PS = @MAKE_PS@ +MAKE_TEXT = @MAKE_TEXT@ +MESA_SOURCE = @MESA_SOURCE@ +MISC_MAN_DIR = @MISC_MAN_DIR@ +MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ +MKDIR_P = @MKDIR_P@ +MKFONTDIR = @MKFONTDIR@ +MKFONTSCALE = @MKFONTSCALE@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJCCLD = @OBJCCLD@ +OBJCDEPMODE = @OBJCDEPMODE@ +OBJCFLAGS = @OBJCFLAGS@ +OBJCLINK = @OBJCLINK@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ +PCIACCESS_LIBS = @PCIACCESS_LIBS@ +PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PROJECTROOT = @PROJECTROOT@ +PS2PDF = @PS2PDF@ +RANLIB = @RANLIB@ +RAWCPP = @RAWCPP@ +RAWCPPFLAGS = @RAWCPPFLAGS@ +SED = @SED@ +SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOLARIS_ASM_CFLAGS = @SOLARIS_ASM_CFLAGS@ +SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ +STRIP = @STRIP@ +TSLIB_CFLAGS = @TSLIB_CFLAGS@ +TSLIB_LIBS = @TSLIB_LIBS@ +UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ +VENDOR_MAN_VERSION = @VENDOR_MAN_VERSION@ +VENDOR_NAME = @VENDOR_NAME@ +VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ +VENDOR_RELEASE = @VENDOR_RELEASE@ +VERSION = @VERSION@ +X11APP_ARCHS = @X11APP_ARCHS@ +X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ +X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ +XDMCP_CFLAGS = @XDMCP_CFLAGS@ +XDMCP_LIBS = @XDMCP_LIBS@ +XDMXCONFIG_DEP_CFLAGS = @XDMXCONFIG_DEP_CFLAGS@ +XDMXCONFIG_DEP_LIBS = @XDMXCONFIG_DEP_LIBS@ +XDMX_CFLAGS = @XDMX_CFLAGS@ +XDMX_LIBS = @XDMX_LIBS@ +XDMX_SYS_LIBS = @XDMX_SYS_LIBS@ +XEGLMODULES_CFLAGS = @XEGLMODULES_CFLAGS@ +XEGL_LIBS = @XEGL_LIBS@ +XEGL_SYS_LIBS = @XEGL_SYS_LIBS@ +XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ +XEPHYR_DRI_LIBS = @XEPHYR_DRI_LIBS@ +XEPHYR_INCS = @XEPHYR_INCS@ +XEPHYR_LIBS = @XEPHYR_LIBS@ +XF86CONFIGFILE = @XF86CONFIGFILE@ +XF86MISC_CFLAGS = @XF86MISC_CFLAGS@ +XF86MISC_LIBS = @XF86MISC_LIBS@ +XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@ +XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@ +XGLMODULES_CFLAGS = @XGLMODULES_CFLAGS@ +XGLMODULES_LIBS = @XGLMODULES_LIBS@ +XGLXMODULES_CFLAGS = @XGLXMODULES_CFLAGS@ +XGLXMODULES_LIBS = @XGLXMODULES_LIBS@ +XGLX_LIBS = @XGLX_LIBS@ +XGLX_SYS_LIBS = @XGLX_SYS_LIBS@ +XGL_LIBS = @XGL_LIBS@ +XGL_MODULE_PATH = @XGL_MODULE_PATH@ +XGL_SYS_LIBS = @XGL_SYS_LIBS@ +XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ +XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ +XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ +XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ +XLIB_CFLAGS = @XLIB_CFLAGS@ +XLIB_LIBS = @XLIB_LIBS@ +XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ +XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ +XNEST_LIBS = @XNEST_LIBS@ +XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ +XORGCFG_DEP_CFLAGS = @XORGCFG_DEP_CFLAGS@ +XORGCFG_DEP_LIBS = @XORGCFG_DEP_LIBS@ +XORGCONFIG_DEP_CFLAGS = @XORGCONFIG_DEP_CFLAGS@ +XORGCONFIG_DEP_LIBS = @XORGCONFIG_DEP_LIBS@ +XORG_CFLAGS = @XORG_CFLAGS@ +XORG_INCS = @XORG_INCS@ +XORG_LIBS = @XORG_LIBS@ +XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ +XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ +XORG_OS = @XORG_OS@ +XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ +XORG_SYS_LIBS = @XORG_SYS_LIBS@ +XPRINTMODULES_CFLAGS = @XPRINTMODULES_CFLAGS@ +XPRINTMODULES_LIBS = @XPRINTMODULES_LIBS@ +XPRINTPROTO_CFLAGS = @XPRINTPROTO_CFLAGS@ +XPRINTPROTO_LIBS = @XPRINTPROTO_LIBS@ +XPRINT_CFLAGS = @XPRINT_CFLAGS@ +XPRINT_LIBS = @XPRINT_LIBS@ +XPRINT_SYS_LIBS = @XPRINT_SYS_LIBS@ +XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ +XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_LIBS@ +XSDL_INCS = @XSDL_INCS@ +XSDL_LIBS = @XSDL_LIBS@ +XSERVERCFLAGS_CFLAGS = @XSERVERCFLAGS_CFLAGS@ +XSERVERCFLAGS_LIBS = @XSERVERCFLAGS_LIBS@ +XSERVERLIBS_CFLAGS = @XSERVERLIBS_CFLAGS@ +XSERVERLIBS_LIBS = @XSERVERLIBS_LIBS@ +XSERVER_LIBS = @XSERVER_LIBS@ +XSERVER_SYS_LIBS = @XSERVER_SYS_LIBS@ +XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ +XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ +XVFB_LIBS = @XVFB_LIBS@ +XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ +XWINMODULES_CFLAGS = @XWINMODULES_CFLAGS@ +XWINMODULES_LIBS = @XWINMODULES_LIBS@ +XWIN_LIBS = @XWIN_LIBS@ +XWIN_SERVER_NAME = @XWIN_SERVER_NAME@ +XWIN_SYS_LIBS = @XWIN_SYS_LIBS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +__XCONFIGFILE__ = @__XCONFIGFILE__@ +abi_ansic = @abi_ansic@ +abi_extension = @abi_extension@ +abi_font = @abi_font@ +abi_videodrv = @abi_videodrv@ +abi_xinput = @abi_xinput@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +driverdir = @driverdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +extdir = @extdir@ +ft_config = @ft_config@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +launchagentsdir = @launchagentsdir@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +logdir = @logdir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moduledir = @moduledir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sdkdir = @sdkdir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +xglmoduledir = @xglmoduledir@ +xpconfigdir = @xpconfigdir@ +INCLUDES = \ + @KDRIVE_INCS@ \ + @KDRIVE_CFLAGS@ + +noinst_LIBRARIES = libi810.a +libi810_a_SOURCES = \ + i810_cursor.c \ + i810_video.c \ + i810draw.c \ + i810draw.h \ + i810_reg.h \ + i810.c \ + i810.h + +Xi810_SOURCES = \ + i810stub.c + +I810_LIBS = \ + libi810.a \ + @KDRIVE_LIBS@ + +@GLX_TRUE@Xi810_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) +Xi810_LDADD = \ + $(I810_LIBS) \ + @KDRIVE_LIBS@ + +Xi810_DEPENDENCIES = \ + libi810.a \ + @KDRIVE_LOCAL_LIBS@ + +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) --foreign hw/kdrive/i810/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign hw/kdrive/i810/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 + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libi810.a: $(libi810_a_OBJECTS) $(libi810_a_DEPENDENCIES) + -rm -f libi810.a + $(libi810_a_AR) libi810.a $(libi810_a_OBJECTS) $(libi810_a_LIBADD) + $(RANLIB) libi810.a +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +Xi810$(EXEEXT): $(Xi810_OBJECTS) $(Xi810_DEPENDENCIES) + @rm -f Xi810$(EXEEXT) + $(Xi810_LINK) $(Xi810_OBJECTS) $(Xi810_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i810.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i810_cursor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i810_video.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i810draw.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i810stub.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; 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-binPROGRAMS clean-generic clean-libtool \ + clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool clean-noinstLIBRARIES ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS + + +relink: + rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS) +# 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/xorg-server/hw/kdrive/i810/i810.c b/xorg-server/hw/kdrive/i810/i810.c new file mode 100644 index 000000000..49090f9eb --- /dev/null +++ b/xorg-server/hw/kdrive/i810/i810.c @@ -0,0 +1,2112 @@ +/* COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 2000, 2001 Nokia Home Communications + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. + +X Window System is a trademark of The Open Group */ + +/* + * i810.c - KDrive driver for the i810 chipset + * + * Authors: + * Pontus Lidman <pontus.lidman@nokia.com> + * + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" +#include "kxv.h" +#include "klinux.h" + +#include "i810.h" +#include "agp.h" + +#include "i810draw.h" + +#ifndef I810_DEBUG +int I810_DEBUG = (0 +/* | DEBUG_ALWAYS_SYNC */ +/* | DEBUG_VERBOSE_ACCEL */ +/* | DEBUG_VERBOSE_SYNC */ +/* | DEBUG_VERBOSE_VGA */ +/* | DEBUG_VERBOSE_RING */ +/* | DEBUG_VERBOSE_OUTREG */ +/* | DEBUG_VERBOSE_MEMORY */ +/* | DEBUG_VERBOSE_CURSOR */ + ); +#endif + + +static Bool +i810ModeInit(KdScreenInfo *screen, const KdMonitorTiming *t); + +static void +i810PrintMode( vgaRegPtr vgaReg, I810RegPtr mode ); + +Bool +i810CardInit (KdCardInfo *card) +{ + int i; + + I810CardInfo *i810c; + +/* fprintf(stderr,"i810CardInit\n"); */ + + i810c = (I810CardInfo *) xalloc (sizeof (I810CardInfo)); + + if (!i810c) + return FALSE; + + /* 2MB Video RAM */ + i810c->videoRam=2048; + + /* Find FB address */ + + if (card->attr.address[1] != 0) { + i810c->LinearAddr = card->attr.address[0] & 0xFF000000; + + if (!i810c->LinearAddr) { + fprintf(stderr,"No valid FB address in PCI config space(1)\n"); + xfree(i810c); + return FALSE; + } else { +/* fprintf(stderr,"Linear framebuffer at %lx\n",i810c->LinearAddr); */ + } + } else { + fprintf(stderr,"No valid FB address in PCI config space(2)\n"); + xfree(i810c); + return FALSE; + } + + if (card->attr.address[1]) { + + i810c->MMIOAddr = card->attr.address[1] & 0xFFF80000; + + i810c->MMIOBase = + KdMapDevice (i810c->MMIOAddr, I810_REG_SIZE); + if (!i810c->MMIOBase) { + fprintf(stderr,"No valid MMIO address in PCI config space(1)\n"); + xfree(i810c); + return FALSE; + } else { + + } + } else { + fprintf(stderr,"No valid MMIO address in PCI config space(2)\n"); + xfree(i810c); + return FALSE; + } + +/* fprintf(stderr,"Mapped 0x%x bytes of MMIO regs at phys 0x%lx virt %p\n", */ +/* I810_REG_SIZE,i810c->MMIOAddr,i810c->MMIOBase); */ + + /* Find out memory bus frequency. + */ + + { + unsigned long *p; + + if (!(p= (unsigned long *) LinuxGetPciCfg(&card->attr))) + return FALSE; + +/* fprintf(stderr,"Frequency long %lx\n",p[WHTCFG_PAMR_DRP]); */ + + if ( (p[WHTCFG_PAMR_DRP] & LM_FREQ_MASK) == LM_FREQ_133 ) + i810c->LmFreqSel = 133; + else + i810c->LmFreqSel = 100; + + xfree(p); + +/* fprintf(stderr,"Selected frequency %d\n",i810c->LmFreqSel); */ + } + +/* fprintf(stderr,"Will alloc AGP framebuffer: %d kByte\n",i810c->videoRam); */ + + /* Since we always want write combining on first 32 mb of framebuffer + * we pass a mapsize of 32 mb */ + i810c->FbMapSize = 32*1024*1024; + + for (i = 2 ; i < i810c->FbMapSize ; i <<= 1); + i810c->FbMapSize = i; + + i810c->FbBase = + KdMapDevice (i810c->LinearAddr, i810c->FbMapSize); + + if (!i810c->FbBase) return FALSE; +/* fprintf(stderr,"Mapped 0x%lx bytes of framebuffer at %p\n", */ +/* i810c->FbMapSize,i810c->FbBase); */ + + card->driver=i810c; + + return TRUE; +} + +static void +i810ScreenFini (KdScreenInfo *screen) +{ + I810ScreenInfo *i810s = (I810ScreenInfo *) screen->driver; + + xfree (i810s); + screen->driver = 0; +} + +static Bool +i810InitScreen (ScreenPtr pScreen) { + +#ifdef XV + i810InitVideo(pScreen); +#endif + return TRUE; +} + +static Bool +i810FinishInitScreen(ScreenPtr pScreen) +{ + /* XXX: RandR init */ + return TRUE; +} + +static void +i810CardFini (KdCardInfo *card) +{ + I810CardInfo *i810c = (I810CardInfo *) card->driver; + + KdUnmapDevice (i810c->FbBase, i810c->FbMapSize); + KdUnmapDevice (i810c->MMIOBase, I810_REG_SIZE); + xfree (i810c); + card->driver = 0; +} + +struct wm_info { + double freq; + unsigned int wm; +}; + +struct wm_info i810_wm_8_100[] = { + { 0, 0x22003000 }, + { 25.2, 0x22003000 }, + { 28.0, 0x22003000 }, + { 31.5, 0x22003000 }, + { 36.0, 0x22007000 }, + { 40.0, 0x22007000 }, + { 45.0, 0x22007000 }, + { 49.5, 0x22008000 }, + { 50.0, 0x22008000 }, + { 56.3, 0x22008000 }, + { 65.0, 0x22008000 }, + { 75.0, 0x22008000 }, + { 78.8, 0x22008000 }, + { 80.0, 0x22008000 }, + { 94.0, 0x22008000 }, + { 96.0, 0x22107000 }, + { 99.0, 0x22107000 }, + { 108.0, 0x22107000 }, + { 121.0, 0x22107000 }, + { 128.9, 0x22107000 }, + { 132.0, 0x22109000 }, + { 135.0, 0x22109000 }, + { 157.5, 0x2210b000 }, + { 162.0, 0x2210b000 }, + { 175.5, 0x2210b000 }, + { 189.0, 0x2220e000 }, + { 202.5, 0x2220e000 } +}; + +struct wm_info i810_wm_16_100[] = { + { 0, 0x22004000 }, + { 25.2, 0x22006000 }, + { 28.0, 0x22006000 }, + { 31.5, 0x22007000 }, + { 36.0, 0x22007000 }, + { 40.0, 0x22007000 }, + { 45.0, 0x22007000 }, + { 49.5, 0x22009000 }, + { 50.0, 0x22009000 }, + { 56.3, 0x22108000 }, + { 65.0, 0x2210e000 }, + { 75.0, 0x2210e000 }, + { 78.8, 0x2210e000 }, + { 80.0, 0x22210000 }, + { 94.5, 0x22210000 }, + { 96.0, 0x22210000 }, + { 99.0, 0x22210000 }, + { 108.0, 0x22210000 }, + { 121.0, 0x22210000 }, + { 128.9, 0x22210000 }, + { 132.0, 0x22314000 }, + { 135.0, 0x22314000 }, + { 157.5, 0x22415000 }, + { 162.0, 0x22416000 }, + { 175.5, 0x22416000 }, + { 189.0, 0x22416000 }, + { 195.0, 0x22416000 }, + { 202.5, 0x22416000 } +}; + + +struct wm_info i810_wm_24_100[] = { + { 0, 0x22006000 }, + { 25.2, 0x22009000 }, + { 28.0, 0x22009000 }, + { 31.5, 0x2200a000 }, + { 36.0, 0x2210c000 }, + { 40.0, 0x2210c000 }, + { 45.0, 0x2210c000 }, + { 49.5, 0x22111000 }, + { 50.0, 0x22111000 }, + { 56.3, 0x22111000 }, + { 65.0, 0x22214000 }, + { 75.0, 0x22214000 }, + { 78.8, 0x22215000 }, + { 80.0, 0x22216000 }, + { 94.5, 0x22218000 }, + { 96.0, 0x22418000 }, + { 99.0, 0x22418000 }, + { 108.0, 0x22418000 }, + { 121.0, 0x22418000 }, + { 128.9, 0x22419000 }, + { 132.0, 0x22519000 }, + { 135.0, 0x4441d000 }, + { 157.5, 0x44419000 }, + { 162.0, 0x44419000 }, + { 175.5, 0x44419000 }, + { 189.0, 0x44419000 }, + { 195.0, 0x44419000 }, + { 202.5, 0x44419000 } +}; + +struct wm_info i810_wm_32_100[] = { + { 0, 0x2210b000 }, + { 60, 0x22415000 }, /* 0x314000 works too */ + { 80, 0x22419000 } /* 0x518000 works too */ +}; + + +struct wm_info i810_wm_8_133[] = { + { 0, 0x22003000 }, + { 25.2, 0x22003000 }, + { 28.0, 0x22003000 }, + { 31.5, 0x22003000 }, + { 36.0, 0x22007000 }, + { 40.0, 0x22007000 }, + { 45.0, 0x22007000 }, + { 49.5, 0x22008000 }, + { 50.0, 0x22008000 }, + { 56.3, 0x22008000 }, + { 65.0, 0x22008000 }, + { 75.0, 0x22008000 }, + { 78.8, 0x22008000 }, + { 80.0, 0x22008000 }, + { 94.0, 0x22008000 }, + { 96.0, 0x22107000 }, + { 99.0, 0x22107000 }, + { 108.0, 0x22107000 }, + { 121.0, 0x22107000 }, + { 128.9, 0x22107000 }, + { 132.0, 0x22109000 }, + { 135.0, 0x22109000 }, + { 157.5, 0x2210b000 }, + { 162.0, 0x2210b000 }, + { 175.5, 0x2210b000 }, + { 189.0, 0x2220e000 }, + { 202.5, 0x2220e000 } +}; + + +struct wm_info i810_wm_16_133[] = { + { 0, 0x22004000 }, + { 25.2, 0x22006000 }, + { 28.0, 0x22006000 }, + { 31.5, 0x22007000 }, + { 36.0, 0x22007000 }, + { 40.0, 0x22007000 }, + { 45.0, 0x22007000 }, + { 49.5, 0x22009000 }, + { 50.0, 0x22009000 }, + { 56.3, 0x22108000 }, + { 65.0, 0x2210e000 }, + { 75.0, 0x2210e000 }, + { 78.8, 0x2210e000 }, + { 80.0, 0x22210000 }, + { 94.5, 0x22210000 }, + { 96.0, 0x22210000 }, + { 99.0, 0x22210000 }, + { 108.0, 0x22210000 }, + { 121.0, 0x22210000 }, + { 128.9, 0x22210000 }, + { 132.0, 0x22314000 }, + { 135.0, 0x22314000 }, + { 157.5, 0x22415000 }, + { 162.0, 0x22416000 }, + { 175.5, 0x22416000 }, + { 189.0, 0x22416000 }, + { 195.0, 0x22416000 }, + { 202.5, 0x22416000 } +}; + +struct wm_info i810_wm_24_133[] = { + { 0, 0x22006000 }, + { 25.2, 0x22009000 }, + { 28.0, 0x22009000 }, + { 31.5, 0x2200a000 }, + { 36.0, 0x2210c000 }, + { 40.0, 0x2210c000 }, + { 45.0, 0x2210c000 }, + { 49.5, 0x22111000 }, + { 50.0, 0x22111000 }, + { 56.3, 0x22111000 }, + { 65.0, 0x22214000 }, + { 75.0, 0x22214000 }, + { 78.8, 0x22215000 }, + { 80.0, 0x22216000 }, + { 94.5, 0x22218000 }, + { 96.0, 0x22418000 }, + { 99.0, 0x22418000 }, + { 108.0, 0x22418000 }, + { 121.0, 0x22418000 }, + { 128.9, 0x22419000 }, + { 132.0, 0x22519000 }, + { 135.0, 0x4441d000 }, + { 157.5, 0x44419000 }, + { 162.0, 0x44419000 }, + { 175.5, 0x44419000 }, + { 189.0, 0x44419000 }, + { 195.0, 0x44419000 }, + { 202.5, 0x44419000 } +}; + +static void +i810WriteControlMMIO(I810CardInfo *i810c, int addr, CARD8 index, CARD8 val) { + moutb(addr, index); + moutb(addr+1, val); +} + +static CARD8 +i810ReadControlMMIO(I810CardInfo *i810c, int addr, CARD8 index) { + moutb(addr, index); + return minb(addr+1); +} + +static Bool +i810ModeSupported (KdScreenInfo *screen, const KdMonitorTiming *t) +{ + /* This is just a guess. */ + if (t->horizontal > 1600 || t->horizontal < 640) return FALSE; + if (t->vertical > 1200 || t->horizontal < 350) return FALSE; + return TRUE; +} + +static Bool +i810ModeUsable (KdScreenInfo *screen) +{ + KdCardInfo *card = screen->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + int byte_width, pixel_width, screen_size; + +/* fprintf(stderr,"i810ModeUsable\n"); */ + + if (screen->fb[0].depth >= 24) + { + screen->fb[0].depth = 24; + screen->fb[0].bitsPerPixel = 24; + screen->dumb = TRUE; + } + else if (screen->fb[0].depth >= 16) + { + screen->fb[0].depth = 16; + screen->fb[0].bitsPerPixel = 16; + } + else if (screen->fb[0].depth >= 15) + { + screen->fb[0].depth = 15; + screen->fb[0].bitsPerPixel = 16; + } + else + { + screen->fb[0].depth = 8; + screen->fb[0].bitsPerPixel = 8; + } + byte_width = screen->width * (screen->fb[0].bitsPerPixel >> 3); + pixel_width = screen->width; + + screen->fb[0].pixelStride = pixel_width; + screen->fb[0].byteStride = byte_width; + + screen_size = byte_width * screen->height; + + return screen_size <= (i810c->videoRam * 1024); +} + +static int i810AllocateGARTMemory( KdScreenInfo *screen ) +{ + KdCardInfo *card = screen->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + unsigned long size = i810c->videoRam * 1024; + + int key; + long tom = 0; + unsigned long physical; + + if (!KdAgpGARTSupported()) + return FALSE; + + if (!KdAcquireGART(screen->mynum)) + return FALSE; + + /* This allows the 2d only Xserver to regen */ + i810c->agpAcquired2d = TRUE; + + /* Treat the gart like video memory - we assume we own all that is + * there, so ignore EBUSY errors. Don't try to remove it on + * failure, either, as other X server may be using it. + */ + + if ((key = KdAllocateGARTMemory(screen->mynum, size, 0, NULL)) == -1) + return FALSE; + + i810c->VramOffset = 0; + i810c->VramKey = key; + + if (!KdBindGARTMemory(screen->mynum, key, 0)) + return FALSE; + + + i810c->SysMem.Start = 0; + i810c->SysMem.Size = size; + i810c->SysMem.End = size; + i810c->SavedSysMem = i810c->SysMem; + + tom = i810c->SysMem.End; + + i810c->DcacheMem.Start = 0; + i810c->DcacheMem.End = 0; + i810c->DcacheMem.Size = 0; + i810c->CursorPhysical = 0; + + /* Dcache - half the speed of normal ram, so not really useful for + * a 2d server. Don't bother reporting its presence. This is + * mapped in addition to the requested amount of system ram. + */ + size = 1024 * 4096; + + /* Keep it 512K aligned for the sake of tiled regions. + */ + tom += 0x7ffff; + tom &= ~0x7ffff; + + if ((key = KdAllocateGARTMemory(screen->mynum, size, AGP_DCACHE_MEMORY, NULL)) != -1) { + i810c->DcacheOffset= tom; + i810c->DcacheKey = key; + if (!KdBindGARTMemory(screen->mynum, key, tom)) { + fprintf(stderr,"Allocation of %ld bytes for DCACHE failed\n", size); + i810c->DcacheKey = -1; + } else { + i810c->DcacheMem.Start = tom; + i810c->DcacheMem.Size = size; + i810c->DcacheMem.End = i810c->DcacheMem.Start + i810c->DcacheMem.Size; + tom = i810c->DcacheMem.End; + } + } else { + fprintf(stderr, + "No physical memory available for %ld bytes of DCACHE\n", + size); + i810c->DcacheKey = -1; + } + + /* Mouse cursor -- The i810 (crazy) needs a physical address in + * system memory from which to upload the cursor. We get this from + * the agpgart module using a special memory type. + */ + + /* 4k for the cursor is excessive, I'm going to steal 3k for + * overlay registers later + */ + + size = 4096; + + if ((key = KdAllocateGARTMemory(screen->mynum, size, AGP_PHYS_MEMORY, + &physical)) == -1) { + fprintf(stderr, + "No physical memory available for HW cursor\n"); + i810c->HwcursKey = -1; + } else { + i810c->HwcursOffset= tom; + i810c->HwcursKey = key; + if (!KdBindGARTMemory(screen->mynum, key, tom)) { + fprintf(stderr, + "Allocation of %ld bytes for HW cursor failed\n", + size); + i810c->HwcursKey = -1; + } else { + i810c->CursorPhysical = physical; + i810c->CursorStart = tom; + tom += size; + } + } + + /* Overlay register buffer -- Just like the cursor, the i810 needs a + * physical address in system memory from which to upload the overlay + * registers. + */ + if (i810c->CursorStart != 0) { + i810c->OverlayPhysical = i810c->CursorPhysical + 1024; + i810c->OverlayStart = i810c->CursorStart + 1024; + } + + + i810c->GttBound = 1; + + return TRUE; +} + +/* Allocate from a memrange, returns success */ + +static int i810AllocLow( I810MemRange *result, I810MemRange *pool, int size ) +{ + if (size > pool->Size) return FALSE; + + pool->Size -= size; + result->Size = size; + result->Start = pool->Start; + result->End = pool->Start += size; + return TRUE; +} + +static int i810AllocHigh( I810MemRange *result, I810MemRange *pool, int size ) +{ + if (size > pool->Size) return 0; + + pool->Size -= size; + result->Size = size; + result->End = pool->End; + result->Start = pool->End -= size; + return 1; +} + +static Bool +i810AllocateFront(KdScreenInfo *screen) { + + KdCardInfo *card = screen->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + + int cache_lines = -1; + + if(i810c->DoneFrontAlloc) + return TRUE; + + memset(&(i810c->FbMemBox), 0, sizeof(BoxRec)); + /* Alloc FrontBuffer/Ring/Accel memory */ + i810c->FbMemBox.x1=0; + i810c->FbMemBox.x2=screen->width; + i810c->FbMemBox.y1=0; + i810c->FbMemBox.y2=screen->height; + + /* This could be made a command line option */ + cache_lines = 0; + + if(cache_lines >= 0) + i810c->FbMemBox.y2 += cache_lines; + else { + /* make sure there is enough for two DVD sized YUV buffers */ + i810c->FbMemBox.y2 += (screen->fb[0].depth == 24) ? 256 : 384; + if (screen->width <= 1024) + i810c->FbMemBox.y2 += (screen->fb[0].depth == 24) ? 256 : 384; + cache_lines = i810c->FbMemBox.y2 - screen->height; + } + + if (I810_DEBUG) + ErrorF("Adding %i scanlines for pixmap caching\n", cache_lines); + + /* Reserve room for the framebuffer and pixcache. Put at the top + * of memory so we can have nice alignment for the tiled regions at + * the start of memory. + */ + i810AllocLow( &(i810c->FrontBuffer), + &(i810c->SysMem), + ((i810c->FbMemBox.x2 * + i810c->FbMemBox.y2 * + i810c->cpp) + 4095) & ~4095); + + memset( &(i810c->LpRing), 0, sizeof( I810RingBuffer ) ); + if(i810AllocLow( &(i810c->LpRing.mem), &(i810c->SysMem), 16*4096 )) { + if (I810_DEBUG & DEBUG_VERBOSE_MEMORY) + ErrorF( "ring buffer at local %lx\n", + i810c->LpRing.mem.Start); + + i810c->LpRing.tail_mask = i810c->LpRing.mem.Size - 1; + i810c->LpRing.virtual_start = i810c->FbBase + i810c->LpRing.mem.Start; + i810c->LpRing.head = 0; + i810c->LpRing.tail = 0; + i810c->LpRing.space = 0; + } + + if ( i810AllocLow( &i810c->Scratch, &(i810c->SysMem), 64*1024 ) || + i810AllocLow( &i810c->Scratch, &(i810c->SysMem), 16*1024 ) ) { + if (I810_DEBUG & DEBUG_VERBOSE_MEMORY) + ErrorF("Allocated Scratch Memory\n"); + } + +#ifdef XV + /* 720x720 is just how much memory the mpeg player needs for overlays */ + + if ( i810AllocHigh( &i810c->XvMem, &(i810c->SysMem), 720*720*2 )) { + if (I810_DEBUG & DEBUG_VERBOSE_MEMORY) + ErrorF("Allocated overlay Memory\n"); + } +#endif + + i810c->DoneFrontAlloc = TRUE; + return TRUE; +} + +static Bool +i810MapMem(KdScreenInfo *screen) +{ + + KdCardInfo *card = screen->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + + i810c->LpRing.virtual_start = i810c->FbBase + i810c->LpRing.mem.Start; + + return TRUE; +} + + +Bool +i810ScreenInit (KdScreenInfo *screen) +{ + KdCardInfo *card = screen->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + I810ScreenInfo *i810s; + + int i; + + const KdMonitorTiming *t; + +/* fprintf(stderr,"i810ScreenInit\n"); */ + + i810s = (I810ScreenInfo *) xalloc (sizeof (I810ScreenInfo)); + if (!i810s) + return FALSE; + + memset (i810s, '\0', sizeof (I810ScreenInfo)); + + i810s->i810c = i810c; + + /* Default dimensions */ + if (!screen->width || !screen->height) + { + screen->width = 720; + screen->height = 576; + screen->rate = 52; +#if 0 + screen->width = 1024; + screen->height = 768; + screen->rate = 72; +#endif + } + + if (!screen->fb[0].depth) + screen->fb[0].depth = 16; + + t = KdFindMode (screen, i810ModeSupported); + + screen->rate = t->rate; + screen->width = t->horizontal; + screen->height = t->vertical; + + if (!KdTuneMode (screen, i810ModeUsable, i810ModeSupported)) + { + xfree (i810c); + return FALSE; + } + +/* fprintf(stderr,"Screen rate %d horiz %d vert %d\n",t->rate,t->horizontal,t->vertical); */ + + switch (screen->fb[0].depth) { + case 8: + screen->fb[0].visuals = ((1 << StaticGray) | + (1 << GrayScale) | + (1 << StaticColor) | + (1 << PseudoColor) | + (1 << TrueColor) | + (1 << DirectColor)); + screen->fb[0].blueMask = 0x00; + screen->fb[0].greenMask = 0x00; + screen->fb[0].redMask = 0x00; + break; + case 15: + screen->fb[0].visuals = (1 << TrueColor); + screen->fb[0].blueMask = 0x001f; + screen->fb[0].greenMask = 0x03e0; + screen->fb[0].redMask = 0x7c00; + + i810c->colorKey = 0x043f; + + break; + case 16: + screen->fb[0].visuals = (1 << TrueColor); + screen->fb[0].blueMask = 0x001f; + screen->fb[0].greenMask = 0x07e0; + screen->fb[0].redMask = 0xf800; + + i810c->colorKey = 0x083f; + + break; + case 24: + screen->fb[0].visuals = (1 << TrueColor); + screen->fb[0].blueMask = 0x0000ff; + screen->fb[0].greenMask = 0x00ff00; + screen->fb[0].redMask = 0xff0000; + + i810c->colorKey = 0x0101ff; + + break; + default: + fprintf(stderr,"Unsupported depth %d\n",screen->fb[0].depth); + return FALSE; + } + + + + /* Set all colours to black */ + for (i=0; i<768; i++) i810c->vga.ModeReg.DAC[i] = 0x00; + + /* ... and the overscan */ + if (screen->fb[0].depth >= 4) + i810c->vga.ModeReg.Attribute[OVERSCAN] = 0xFF; + + /* Could be made a command-line option */ + +#ifdef I810CFG_SHOW_OVERSCAN + i810c->vga.ModeReg.DAC[765] = 0x3F; + i810c->vga.ModeReg.DAC[766] = 0x00; + i810c->vga.ModeReg.DAC[767] = 0x3F; + i810c->vga.ModeReg.Attribute[OVERSCAN] = 0xFF; + i810c->vga.ShowOverscan = TRUE; +#else + i810c->vga.ShowOverscan = FALSE; +#endif + + i810c->vga.paletteEnabled = FALSE; + i810c->vga.cmapSaved = FALSE; + i810c->vga.MMIOBase = i810c->MMIOBase; + + i810c->cpp = screen->fb[0].bitsPerPixel/8; + + /* move to initscreen? */ + + switch (screen->fb[0].bitsPerPixel) { + case 8: + i810c->MaxClock = 203000; + break; + case 16: + i810c->MaxClock = 163000; + break; + case 24: + i810c->MaxClock = 136000; + break; + case 32: /* not supported */ + i810c->MaxClock = 86000; + default: + fprintf(stderr,"Unsupported bpp %d\n",screen->fb[0].bitsPerPixel); + return FALSE; + } + + if (!i810AllocateGARTMemory( screen )) { + return FALSE; + } + + i810AllocateFront(screen); + + /* Map LpRing memory */ + if (!i810MapMem(screen)) return FALSE; + + screen->fb[0].frameBuffer = i810c->FbBase; + + screen->driver = i810s; + + return TRUE; +} + +/* + * I810Save -- + * + * This function saves the video state. It reads all of the SVGA registers + * into the vgaI810Rec data structure. There is in general no need to + * mask out bits here - just read the registers. + */ +static void +DoSave(KdCardInfo *card, vgaRegPtr vgaReg, I810RegPtr i810Reg, Bool saveFonts) +{ + + I810CardInfo *i810c = card->driver; + i810VGAPtr vgap = &i810c->vga; + + int i; + + /* Save VGA registers */ + + vgaReg->MiscOutReg = mmioReadMiscOut(vgap); + if (vgaReg->MiscOutReg & 0x01) + vgap->IOBase = VGA_IOBASE_COLOR; + else + vgap->IOBase = VGA_IOBASE_MONO; + + for (i = 0; i < VGA_NUM_CRTC; i++) { + vgaReg->CRTC[i] = mmioReadCrtc(vgap, i); + } + + mmioEnablePalette(vgap); + for (i = 0; i < VGA_NUM_ATTR; i++) { + vgaReg->Attribute[i] = mmioReadAttr(vgap, i); + } + mmioDisablePalette(vgap); + + for (i = 0; i < VGA_NUM_GFX; i++) { + vgaReg->Graphics[i] = mmioReadGr(vgap, i); + } + + for (i = 1; i < VGA_NUM_SEQ; i++) { + vgaReg->Sequencer[i] = mmioReadSeq(vgap, i); + } + + /* + * The port I/O code necessary to read in the extended registers + * into the fields of the I810Rec structure goes here. + */ + i810Reg->IOControl = mmioReadCrtc(vgap, IO_CTNL); + i810Reg->AddressMapping = i810ReadControlMMIO(i810c, GRX, ADDRESS_MAPPING); + i810Reg->BitBLTControl = INREG8(BITBLT_CNTL); + i810Reg->VideoClk2_M = INREG16(VCLK2_VCO_M); + i810Reg->VideoClk2_N = INREG16(VCLK2_VCO_N); + i810Reg->VideoClk2_DivisorSel = INREG8(VCLK2_VCO_DIV_SEL); + + i810Reg->ExtVertTotal=mmioReadCrtc(vgap, EXT_VERT_TOTAL); + i810Reg->ExtVertDispEnd=mmioReadCrtc(vgap, EXT_VERT_DISPLAY); + i810Reg->ExtVertSyncStart=mmioReadCrtc(vgap, EXT_VERT_SYNC_START); + i810Reg->ExtVertBlankStart=mmioReadCrtc(vgap, EXT_VERT_BLANK_START); + i810Reg->ExtHorizTotal=mmioReadCrtc(vgap, EXT_HORIZ_TOTAL); + i810Reg->ExtHorizBlank=mmioReadCrtc(vgap, EXT_HORIZ_BLANK); + i810Reg->ExtOffset=mmioReadCrtc(vgap, EXT_OFFSET); + i810Reg->InterlaceControl=mmioReadCrtc(vgap, INTERLACE_CNTL); + + i810Reg->PixelPipeCfg0 = INREG8(PIXPIPE_CONFIG_0); + i810Reg->PixelPipeCfg1 = INREG8(PIXPIPE_CONFIG_1); + i810Reg->PixelPipeCfg2 = INREG8(PIXPIPE_CONFIG_2); + i810Reg->DisplayControl = INREG8(DISPLAY_CNTL); + i810Reg->LMI_FIFO_Watermark = INREG(FWATER_BLC); + + for (i = 0 ; i < 8 ; i++) + i810Reg->Fence[i] = INREG(FENCE+i*4); + + i810Reg->LprbTail = INREG(LP_RING + RING_TAIL); + i810Reg->LprbHead = INREG(LP_RING + RING_HEAD); + i810Reg->LprbStart = INREG(LP_RING + RING_START); + i810Reg->LprbLen = INREG(LP_RING + RING_LEN); + + if ((i810Reg->LprbTail & TAIL_ADDR) != (i810Reg->LprbHead & HEAD_ADDR) && + i810Reg->LprbLen & RING_VALID) { + i810PrintErrorState( i810c ); + FatalError( "Active ring not flushed\n"); + } + + if (I810_DEBUG) { + fprintf(stderr,"Got mode in I810Save:\n"); + i810PrintMode( vgaReg, i810Reg ); + } +} + +static void +i810Preserve(KdCardInfo *card) +{ + I810CardInfo *i810c = card->driver; + i810VGAPtr vgap = &i810c->vga; + +/* fprintf(stderr,"i810Preserve\n"); */ + DoSave(card, &vgap->SavedReg, &i810c->SavedReg, TRUE); +} + +/* Famous last words + */ +void +i810PrintErrorState(i810CardInfo *i810c) +{ + + fprintf(stderr, "pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n", + INREG(PGETBL_CTL), + INREG(PGE_ERR)); + + fprintf(stderr, "ipeir: %lx iphdr: %lx\n", + INREG(IPEIR), + INREG(IPEHR)); + + fprintf(stderr, "LP ring tail: %lx head: %lx len: %lx start %lx\n", + INREG(LP_RING + RING_TAIL), + INREG(LP_RING + RING_HEAD) & HEAD_ADDR, + INREG(LP_RING + RING_LEN), + INREG(LP_RING + RING_START)); + + fprintf(stderr, "eir: %x esr: %x emr: %x\n", + INREG16(EIR), + INREG16(ESR), + INREG16(EMR)); + + fprintf(stderr, "instdone: %x instpm: %x\n", + INREG16(INST_DONE), + INREG8(INST_PM)); + + fprintf(stderr, "memmode: %lx instps: %lx\n", + INREG(MEMMODE), + INREG(INST_PS)); + + fprintf(stderr, "hwstam: %x ier: %x imr: %x iir: %x\n", + INREG16(HWSTAM), + INREG16(IER), + INREG16(IMR), + INREG16(IIR)); +} + +static Bool +i810BindGARTMemory( KdScreenInfo *screen ) +{ + + KdCardInfo *card = screen->card; + I810CardInfo *i810c = card->driver; + + if (!i810c->GttBound) { + if (!KdAcquireGART(screen->mynum)) + return FALSE; + if (!KdBindGARTMemory(screen->mynum, i810c->VramKey, + i810c->VramOffset)) + + return FALSE; + if (i810c->DcacheKey != -1) { + if (!KdBindGARTMemory(screen->mynum, i810c->DcacheKey, + i810c->DcacheOffset)) + return FALSE; + } + if (i810c->HwcursKey != -1) { + if (!KdBindGARTMemory(screen->mynum, i810c->HwcursKey, + i810c->HwcursOffset)) + return FALSE; + } + i810c->GttBound = 1; + } + return TRUE; +} + +static Bool +i810UnbindGARTMemory(KdScreenInfo *screen) +{ + KdCardInfo *card = screen->card; + I810CardInfo *i810c = card->driver; + + + if (KdAgpGARTSupported() && i810c->GttBound) { + if (!KdUnbindGARTMemory(screen->mynum, i810c->VramKey)) + return FALSE; + if (i810c->DcacheKey != -1) { + if (!KdUnbindGARTMemory(screen->mynum, i810c->DcacheKey)) + return FALSE; + } + if (i810c->HwcursKey != -1) { + if (!KdUnbindGARTMemory(screen->mynum, i810c->HwcursKey)) + return FALSE; + } + if (!KdReleaseGART(screen->mynum)) + return FALSE; + i810c->GttBound = 0; + } + return TRUE; +} + +/* + * I810CalcVCLK -- + * + * Determine the closest clock frequency to the one requested. + */ + +#define MAX_VCO_FREQ 600.0 +#define TARGET_MAX_N 30 +#define REF_FREQ 24.0 + +#define CALC_VCLK(m,n,p) \ + (double)m / ((double)n * (1 << p)) * 4 * REF_FREQ + +static void +i810CalcVCLK( KdScreenInfo *screen, double freq ) +{ + + KdCardInfo *card = screen->card; + I810CardInfo *i810c = card->driver; + I810RegPtr i810Reg = &i810c->ModeReg; + + int m, n, p; + double f_out, f_best; + double f_err; + double f_vco; + int m_best = 0, n_best = 0, p_best = 0; + double f_target = freq; + double err_max = 0.005; + double err_target = 0.001; + double err_best = 999999.0; + + p_best = p = log(MAX_VCO_FREQ/f_target)/log((double)2); + f_vco = f_target * (1 << p); + + n = 2; + do { + n++; + m = f_vco / (REF_FREQ / (double)n) / (double)4.0 + 0.5; + if (m < 3) m = 3; + f_out = CALC_VCLK(m,n,p); + f_err = 1.0 - (f_target/f_out); + if (fabs(f_err) < err_max) { + m_best = m; + n_best = n; + f_best = f_out; + err_best = f_err; + } + } while ((fabs(f_err) >= err_target) && + ((n <= TARGET_MAX_N) || (fabs(err_best) > err_max))); + + if (fabs(f_err) < err_target) { + m_best = m; + n_best = n; + } + + i810Reg->VideoClk2_M = (m_best-2) & 0x3FF; + i810Reg->VideoClk2_N = (n_best-2) & 0x3FF; + i810Reg->VideoClk2_DivisorSel = (p_best << 4); + +/* fprintf(stderr, "Setting dot clock to %.1f MHz " */ +/* "[ 0x%x 0x%x 0x%x ] " */ +/* "[ %d %d %d ]\n", */ +/* CALC_VCLK(m_best,n_best,p_best), */ +/* i810Reg->VideoClk2_M, */ +/* i810Reg->VideoClk2_N, */ +/* i810Reg->VideoClk2_DivisorSel, */ +/* m_best, n_best, p_best); */ +} + +/* + * I810CalcFIFO -- + * + * Calculate burst length and FIFO watermark. + */ + +#define Elements(x) (sizeof(x)/sizeof(*x)) + +static unsigned int +i810CalcWatermark( KdScreenInfo *screen, double freq, Bool dcache ) +{ + + KdCardInfo *card = screen->card; + I810CardInfo *i810c = card->driver; + + + struct wm_info *tab; + int nr; + int i; + + if (i810c->LmFreqSel == 100) { + switch(screen->fb[0].bitsPerPixel) { + case 8: + tab = i810_wm_8_100; + nr = Elements(i810_wm_8_100); + break; + case 16: + tab = i810_wm_16_100; + nr = Elements(i810_wm_16_100); + break; + case 24: + tab = i810_wm_24_100; + nr = Elements(i810_wm_24_100); + break; + default: + return 0; + } + } else { + switch(screen->fb[0].bitsPerPixel) { + case 8: + tab = i810_wm_8_133; + nr = Elements(i810_wm_8_133); + break; + case 16: + tab = i810_wm_16_133; + nr = Elements(i810_wm_16_133); + break; + case 24: + tab = i810_wm_24_133; + nr = Elements(i810_wm_24_133); + break; + default: + return 0; + } + } + + for (i = 0 ; i < nr && tab[i].freq < freq ; i++); + + if (i == nr) + i--; + +/* fprintf(stderr,"chose watermark 0x%x: (tab.freq %.1f)\n", */ +/* tab[i].wm, tab[i].freq); */ + + /* None of these values (sourced from intel) have watermarks for + * the dcache memory. Fake it for now by using the same watermark + * for both... + * + * Update: this is probably because dcache isn't real useful as + * framebuffer memory, so intel's drivers don't need watermarks + * for that memory because they never use it to feed the ramdacs. + * We do use it in the fallback mode, so keep the watermarks for + * now. + */ + if (dcache) + return (tab[i].wm & ~0xffffff) | ((tab[i].wm>>12) & 0xfff); + else + return tab[i].wm; +} + +static void i810PrintMode( vgaRegPtr vgaReg, I810RegPtr mode ) +{ + int i; + + fprintf(stderr," MiscOut: %x\n", vgaReg->MiscOutReg); + + + fprintf(stderr,"SEQ: "); + for (i = 0 ; i < VGA_NUM_SEQ ; i++) { + if ((i&7)==0) fprintf(stderr,"\n"); + fprintf(stderr," %d: %x", i, vgaReg->Sequencer[i]); + } + fprintf(stderr,"\n"); + + fprintf(stderr,"CRTC: "); + for (i = 0 ; i < VGA_NUM_CRTC ; i++) { + if ((i&3)==0) fprintf(stderr,"\n"); + fprintf(stderr," CR%02x: %2x", i, vgaReg->CRTC[i]); + } + fprintf(stderr,"\n"); + + fprintf(stderr,"GFX: "); + for (i = 0 ; i < VGA_NUM_GFX ; i++) { + if ((i&3)==0) fprintf(stderr,"\n"); + fprintf(stderr," GR%02x: %02x", i, vgaReg->Graphics[i]); + } + fprintf(stderr,"\n"); + + fprintf(stderr,"ATTR: "); + for (i = 0 ; i < VGA_NUM_ATTR ; i++) { + if ((i&7)==0) fprintf(stderr,"\n"); + fprintf(stderr," %d: %x", i, vgaReg->Attribute[i]); + } + fprintf(stderr,"\n"); + + + fprintf(stderr," DisplayControl: %x\n", mode->DisplayControl); + fprintf(stderr," PixelPipeCfg0: %x\n", mode->PixelPipeCfg0); + fprintf(stderr," PixelPipeCfg1: %x\n", mode->PixelPipeCfg1); + fprintf(stderr," PixelPipeCfg2: %x\n", mode->PixelPipeCfg2); + fprintf(stderr," VideoClk2_M: %x\n", mode->VideoClk2_M); + fprintf(stderr," VideoClk2_N: %x\n", mode->VideoClk2_N); + fprintf(stderr," VideoClk2_DivisorSel: %x\n", mode->VideoClk2_DivisorSel); + fprintf(stderr," AddressMapping: %x\n", mode->AddressMapping); + fprintf(stderr," IOControl: %x\n", mode->IOControl); + fprintf(stderr," BitBLTControl: %x\n", mode->BitBLTControl); + fprintf(stderr," ExtVertTotal: %x\n", mode->ExtVertTotal); + fprintf(stderr," ExtVertDispEnd: %x\n", mode->ExtVertDispEnd); + fprintf(stderr," ExtVertSyncStart: %x\n", mode->ExtVertSyncStart); + fprintf(stderr," ExtVertBlankStart: %x\n", mode->ExtVertBlankStart); + fprintf(stderr," ExtHorizTotal: %x\n", mode->ExtHorizTotal); + fprintf(stderr," ExtHorizBlank: %x\n", mode->ExtHorizBlank); + fprintf(stderr," ExtOffset: %x\n", mode->ExtOffset); + fprintf(stderr," InterlaceControl: %x\n", mode->InterlaceControl); + fprintf(stderr," LMI_FIFO_Watermark: %x\n", mode->LMI_FIFO_Watermark); + fprintf(stderr," LprbTail: %x\n", mode->LprbTail); + fprintf(stderr," LprbHead: %x\n", mode->LprbHead); + fprintf(stderr," LprbStart: %x\n", mode->LprbStart); + fprintf(stderr," LprbLen: %x\n", mode->LprbLen); + fprintf(stderr," OverlayActiveStart: %x\n", mode->OverlayActiveStart); + fprintf(stderr," OverlayActiveEnd: %x\n", mode->OverlayActiveEnd); +} + + +/* + * i810VGASeqReset + * perform a sequencer reset. + * + * The i815 documentation states that these bits are not used by the + * HW, but still warns about not programming them... + */ + +static void +i810VGASeqReset(i810VGAPtr vgap, Bool start) +{ + if (start) + { + mmioWriteSeq(vgap, 0x00, 0x01); /* Synchronous Reset */ + } + else + { + mmioWriteSeq(vgap, 0x00, 0x03); /* End Reset */ + } +} + +static void +i810VGAProtect(KdCardInfo *card, Bool on) +{ + + I810CardInfo *i810c = card->driver; + i810VGAPtr vgap = &i810c->vga; + + unsigned char tmp; + + if (on) { + /* + * Turn off screen and disable sequencer. + */ + tmp = mmioReadSeq(vgap, 0x01); + + i810VGASeqReset(vgap, TRUE); /* start synchronous reset */ + mmioWriteSeq(vgap, 0x01, tmp | 0x20); /* disable the display */ + + mmioEnablePalette(vgap); + } else { + /* + * Reenable sequencer, then turn on screen. + */ + + tmp = mmioReadSeq(vgap, 0x01); + + mmioWriteSeq(vgap, 0x01, tmp & ~0x20); /* reenable display */ + i810VGASeqReset(vgap, FALSE); /* clear synchronousreset */ + + mmioDisablePalette(vgap); + } +} + +/* + * i810VGABlankScreen -- blank the screen. + */ + +void +i810VGABlankScreen(KdCardInfo *card, Bool on) +{ + I810CardInfo *i810c = card->driver; + i810VGAPtr vgap = &i810c->vga; + + unsigned char scrn; + + scrn = mmioReadSeq(vgap, 0x01); + + if (on) { + scrn &= ~0x20; /* enable screen */ + } else { + scrn |= 0x20; /* blank screen */ + } + + mmioWriteSeq(vgap,0x00,0x01); + mmioWriteSeq(vgap, 0x01, scrn); /* change mode */ + mmioWriteSeq(vgap,0x00,0x03); +} + +/* Restore hardware state */ + +static void +DoRestore(KdCardInfo *card, vgaRegPtr vgaReg, I810RegPtr i810Reg, + Bool restoreFonts) { + + + I810CardInfo *i810c = card->driver; + + i810VGAPtr vgap = &i810c->vga; + + unsigned char temp; + unsigned int itemp; + int i; + + if (I810_DEBUG & DEBUG_VERBOSE_VGA) { + fprintf(stderr,"Setting mode in DoRestore:\n"); + i810PrintMode( vgaReg, i810Reg ); + } + + /* Blank screen (i810vgaprotect) */ + i810VGAProtect(card, TRUE); + + /* Should wait for at least two hsync and no more than two vsync + before writing PIXCONF and turning the display on (?) */ + usleep(50000); + + /* Turn off DRAM Refresh */ + temp = INREG8( DRAM_ROW_CNTL_HI ); + temp &= ~DRAM_REFRESH_RATE; + temp |= DRAM_REFRESH_DISABLE; + OUTREG8( DRAM_ROW_CNTL_HI, temp ); + + usleep(1000); /* Wait 1 ms */ + + /* Write the M, N and P values */ + OUTREG16( VCLK2_VCO_M, i810Reg->VideoClk2_M); + OUTREG16( VCLK2_VCO_N, i810Reg->VideoClk2_N); + OUTREG8( VCLK2_VCO_DIV_SEL, i810Reg->VideoClk2_DivisorSel); + + /* + * Turn on 8 bit dac mode, if requested. This is needed to make + * sure that vgaHWRestore writes the values into the DAC properly. + * The problem occurs if 8 bit dac mode is requested and the HW is + * in 6 bit dac mode. If this happens, all the values are + * automatically shifted left twice by the HW and incorrect colors + * will be displayed on the screen. The only time this can happen + * is at server startup time and when switching back from a VT. + */ + temp = INREG8(PIXPIPE_CONFIG_0); + temp &= 0x7F; /* Save all but the 8 bit dac mode bit */ + temp |= (i810Reg->PixelPipeCfg0 & DAC_8_BIT); + OUTREG8( PIXPIPE_CONFIG_0, temp ); + + /* + * Code to restore any SVGA registers that have been saved/modified + * goes here. Note that it is allowable, and often correct, to + * only modify certain bits in a register by a read/modify/write cycle. + * + * A special case - when using an external clock-setting program, + * this function must not change bits associated with the clock + * selection. This condition can be checked by the condition: + * + * if (i810Reg->std.NoClock >= 0) + * restore clock-select bits. + */ + + /* VGA restore */ + if (vgaReg->MiscOutReg & 0x01) + vgap->IOBase = VGA_IOBASE_COLOR; + else + vgap->IOBase = VGA_IOBASE_MONO; + + mmioWriteMiscOut(vgap, vgaReg->MiscOutReg); + + for (i = 1; i < VGA_NUM_SEQ; i++) + mmioWriteSeq(vgap, i, vgaReg->Sequencer[i]); + + /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */ + /* = CR11 */ + mmioWriteCrtc(vgap, 17, vgaReg->CRTC[17] & ~0x80); + + for (i = 0; i < VGA_NUM_CRTC; i++) { + mmioWriteCrtc(vgap, i, vgaReg->CRTC[i]); + } + + for (i = 0; i < VGA_NUM_GFX; i++) + mmioWriteGr(vgap, i, vgaReg->Graphics[i]); + + mmioEnablePalette(vgap); + for (i = 0; i < VGA_NUM_ATTR; i++) + mmioWriteAttr(vgap, i, vgaReg->Attribute[i]); + mmioDisablePalette(vgap); + + + mmioWriteCrtc(vgap, EXT_VERT_TOTAL, i810Reg->ExtVertTotal); + mmioWriteCrtc(vgap, EXT_VERT_DISPLAY, i810Reg->ExtVertDispEnd); + mmioWriteCrtc(vgap, EXT_VERT_SYNC_START, i810Reg->ExtVertSyncStart); + mmioWriteCrtc(vgap, EXT_VERT_BLANK_START, i810Reg->ExtVertBlankStart); + mmioWriteCrtc(vgap, EXT_HORIZ_TOTAL, i810Reg->ExtHorizTotal); + mmioWriteCrtc(vgap, EXT_HORIZ_BLANK, i810Reg->ExtHorizBlank); + + /* write CR40, CR42 first etc to get CR13 written as described in PRM */ + + mmioWriteCrtc(vgap, EXT_START_ADDR_HI, 0); + mmioWriteCrtc(vgap, EXT_START_ADDR, EXT_START_ADDR_ENABLE); + + mmioWriteCrtc(vgap, EXT_OFFSET, i810Reg->ExtOffset); + mmioWriteCrtc(vgap, 0x13, vgaReg->CRTC[0x13]); + + temp=mmioReadCrtc(vgap, INTERLACE_CNTL); + temp &= ~INTERLACE_ENABLE; + temp |= i810Reg->InterlaceControl; + mmioWriteCrtc(vgap, INTERLACE_CNTL, temp); + + temp=i810ReadControlMMIO(i810c, GRX, ADDRESS_MAPPING); + temp &= 0xE0; /* Save reserved bits 7:5 */ + temp |= i810Reg->AddressMapping; + i810WriteControlMMIO(i810c, GRX, ADDRESS_MAPPING, temp); + + /* Setting the OVRACT Register for video overlay*/ + OUTREG(0x6001C, (i810Reg->OverlayActiveEnd << 16) | i810Reg->OverlayActiveStart); + + /* Turn on DRAM Refresh */ + temp = INREG8( DRAM_ROW_CNTL_HI ); + temp &= ~DRAM_REFRESH_RATE; + temp |= DRAM_REFRESH_60HZ; + OUTREG8( DRAM_ROW_CNTL_HI, temp ); + + temp = INREG8( BITBLT_CNTL ); + temp &= ~COLEXP_MODE; + temp |= i810Reg->BitBLTControl; + OUTREG8( BITBLT_CNTL, temp ); + + temp = INREG8( DISPLAY_CNTL ); + temp &= ~(VGA_WRAP_MODE | GUI_MODE); + temp |= i810Reg->DisplayControl; + OUTREG8( DISPLAY_CNTL, temp ); + + + temp = INREG8( PIXPIPE_CONFIG_0 ); + temp &= 0x64; /* Save reserved bits 6:5,2 */ + temp |= i810Reg->PixelPipeCfg0; + OUTREG8( PIXPIPE_CONFIG_0, temp ); + + temp = INREG8( PIXPIPE_CONFIG_2 ); + temp &= 0xF3; /* Save reserved bits 7:4,1:0 */ + temp |= i810Reg->PixelPipeCfg2; + OUTREG8( PIXPIPE_CONFIG_2, temp ); + + temp = INREG8( PIXPIPE_CONFIG_1 ); + temp &= ~DISPLAY_COLOR_MODE; + temp &= 0xEF; /* Restore the CRT control bit */ + temp |= i810Reg->PixelPipeCfg1; + OUTREG8( PIXPIPE_CONFIG_1, temp ); + + OUTREG16(EIR, 0); + + itemp = INREG(FWATER_BLC); + itemp &= ~(LM_BURST_LENGTH | LM_FIFO_WATERMARK | + MM_BURST_LENGTH | MM_FIFO_WATERMARK ); + itemp |= i810Reg->LMI_FIFO_Watermark; + OUTREG(FWATER_BLC, itemp); + + + for (i = 0 ; i < 8 ; i++) { + OUTREG( FENCE+i*4, i810Reg->Fence[i] ); + if (I810_DEBUG & DEBUG_VERBOSE_VGA) + fprintf(stderr,"Fence Register : %x\n", i810Reg->Fence[i]); + } + + /* First disable the ring buffer (Need to wait for empty first?, if so + * should probably do it before entering this section) + */ + itemp = INREG(LP_RING + RING_LEN); + itemp &= ~RING_VALID_MASK; + OUTREG(LP_RING + RING_LEN, itemp ); + + /* Set up the low priority ring buffer. + */ + OUTREG(LP_RING + RING_TAIL, 0 ); + OUTREG(LP_RING + RING_HEAD, 0 ); + + i810c->LpRing.head = 0; + i810c->LpRing.tail = 0; + + itemp = INREG(LP_RING + RING_START); + itemp &= ~(START_ADDR); + itemp |= i810Reg->LprbStart; + OUTREG(LP_RING + RING_START, itemp ); + + itemp = INREG(LP_RING + RING_LEN); + itemp &= ~(RING_NR_PAGES | RING_REPORT_MASK | RING_VALID_MASK); + itemp |= i810Reg->LprbLen; + OUTREG(LP_RING + RING_LEN, itemp ); + + i810VGAProtect(card, FALSE); + + temp=mmioReadCrtc(vgap, IO_CTNL); + temp &= ~(EXTENDED_ATTR_CNTL | EXTENDED_CRTC_CNTL); + temp |= i810Reg->IOControl; + mmioWriteCrtc(vgap, IO_CTNL, temp); + /* Protect CRTC[0-7] */ + mmioWriteCrtc(vgap, 0x11, mmioReadCrtc(vgap, 0x11) | 0x80); +} + + +static Bool +i810SetMode(KdScreenInfo *screen, const KdMonitorTiming *t) +{ + + KdCardInfo *card = screen->card; + I810CardInfo *i810c = card->driver; + i810VGAPtr vgap = &i810c->vga; + + I810RegPtr i810Reg = &i810c->ModeReg; + vgaRegPtr pVga = &vgap->ModeReg; + + double dclk = t->clock/1000.0; + + switch (screen->fb[0].bitsPerPixel) { + case 8: + pVga->CRTC[0x13] = screen->width >> 3; + i810Reg->ExtOffset = screen->width >> 11; + i810Reg->PixelPipeCfg1 = DISPLAY_8BPP_MODE; + i810Reg->BitBLTControl = COLEXP_8BPP; + break; + case 16: + i810Reg->PixelPipeCfg1 = DISPLAY_16BPP_MODE; + pVga->CRTC[0x13] = screen->width >> 2; + i810Reg->ExtOffset = screen->width >> 10; + i810Reg->BitBLTControl = COLEXP_16BPP; + break; + case 24: + pVga->CRTC[0x13] = (screen->width * 3) >> 3; + i810Reg->ExtOffset = (screen->width * 3) >> 11; + + i810Reg->PixelPipeCfg1 = DISPLAY_24BPP_MODE; + i810Reg->BitBLTControl = COLEXP_24BPP; + break; + default: + break; + } + + i810Reg->PixelPipeCfg0 = DAC_8_BIT; + + /* Do not delay CRT Blank: needed for video overlay */ + i810Reg->PixelPipeCfg1 |= 0x10; + + /* Turn on Extended VGA Interpretation */ + i810Reg->IOControl = EXTENDED_CRTC_CNTL; + + /* Turn on linear and page mapping */ + i810Reg->AddressMapping = (LINEAR_MODE_ENABLE | + GTT_MEM_MAP_ENABLE); + + /* Turn on GUI mode */ + i810Reg->DisplayControl = HIRES_MODE; + + i810Reg->OverlayActiveStart = t->horizontal + t->hblank - 32; + i810Reg->OverlayActiveEnd = t->horizontal - 32; + + /* Turn on interlaced mode if necessary (it's not) */ + i810Reg->InterlaceControl = INTERLACE_DISABLE; + + /* + * Set the overscan color to 0. + * NOTE: This only affects >8bpp mode. + */ + pVga->Attribute[0x11] = 0; + + /* + * Calculate the VCLK that most closely matches the requested dot + * clock. + */ + i810CalcVCLK(screen, dclk); + + /* Since we program the clocks ourselves, always use VCLK2. */ + pVga->MiscOutReg |= 0x0C; + + /* Calculate the FIFO Watermark and Burst Length. */ + i810Reg->LMI_FIFO_Watermark = i810CalcWatermark(screen, dclk, FALSE); + + /* Setup the ring buffer */ + i810Reg->LprbTail = 0; + i810Reg->LprbHead = 0; + i810Reg->LprbStart = i810c->LpRing.mem.Start; + + if (i810Reg->LprbStart) + i810Reg->LprbLen = ((i810c->LpRing.mem.Size-4096) | + RING_NO_REPORT | RING_VALID); + else + i810Reg->LprbLen = RING_INVALID; + + return TRUE; +} + +static Bool +i810ModeInit(KdScreenInfo *screen, const KdMonitorTiming *t) +{ + + KdCardInfo *card = screen->card; + I810CardInfo *i810c = card->driver; + i810VGAPtr vgap = &i810c->vga; + vgaRegPtr pVga; + +/* fprintf(stderr,"i810ModeInit\n"); */ + + i810VGAUnlock(vgap); + + if (!i810VGAInit(screen, t)) return FALSE; + pVga = &vgap->ModeReg; + + if (!i810SetMode(screen, t)) return FALSE; + + DoRestore(screen->card, &vgap->ModeReg, &i810c->ModeReg, FALSE); + + return TRUE; +} + +Bool +i810VGAInit(KdScreenInfo *screen, const KdMonitorTiming *t) +{ + unsigned int i; + + int hactive, hblank, hbp, hfp; + int vactive, vblank, vbp, vfp; + int h_screen_off = 0, h_adjust = 0, h_total, h_display_end, h_blank_start; + int h_blank_end, h_sync_start, h_sync_end, v_total, v_retrace_start; + int v_retrace_end, v_display_end, v_blank_start, v_blank_end; + + KdCardInfo *card = screen->card; + I810CardInfo *i810c = card->driver; + + i810VGAPtr vgap = &i810c->vga; + I810RegPtr ireg = &i810c->ModeReg; + + + vgaRegPtr regp; + int depth = screen->fb[0].depth; + + regp = &vgap->ModeReg; + + /* + * compute correct Hsync & Vsync polarity + */ + + regp->MiscOutReg = 0x23; + if (t->vpol == KdSyncNegative) regp->MiscOutReg |= 0x40; + if (t->hpol == KdSyncNegative) regp->MiscOutReg |= 0x80; + + /* + * Time Sequencer + */ + if (depth == 4) + regp->Sequencer[0] = 0x02; + else + regp->Sequencer[0] = 0x00; + /* No support for 320 or 360 x resolution */ + regp->Sequencer[1] = 0x01; + + if (depth == 1) + regp->Sequencer[2] = 1 << BIT_PLANE; + else + regp->Sequencer[2] = 0x0F; + + regp->Sequencer[3] = 0x00; /* Font select */ + + if (depth < 8) + regp->Sequencer[4] = 0x06; /* Misc */ + else + regp->Sequencer[4] = 0x0E; /* Misc */ + + hactive = t->horizontal; + hblank = t->hblank; + hbp = t->hbp; + hfp = t->hfp; + + vactive = t->vertical; + vblank = t->vblank; + vbp = t->vbp; + vfp = t->vfp; + + switch (screen->fb[0].bitsPerPixel) { + case 8: + hactive /= 8; + hblank /= 8; + hfp /= 8; + hbp /= 8; + h_screen_off = hactive; + h_adjust = 1; + break; + case 16: + hactive /= 8; + hblank /= 8; + hfp /= 8; + hbp /= 8; + + h_screen_off = hactive * 2; + h_adjust = 1; + break; + case 24: + hactive /= 8; + hblank /= 8; + hfp /= 8; + hbp /= 8; + + h_screen_off = hactive * 3; + h_adjust = 1; + break; + case 32: + hactive /= 8; + hblank /= 8; + hfp /= 8; + hbp /= 8; + + h_screen_off = hactive * 4; + h_adjust = 1; + break; + } + + /* + * Compute horizontal register values from timings + */ + h_total = hactive + hblank - 5; + h_display_end = hactive - 1; + h_blank_start = h_display_end; + h_blank_end = h_blank_start + hblank; + + h_sync_start = hactive + hfp + h_adjust; + h_sync_end = h_sync_start + hblank - hbp - hfp; + + /* Set CRTC regs for horizontal timings */ + regp->CRTC[0x0] = h_total; + ireg->ExtHorizTotal=(h_total & 0x100) >> 8; + + regp->CRTC[0x1] = h_display_end; + + regp->CRTC[0x2] = h_blank_start; + + regp->CRTC[0x3] = 0x80 | (h_blank_end & 0x1f); + regp->CRTC[0x5] = (h_blank_end & 0x20) << 2; + + regp->CRTC[0x4] = h_sync_start; + + regp->CRTC[0x5] |= h_sync_end & 0x1f; + + regp->CRTC[0x13] = h_screen_off; + ireg->ExtOffset = h_screen_off >> 8; + + /* Compute vertical timings */ + v_total = vactive + vblank - 2; + v_retrace_start = vactive + vfp - 1; + v_retrace_end = v_retrace_start + vblank - vbp - vfp; + v_display_end = vactive - 1; + v_blank_start = vactive - 1; + v_blank_end = v_blank_start + vblank /* - 1 */; + + regp->CRTC[0x6] = v_total; + ireg->ExtVertTotal = v_total >> 8; + + regp->CRTC[0x10] = v_retrace_start; + ireg->ExtVertSyncStart = v_retrace_start >> 8; + + regp->CRTC[0x11] = v_retrace_end; + + regp->CRTC[0x12] = v_display_end; + ireg->ExtVertDispEnd = v_display_end >> 8; + + regp->CRTC[0x15] = v_blank_start; + ireg->ExtVertBlankStart = v_blank_start >> 8; + + regp->CRTC[0x16] = v_blank_end; + + if (depth < 8) + regp->CRTC[23] = 0xE3; + else + regp->CRTC[23] = 0xC3; + regp->CRTC[24] = 0xFF; + + /* + * Graphics Display Controller + */ + regp->Graphics[0] = 0x00; + regp->Graphics[1] = 0x00; + regp->Graphics[2] = 0x00; + regp->Graphics[3] = 0x00; + if (depth == 1) { + regp->Graphics[4] = BIT_PLANE; + regp->Graphics[5] = 0x00; + } else { + regp->Graphics[4] = 0x00; + if (depth == 4) + regp->Graphics[5] = 0x02; + else + regp->Graphics[5] = 0x40; + } + regp->Graphics[6] = 0x05; + regp->Graphics[7] = 0x0F; + regp->Graphics[8] = 0xFF; + + if (depth == 1) { + /* Initialise the Mono map according to which bit-plane gets used */ + + Bool flipPixels = FALSE; /* maybe support this in the future? */ + + for (i=0; i<16; i++) + if (((i & (1 << BIT_PLANE)) != 0) != flipPixels) + regp->Attribute[i] = WHITE_VALUE; + else + regp->Attribute[i] = BLACK_VALUE; + + regp->Attribute[16] = 0x01; /* -VGA2- */ + if (!vgap->ShowOverscan) + regp->Attribute[OVERSCAN] = OVERSCAN_VALUE; /* -VGA2- */ + } else { + regp->Attribute[0] = 0x00; /* standard colormap translation */ + regp->Attribute[1] = 0x01; + regp->Attribute[2] = 0x02; + regp->Attribute[3] = 0x03; + regp->Attribute[4] = 0x04; + regp->Attribute[5] = 0x05; + regp->Attribute[6] = 0x06; + regp->Attribute[7] = 0x07; + regp->Attribute[8] = 0x08; + regp->Attribute[9] = 0x09; + regp->Attribute[10] = 0x0A; + regp->Attribute[11] = 0x0B; + regp->Attribute[12] = 0x0C; + regp->Attribute[13] = 0x0D; + regp->Attribute[14] = 0x0E; + regp->Attribute[15] = 0x0F; + if (depth == 4) + regp->Attribute[16] = 0x81; + else + regp->Attribute[16] = 0x41; + /* Attribute[17] (overscan) was initialised earlier */ + } + regp->Attribute[18] = 0x0F; + regp->Attribute[19] = 0x00; + regp->Attribute[20] = 0x00; + + return(TRUE); +} + +void +i810VGALock(i810VGAPtr vgap) +{ + /* Protect CRTC[0-7] */ + mmioWriteCrtc(vgap, 0x11, mmioReadCrtc(vgap, 0x11) & ~0x80); +} + +void +i810VGAUnlock(i810VGAPtr vgap) +{ + /* Unprotect CRTC[0-7] */ + mmioWriteCrtc(vgap, 0x11, mmioReadCrtc(vgap, 0x11) | 0x80); +} + +static void +i810Restore(KdCardInfo *card) { + + I810CardInfo *i810c = card->driver; + + i810VGAPtr vgap = &i810c->vga; + + if (I810_DEBUG) + fprintf(stderr,"i810Restore\n"); + + DoRestore(card, &vgap->SavedReg, &i810c->SavedReg, TRUE); +} + +static Bool +i810Enable (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + KdCardInfo *card = pScreenPriv->card; + I810CardInfo *i810c = card->driver; + i810VGAPtr vgap = &i810c->vga; + const KdMonitorTiming *t; + + if (I810_DEBUG) + fprintf(stderr,"i810Enable\n"); + + vgap->IOBase = (mmioReadMiscOut(vgap) & 0x01) ? + VGA_IOBASE_COLOR : VGA_IOBASE_MONO; + + { + I810RegPtr i810Reg = &i810c->ModeReg; + int i; + + for (i = 0 ; i < 8 ; i++) + i810Reg->Fence[i] = 0; + } + + t = KdFindMode (screen, i810ModeSupported); + + if (!i810BindGARTMemory(screen)) + return FALSE; + + if (!i810ModeInit(screen, t)) return FALSE; + + { + /* DPMS power on state */ + + unsigned char SEQ01=0; + int DPMSSyncSelect=0; + + SEQ01 = 0x00; + DPMSSyncSelect = HSYNC_ON | VSYNC_ON; + + SEQ01 |= i810ReadControlMMIO(i810c, SRX, 0x01) & ~0x20; + i810WriteControlMMIO(i810c, SRX, 0x01, SEQ01); + + /* Set the DPMS mode */ + OUTREG8(DPMS_SYNC_SELECT, DPMSSyncSelect); + } +#ifdef XV + KdXVEnable (pScreen); +#endif + return TRUE; +} + + +static void +i810Disable(ScreenPtr pScreen) { + + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + KdCardInfo *card = pScreenPriv->card; + I810CardInfo *i810c = card->driver; + + i810VGAPtr vgap = &i810c->vga; + + if (I810_DEBUG) + fprintf(stderr,"i810Disable\n"); + +#ifdef XV + KdXVDisable (pScreen); +#endif + i810Restore(screen->card); + + if (!i810UnbindGARTMemory(screen)) + return; + + i810VGALock(vgap); +} + + +static Bool +i810DPMS(ScreenPtr pScreen, int mode) +{ + KdScreenPriv(pScreen); + KdCardInfo *card = pScreenPriv->card; + I810CardInfo *i810c = card->driver; + + unsigned char SEQ01=0; + int DPMSSyncSelect=0; + + if (I810_DEBUG) + fprintf(stderr,"i810DPMS: %d\n",mode); + + switch (mode) { + case KD_DPMS_NORMAL: + /* Screen: On; HSync: On, VSync: On */ + SEQ01 = 0x00; + DPMSSyncSelect = HSYNC_ON | VSYNC_ON; + break; + case KD_DPMS_STANDBY: + /* Screen: Off; HSync: Off, VSync: On */ + SEQ01 = 0x20; + DPMSSyncSelect = HSYNC_OFF | VSYNC_ON; + break; + case KD_DPMS_SUSPEND: + /* Screen: Off; HSync: On, VSync: Off */ + SEQ01 = 0x20; + DPMSSyncSelect = HSYNC_ON | VSYNC_OFF; + break; + case KD_DPMS_POWERDOWN: + /* Screen: Off; HSync: Off, VSync: Off */ + SEQ01 = 0x20; + DPMSSyncSelect = HSYNC_OFF | VSYNC_OFF; + break; + } + + /* Turn the screen on/off */ + SEQ01 |= i810ReadControlMMIO(i810c, SRX, 0x01) & ~0x20; + i810WriteControlMMIO(i810c, SRX, 0x01, SEQ01); + + /* Set the DPMS mode */ + OUTREG8(DPMS_SYNC_SELECT, DPMSSyncSelect); + return TRUE; +} + + +static void +i810GetColors (ScreenPtr pScreen, int fb, int ndefs, xColorItem *c) +{ + + if (I810_DEBUG) + fprintf(stderr,"i810GetColors (NOT IMPLEMENTED)\n"); +} + +#define DACDelay(hw) \ + do { \ + unsigned char temp = Vminb((hw)->IOBase + VGA_IN_STAT_1_OFFSET); \ + temp = Vminb((hw)->IOBase + VGA_IN_STAT_1_OFFSET); \ + } while (0) + +static void +i810PutColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs) +{ + + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + KdCardInfo *card = screen->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + + i810VGAPtr vgap = &i810c->vga; + + if (I810_DEBUG) + fprintf(stderr,"i810PutColors\n"); + + while (ndef--) + { + mmioWriteDacWriteAddr(vgap, pdefs->pixel); + DACDelay(vgap); + mmioWriteDacData(vgap, pdefs->red); + DACDelay(vgap); + mmioWriteDacData(vgap, pdefs->green); + DACDelay(vgap); + mmioWriteDacData(vgap, pdefs->blue); + DACDelay(vgap); + + pdefs++; + } +} + + +KdCardFuncs i810Funcs = { + i810CardInit, /* cardinit */ + i810ScreenInit, /* scrinit */ + i810InitScreen, /* initScreen */ + i810FinishInitScreen, /* finishInitScreen */ + NULL, /* createResources */ + i810Preserve, /* preserve */ + i810Enable, /* enable */ + i810DPMS, /* dpms */ + i810Disable, /* disable */ + i810Restore, /* restore */ + i810ScreenFini, /* scrfini */ + i810CardFini, /* cardfini */ + + i810CursorInit, /* initCursor */ + i810CursorEnable, /* enableCursor */ + i810CursorDisable, /* disableCursor */ + i810CursorFini, /* finiCursor */ + NULL, /* recolorCursor */ + + i810InitAccel, /* initAccel */ + i810EnableAccel, /* enableAccel */ + i810DisableAccel, /* disableAccel */ + i810FiniAccel, /* finiAccel */ + + i810GetColors, /* getColors */ + i810PutColors, /* putColors */ +}; diff --git a/xorg-server/hw/kdrive/i810/i810.h b/xorg-server/hw/kdrive/i810/i810.h new file mode 100644 index 000000000..8fc2d56be --- /dev/null +++ b/xorg-server/hw/kdrive/i810/i810.h @@ -0,0 +1,511 @@ +/* COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 2000, 2001 Nokia Home Communications + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. + +X Window System is a trademark of The Open Group */ + +/* + * Author: + * Pontus Lidman <pontus.lidman@nokia.com> + */ + +#ifndef _I810_H_ +#define _I810_H_ + +#include "i810_reg.h" + +/* Globals */ + +typedef struct _I810Rec *I810Ptr; + +/* Linear region allocated in framebuffer. + */ +typedef struct { + unsigned long Start; + unsigned long End; + unsigned long Size; +} I810MemRange; + +typedef struct { + int tail_mask; + I810MemRange mem; + unsigned char *virtual_start; + int head; + int tail; + int space; +} I810RingBuffer; + +typedef struct { + unsigned char DisplayControl; + unsigned char PixelPipeCfg0; + unsigned char PixelPipeCfg1; + unsigned char PixelPipeCfg2; + unsigned short VideoClk2_M; + unsigned short VideoClk2_N; + unsigned char VideoClk2_DivisorSel; + unsigned char AddressMapping; + unsigned char IOControl; + unsigned char BitBLTControl; + unsigned char ExtVertTotal; + unsigned char ExtVertDispEnd; + unsigned char ExtVertSyncStart; + unsigned char ExtVertBlankStart; + unsigned char ExtHorizTotal; + unsigned char ExtHorizBlank; + unsigned char ExtOffset; + unsigned char InterlaceControl; + unsigned int LMI_FIFO_Watermark; + + unsigned int LprbTail; + unsigned int LprbHead; + unsigned int LprbStart; + unsigned int LprbLen; + + unsigned int Fence[8]; + + unsigned short OverlayActiveStart; + unsigned short OverlayActiveEnd; + + +} I810RegRec, *I810RegPtr; + +#define minb(p) *(volatile CARD8 *)(i810c->MMIOBase + (p)) +#define moutb(p,v) *(volatile CARD8 *)(i810c->MMIOBase + (p)) = (v) + +#define OUT_RING(n) { \ + if (I810_DEBUG & DEBUG_VERBOSE_RING) \ + ErrorF( "OUT_RING %x: %x\n", outring, n); \ + *(volatile unsigned int *)(virt + outring) = n; \ + outring += 4; \ + outring &= ringmask; \ +} + +#define ADVANCE_LP_RING() { \ + i810c->LpRing.tail = outring; \ + OUTREG(LP_RING + RING_TAIL, outring); \ +} + +#ifdef __GNUC__ +#define LP_RING_MESSAGE(n) \ + ErrorF("BEGIN_LP_RING %d in %s\n", n, __FUNCTION__) +#else +#define LP_RING_MESSAGE(n) \ + ErrorF("BEGIN_LP_RING %d in %s:%d\n", n, __FILE__, __LINE__) +#endif + +#define LP_RING_LOCALS \ + unsigned int outring, ringmask; \ + volatile unsigned char *virt + +#define BEGIN_LP_RING(n) \ + if (n>2 && (I810_DEBUG&DEBUG_ALWAYS_SYNC)) \ + i810Sync(i810s); \ + if (i810c->LpRing.space < n*4) i810WaitLpRing(i810s, n*4, 0); \ + i810c->LpRing.space -= n*4; \ + if (I810_DEBUG & DEBUG_VERBOSE_RING) \ + LP_RING_MESSAGE(n); \ + outring = i810c->LpRing.tail; \ + ringmask = i810c->LpRing.tail_mask; \ + virt = i810c->LpRing.virtual_start; + +/* Memory mapped register access macros */ +#define INREG8(addr) *(volatile CARD8 *)(i810c->MMIOBase + (addr)) +#define INREG16(addr) *(volatile CARD16 *)(i810c->MMIOBase + (addr)) +#define INREG(addr) *(volatile CARD32 *)(i810c->MMIOBase + (addr)) + +#define OUTREG8(addr, val) do { \ + *(volatile CARD8 *)(i810c->MMIOBase + (addr)) = (val); \ + if (I810_DEBUG&DEBUG_VERBOSE_OUTREG) \ + ErrorF( "OUTREG8(%x, %x)\n", addr, val); \ +} while (0) + +#define OUTREG16(addr, val) do { \ + *(volatile CARD16 *)(i810c->MMIOBase + (addr)) = (val); \ + if (I810_DEBUG&DEBUG_VERBOSE_OUTREG) \ + ErrorF( "OUTREG16(%x, %x)\n", addr, val); \ +} while (0) + +#define OUTREG(addr, val) do { \ + *(volatile CARD32 *)(i810c->MMIOBase + (addr)) = (val); \ + if (I810_DEBUG&DEBUG_VERBOSE_OUTREG) \ + ErrorF( "OUTREG(%x, %x)\n", addr, val); \ +} while (0) + +/* To remove all debugging, make sure I810_DEBUG is defined as a + * preprocessor symbol, and equal to zero. + */ + +#define I810_DEBUG 0 + +#ifndef I810_DEBUG +#warning "Debugging enabled - expect reduced performance" +extern int I810_DEBUG; +#endif + +#define DEBUG_VERBOSE_ACCEL 0x1 +#define DEBUG_VERBOSE_SYNC 0x2 +#define DEBUG_VERBOSE_VGA 0x4 +#define DEBUG_VERBOSE_RING 0x8 +#define DEBUG_VERBOSE_OUTREG 0x10 +#define DEBUG_VERBOSE_MEMORY 0x20 +#define DEBUG_VERBOSE_CURSOR 0x40 +#define DEBUG_ALWAYS_SYNC 0x80 +#define DEBUG_VERBOSE_DRI 0x100 + + +/* Size of the mmio region. + */ +#define I810_REG_SIZE 0x80000 + +/* PCI identifiers */ +#ifndef PCI_CHIP_I810 +#define PCI_CHIP_I810 0x7121 +#define PCI_CHIP_I810_DC100 0x7123 +#define PCI_CHIP_I810_E 0x7125 +#define PCI_CHIP_I815 0x1132 +#define PCI_CHIP_I810_BRIDGE 0x7120 +#define PCI_CHIP_I810_DC100_BRIDGE 0x7122 +#define PCI_CHIP_I810_E_BRIDGE 0x7124 +#define PCI_CHIP_I815_BRIDGE 0x1130 +#define PCI_CHIP_I845G 0x2562 +#endif + + +#define IS_I810(i810c) (i810c->PciInfo->chipType == PCI_CHIP_I810 || \ + i810c->PciInfo->chipType == PCI_CHIP_I810_DC100 || \ + i810c->PciInfo->chipType == PCI_CHIP_I810_E) +#define IS_I815(i810c) (i810c->PciInfo->chipType == PCI_CHIP_I815) + + +/* default number of VGA registers stored internally */ +#define VGA_NUM_CRTC 25 /* 0x19 */ +#define VGA_NUM_SEQ 5 +#define VGA_NUM_GFX 9 +#define VGA_NUM_ATTR 21 + +/* + * Settings of standard VGA registers. + */ +typedef struct { + unsigned char MiscOutReg; /* */ + unsigned char CRTC[VGA_NUM_CRTC]; /* Crtc Controller */ + unsigned char Sequencer[VGA_NUM_SEQ]; /* Video Sequencer */ + unsigned char Graphics[VGA_NUM_GFX]; /* Video Graphics */ + unsigned char Attribute[VGA_NUM_ATTR]; /* Video Atribute */ + unsigned char DAC[768]; /* Internal Colorlookuptable */ +} vgaRegRec, *vgaRegPtr; + + +typedef struct _i810VGARec *i810VGAPtr; + +/* VGA registers */ +typedef struct _i810VGARec { + int IOBase; /* I/O Base address */ + CARD8 * MMIOBase; /* Pointer to MMIO start */ + vgaRegRec SavedReg; /* saved registers */ + vgaRegRec ModeReg; /* register settings for + current mode */ + Bool ShowOverscan; + Bool paletteEnabled; + Bool cmapSaved; +} i810VGARec; + +typedef struct _i810CardInfo { + int videoRam; + int MaxClock; + long FbMapSize; + int cpp; /* chars per pixel */ + + unsigned long LinearAddr; + unsigned long MMIOAddr; + + unsigned char *MMIOBase; + unsigned char *FbBase; + + Bool GttBound; + Bool agpAcquired2d; + int VramKey; + unsigned long VramOffset; + int DcacheKey; + unsigned long DcacheOffset; + int HwcursKey; + unsigned long HwcursOffset; + + I810MemRange DcacheMem; + I810MemRange SysMem; + + I810MemRange SavedDcacheMem; + I810MemRange SavedSysMem; + + unsigned int bufferOffset; /* for I810SelectBuffer */ + Bool DoneFrontAlloc; + BoxRec FbMemBox; + I810MemRange FrontBuffer; + I810MemRange Scratch; + I810MemRange XvMem; + + int LmFreqSel; + + i810VGARec vga; + + I810RegRec SavedReg; + I810RegRec ModeReg; + I810RingBuffer LpRing; + + unsigned int BR[20]; + + int CursorOffset; + unsigned long CursorPhysical; + unsigned long CursorStart; + unsigned long OverlayPhysical; + unsigned long OverlayStart; + int colorKey; + + int nextColorExpandBuf; + + ScreenBlockHandlerProcPtr BlockHandler; + +#ifdef XV + KdVideoAdaptorPtr adaptor; +#endif + +} i810CardInfo; + +typedef struct _i810CardInfo I810CardInfo; /* compatibility */ + +#define getI810CardInfo(kd) ((I810CardInfo *) ((kd)->card->driver)) +#define i810CardInfo(kd) I810CardInfo *i810c = getI810CardInfo(kd) + +#define getI810ScreenInfo(kd) ((I810ScreenInfo *) ((kd)->screen->driver)) +#define i810ScreenInfo(kd) I810ScreenInfo *i810s = getI810ScreenInfo(kd) + +typedef struct _i810Cursor { + int width, height; + int xhot, yhot; + Bool has_cursor; + CursorPtr pCursor; +} i810Cursor, *i810CursorPtr; + +typedef struct _i810ScreenInfo { + i810CardInfo *i810c; + i810Cursor cursor; + + int pitch; + KaaScreenInfoRec kaa; +} i810ScreenInfo; + +typedef struct _i810ScreenInfo I810ScreenInfo; /* compatibility */ + +#define I810_CURSOR_HEIGHT 64 +#define I810_CURSOR_WIDTH 64 + +/* init functions (i810.c) */ + +Bool +i810CardInit (KdCardInfo *card); + +Bool +i810ScreenInit (KdScreenInfo *screen); + +/* The cursor functions (i810_cursor.c) */ + +Bool +i810CursorInit(ScreenPtr pScreen); + +void +i810CursorEnable (ScreenPtr pScreen); + +void +i810CursorDisable (ScreenPtr pScreen); + +void +i810CursorFini (ScreenPtr pScreen); + +/* Accel functions (i810draw.c) */ + +Bool +i810InitAccel(ScreenPtr); + +void +i810EnableAccel (ScreenPtr); + +void +i810DisableAccel (ScreenPtr); + +void +i810FiniAccel (ScreenPtr); + +void +i810FillBoxSolid (KdScreenInfo *screen, int nBox, BoxPtr pBox, + unsigned long pixel, int alu, unsigned long planemask); + + +extern KdCardFuncs i810Funcs; + +/* Standard VGA registers */ + +#define VGA_ATTR_INDEX 0x3C0 +#define VGA_ATTR_DATA_W 0x3C0 +#define VGA_ATTR_DATA_R 0x3C1 +#define VGA_IN_STAT_0 0x3C2 /* read */ +#define VGA_MISC_OUT_W 0x3C2 /* write */ +#define VGA_ENABLE 0x3C3 +#define VGA_SEQ_INDEX 0x3C4 +#define VGA_SEQ_DATA 0x3C5 +#define VGA_DAC_MASK 0x3C6 +#define VGA_DAC_READ_ADDR 0x3C7 +#define VGA_DAC_WRITE_ADDR 0x3C8 +#define VGA_DAC_DATA 0x3C9 +#define VGA_FEATURE_R 0x3CA /* read */ +#define VGA_MISC_OUT_R 0x3CC /* read */ +#define VGA_GRAPH_INDEX 0x3CE +#define VGA_GRAPH_DATA 0x3CF + +#define VGA_IOBASE_MONO 0x3B0 +#define VGA_IOBASE_COLOR 0x3D0 + +#define VGA_CRTC_INDEX_OFFSET 0x04 +#define VGA_CRTC_DATA_OFFSET 0x05 +#define VGA_IN_STAT_1_OFFSET 0x0A /* read */ +#define VGA_FEATURE_W_OFFSET 0x0A /* write */ + +/* VGA stuff */ +#define BIT_PLANE 3 /* Which plane we write to in mono mode */ + +/* DAC indices for white and black */ +#define WHITE_VALUE 0x3F +#define BLACK_VALUE 0x00 +#define OVERSCAN_VALUE 0x01 + +#define OVERSCAN 0x11 /* Index of OverScan register */ + +void +i810VGAUnlock(i810VGAPtr vgap); + +void +i810VGALock(i810VGAPtr vgap); + +Bool +i810VGAInit(KdScreenInfo *scrninfp, const KdMonitorTiming *t); + +void +i810VGABlankScreen(KdCardInfo *card, Bool on); + +void +i810AdjustFrame(KdScreenInfo *screen, int x, int y, int flags); + +Bool +i810VGAMapMem(KdCardInfo *card); + +void +i810VGASave(KdCardInfo *card, vgaRegPtr save, int flags); + +void +i810PrintErrorState(i810CardInfo *i810c); + +void +i810VGAGetIOBase(i810VGAPtr vgap); + +Bool +i810InitVideo(ScreenPtr pScreen); + +/* + * MMIO versions of the register access functions. These require + * hwp->MemBase to be set in such a way that when the standard VGA port + * address is added the correct memory address results. + */ + +#define Vminb(p) ( *(volatile CARD8 *)(vgap->MMIOBase + (p))) +#define Vmoutb(p,v) ( *(volatile CARD8 *)(vgap->MMIOBase + (p)) = (v)) + +#define mmioWriteCrtc(vgap, index, value) { \ + Vmoutb(vgap->IOBase + VGA_CRTC_INDEX_OFFSET, index); \ + Vmoutb(vgap->IOBase + VGA_CRTC_DATA_OFFSET, value); \ +} + +#define mmioReadCrtc(vgap, index) ( \ + Vmoutb(vgap->IOBase + VGA_CRTC_INDEX_OFFSET, index), \ + Vminb(vgap->IOBase + VGA_CRTC_DATA_OFFSET) \ +) + +#define mmioWriteGr(vgap, index, value) { \ + Vmoutb(VGA_GRAPH_INDEX, index); \ + Vmoutb(VGA_GRAPH_DATA, value); \ +} + +#define mmioReadGr(vgap, index) ( \ + Vmoutb(VGA_GRAPH_INDEX, index), \ + Vminb(VGA_GRAPH_DATA) \ +) + +#define mmioWriteSeq(vgap, index, value) {\ + Vmoutb(VGA_SEQ_INDEX, index); \ + Vmoutb(VGA_SEQ_DATA, value); \ +} + +#define mmioReadSeq(vgap, index) ( \ + Vmoutb(VGA_SEQ_INDEX, index), \ + Vminb(VGA_SEQ_DATA) \ +) + +#define mmioWriteAttr(vgap, index, value) { \ + (void) Vminb(vgap->IOBase + VGA_IN_STAT_1_OFFSET); \ + Vmoutb(VGA_ATTR_INDEX, index); \ + Vmoutb(VGA_ATTR_DATA_W, value); \ +} + +#define mmioReadAttr(vgap, index) ( \ + (void) Vminb(vgap->IOBase + VGA_IN_STAT_1_OFFSET), \ + Vmoutb(VGA_ATTR_INDEX, index), \ + Vminb(VGA_ATTR_DATA_R) \ +) + +#define mmioWriteMiscOut(vgap, value) Vmoutb(VGA_MISC_OUT_W, value) + + +#define mmioReadMiscOut(vgap) Vminb(VGA_MISC_OUT_R) + +#define mmioEnablePalette(vgap) { \ + (void) Vminb(vgap->IOBase + VGA_IN_STAT_1_OFFSET); \ + Vmoutb(VGA_ATTR_INDEX, 0x00); \ + vgap->paletteEnabled = TRUE; \ +} + +#define mmioDisablePalette(vgap) { \ + (void) Vminb(vgap->IOBase + VGA_IN_STAT_1_OFFSET); \ + Vmoutb(VGA_ATTR_INDEX, 0x20); \ + vgap->paletteEnabled = FALSE; \ +} + +#define mmioWriteDacWriteAddr(vgap, value) Vmoutb(VGA_DAC_WRITE_ADDR, value) + +#define mmioWriteDacData(vgap, value) Vmoutb(VGA_DAC_DATA, value) + +#endif /* _I810_H_ */ diff --git a/xorg-server/hw/kdrive/i810/i810_cursor.c b/xorg-server/hw/kdrive/i810/i810_cursor.c new file mode 100644 index 000000000..434fc4087 --- /dev/null +++ b/xorg-server/hw/kdrive/i810/i810_cursor.c @@ -0,0 +1,435 @@ +/* COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 2000, 2001 Nokia Home Communications + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. + +X Window System is a trademark of The Open Group */ + +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, 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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* i810_cursor.c: KDrive hardware cursor routines for the i810 chipset */ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * Pontus Lidman <pontus.lidman@nokia.com> + * + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" +#include "kxv.h" +#include "i810.h" +#include "cursorstr.h" + +#define SetupCursor(s) KdScreenPriv(pScreen); \ + i810CardInfo(pScreenPriv); \ + i810ScreenInfo(pScreenPriv); \ + i810Cursor *pCurPriv = &i810s->cursor + + +static void +writeStandardMMIO(I810CardInfo *i810c, int addr, CARD8 val) +{ + moutb(addr, val); +} + +static void +_i810MoveCursor(ScreenPtr pScreen, int x, int y) +{ + KdScreenPriv(pScreen); + i810CardInfo(pScreenPriv); + int flag; + + if (I810_DEBUG & DEBUG_VERBOSE_CURSOR) + ErrorF( "I810SetCursorPosition %d %d\n", x, y); + + x += i810c->CursorOffset; + + if (x >= 0) flag = CURSOR_X_POS; + else { + flag = CURSOR_X_NEG; + x=-x; + } + + OUTREG8( CURSOR_X_LO, x&0xFF); + OUTREG8( CURSOR_X_HI, (((x >> 8) & 0x07) | flag)); + + if (y >= 0) flag = CURSOR_Y_POS; + else { + flag = CURSOR_Y_NEG; + y=-y; + } + OUTREG8( CURSOR_Y_LO, y&0xFF); + OUTREG8( CURSOR_Y_HI, (((y >> 8) & 0x07) | flag)); + + /* Enable cursor */ + OUTREG( CURSOR_BASEADDR, i810c->CursorPhysical); + OUTREG8( CURSOR_CONTROL, CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C); + +} + +static void i810LoadCursor(ScreenPtr pScreen, int x, int y); + +static void +i810MoveCursor (ScreenPtr pScreen, int x, int y) +{ + KdScreenPriv(pScreen); + i810ScreenInfo(pScreenPriv); + i810Cursor *pCurPriv = &i810s->cursor; + + if (!pCurPriv->has_cursor) + return; + + if (!pScreenPriv->enabled) + return; + + _i810MoveCursor (pScreen, x, y); + + i810LoadCursor(pScreen, x, y); +} + +static void +_i810SetCursorColors(ScreenPtr pScreen) +{ + + KdScreenPriv(pScreen); + i810CardInfo(pScreenPriv); + int tmp; + + int bg = 0xffffff; + int fg = 0x000000; + + tmp=INREG8(PIXPIPE_CONFIG_0); + tmp |= EXTENDED_PALETTE; + OUTREG8( PIXPIPE_CONFIG_0, tmp); + + writeStandardMMIO(i810c, DACMASK, 0xFF); + writeStandardMMIO(i810c, DACWX, 0x04); + + writeStandardMMIO(i810c, DACDATA, (bg & 0x00FF0000) >> 16); + writeStandardMMIO(i810c, DACDATA, (bg & 0x0000FF00) >> 8); + writeStandardMMIO(i810c, DACDATA, (bg & 0x000000FF)); + + writeStandardMMIO(i810c, DACDATA, (fg & 0x00FF0000) >> 16); + writeStandardMMIO(i810c, DACDATA, (fg & 0x0000FF00) >> 8); + writeStandardMMIO(i810c, DACDATA, (fg & 0x000000FF)); + + tmp=INREG8( PIXPIPE_CONFIG_0 ); + tmp &= ~EXTENDED_PALETTE; + OUTREG8( PIXPIPE_CONFIG_0, tmp ); +} + +#define InvertBits32(v) { \ + v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \ + v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \ + v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \ +} + +static void i810LoadCursor(ScreenPtr pScreen, int x, int y) +{ + SetupCursor(pScreen); + + int h; + unsigned int *msk, *mskLine, *src, *srcLine; + + int i, j; + int src_stride, src_width; + + CursorPtr pCursor = pCurPriv->pCursor; + CursorBitsPtr bits = pCursor->bits; + CARD8 tmp; + unsigned int *ram, *ramLine; + + pCurPriv->pCursor = pCursor; + pCurPriv->xhot = pCursor->bits->xhot; + pCurPriv->yhot = pCursor->bits->yhot; + + ramLine = (unsigned int *) (i810c->FbBase + i810c->CursorStart); + mskLine = (unsigned int *) (bits->mask); + srcLine = (unsigned int *) (bits->source); + + h = bits->height; + if (h > I810_CURSOR_HEIGHT) + h = I810_CURSOR_HEIGHT; + + src_stride = BitmapBytePad(bits->width); /* bytes per line */ + src_stride = (src_stride +3) >> 2; + src_width = (bits->width + 31) >> 5; + + for (i = 0; i < I810_CURSOR_HEIGHT; i++) { + + msk = mskLine; + src = srcLine; + ram = ramLine; + mskLine += src_stride; + srcLine += src_stride; + ramLine += I810_CURSOR_WIDTH / 16; + + for (j = 0; j < I810_CURSOR_WIDTH / 32; j++) { + + unsigned long m, s; + + if (i < h && j < src_width) + { + m = *msk++; + s = *src++ & m; + m = ~m; + /* mask off right side */ + if (j == src_width - 1 && (bits->width & 31)) + { + m |= 0xffffffff << (bits->width & 31); + } + } + else + { + m = 0xffffffff; + s = 0x00000000; + } + + InvertBits32(s); + InvertBits32(m); + + ram[2+j]=s; + ram[0+j]=m; + } + } + /* Set new color */ + _i810SetCursorColors (pScreen); + + /* Move to new position */ + _i810MoveCursor (pScreen, x, y); + + /* Enable cursor */ + OUTREG( CURSOR_BASEADDR, i810c->CursorPhysical); + OUTREG8( CURSOR_CONTROL, CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C); + + tmp = INREG8( PIXPIPE_CONFIG_0 ); + tmp |= HW_CURSOR_ENABLE; + OUTREG8( PIXPIPE_CONFIG_0, tmp); +} + +static void +i810UnloadCursor(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + i810CardInfo(pScreenPriv); + + unsigned char tmp; + + tmp=INREG8( PIXPIPE_CONFIG_0 ); + tmp &= ~HW_CURSOR_ENABLE; + OUTREG8( PIXPIPE_CONFIG_0, tmp); +} + + +static Bool +i810RealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) +{ + KdScreenPriv(pScreen); + i810ScreenInfo(pScreenPriv); + i810Cursor *pCurPriv = &i810s->cursor; + + if (!pScreenPriv->enabled) + return TRUE; + + /* miRecolorCursor does this */ + if (pCurPriv->pCursor == pCursor) + { + if (pCursor) + { + int x, y; + + miPointerPosition (&x, &y); + i810LoadCursor (pScreen, x, y); + } + } + return TRUE; +} + +static Bool +i810UnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) +{ + return TRUE; +} + +static void +i810SetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y) +{ + KdScreenPriv(pScreen); + i810ScreenInfo(pScreenPriv); + i810Cursor *pCurPriv = &i810s->cursor; + + pCurPriv->pCursor = pCursor; + + if (!pScreenPriv->enabled) + return; + + if (pCursor) + i810LoadCursor (pScreen, x, y); + else + i810UnloadCursor (pScreen); +} + +miPointerSpriteFuncRec i810PointerSpriteFuncs = { + i810RealizeCursor, + i810UnrealizeCursor, + i810SetCursor, + i810MoveCursor, +}; + +static void +i810QueryBestSize (int class, + unsigned short *pwidth, unsigned short *pheight, + ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + i810ScreenInfo(pScreenPriv); + i810Cursor *pCurPriv = &i810s->cursor; + + switch (class) + { + case CursorShape: + if (*pwidth > pCurPriv->width) + *pwidth = pCurPriv->width; + if (*pheight > pCurPriv->height) + *pheight = pCurPriv->height; + if (*pwidth > pScreen->width) + *pwidth = pScreen->width; + if (*pheight > pScreen->height) + *pheight = pScreen->height; + break; + default: + fbQueryBestSize (class, pwidth, pheight, pScreen); + break; + } +} + +Bool +i810CursorInit(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + i810ScreenInfo(pScreenPriv); + i810CardInfo(pScreenPriv); + i810Cursor *pCurPriv = &i810s->cursor; + + if (!i810c->CursorStart) { + pCurPriv->has_cursor = FALSE; + return FALSE; + } + + pCurPriv->width = I810_CURSOR_WIDTH; + pCurPriv->height= I810_CURSOR_HEIGHT; + pScreen->QueryBestSize = i810QueryBestSize; + miPointerInitialize (pScreen, + &i810PointerSpriteFuncs, + &kdPointerScreenFuncs, + FALSE); + pCurPriv->has_cursor = TRUE; + pCurPriv->pCursor = NULL; + return TRUE; +} + +void +i810CursorEnable (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + i810ScreenInfo(pScreenPriv); + i810Cursor *pCurPriv = &i810s->cursor; + + if (pCurPriv->has_cursor) + { + if (pCurPriv->pCursor) + { + int x, y; + + miPointerPosition (&x, &y); + i810LoadCursor (pScreen, x, y); + } + else + i810UnloadCursor (pScreen); + } +} + +void +i810CursorDisable (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + i810ScreenInfo(pScreenPriv); + i810Cursor *pCurPriv = &i810s->cursor; + + if (!pScreenPriv->enabled) + return; + + if (pCurPriv->has_cursor) + { + if (pCurPriv->pCursor) + { + i810UnloadCursor (pScreen); + } + } +} + +void +i810CursorFini (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + i810ScreenInfo(pScreenPriv); + i810Cursor *pCurPriv = &i810s->cursor; + + pCurPriv->pCursor = NULL; +} + diff --git a/xorg-server/hw/kdrive/i810/i810_reg.h b/xorg-server/hw/kdrive/i810/i810_reg.h new file mode 100644 index 000000000..d9f4c8f48 --- /dev/null +++ b/xorg-server/hw/kdrive/i810/i810_reg.h @@ -0,0 +1,695 @@ +/* COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 2000, 2001 Nokia Home Communications + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. + +X Window System is a trademark of The Open Group */ + +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, 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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * Pontus Lidman <pontus.lidman@nokia.com> + * + * based on the i740 driver by + * Kevin E. Martin <kevin@precisioninsight.com> + * + * + */ + +/* I/O register offsets + */ +#define SRX 0x3C4 /* p208 */ +#define GRX 0x3CE /* p213 */ +#define ARX 0x3C0 /* p224 */ + +/* VGA Color Palette Registers */ +#define DACMASK 0x3C6 /* p232 */ +#define DACSTATE 0x3C7 /* p232 */ +#define DACRX 0x3C7 /* p233 */ +#define DACWX 0x3C8 /* p233 */ +#define DACDATA 0x3C9 /* p233 */ + +/* CRT Controller Registers (CRX) */ +#define START_ADDR_HI 0x0C /* p246 */ +#define START_ADDR_LO 0x0D /* p247 */ +#define VERT_SYNC_END 0x11 /* p249 */ +#define EXT_VERT_TOTAL 0x30 /* p257 */ +#define EXT_VERT_DISPLAY 0x31 /* p258 */ +#define EXT_VERT_SYNC_START 0x32 /* p259 */ +#define EXT_VERT_BLANK_START 0x33 /* p260 */ +#define EXT_HORIZ_TOTAL 0x35 /* p261 */ +#define EXT_HORIZ_BLANK 0x39 /* p261 */ +#define EXT_START_ADDR 0x40 /* p262 */ +#define EXT_START_ADDR_ENABLE 0x80 +#define EXT_OFFSET 0x41 /* p263 */ +#define EXT_START_ADDR_HI 0x42 /* p263 */ +#define INTERLACE_CNTL 0x70 /* p264 */ +#define INTERLACE_ENABLE 0x80 +#define INTERLACE_DISABLE 0x00 + +/* Miscellaneous Output Register + */ +#define MSR_R 0x3CC /* p207 */ +#define MSR_W 0x3C2 /* p207 */ +#define IO_ADDR_SELECT 0x01 + +#define MDA_BASE 0x3B0 /* p207 */ +#define CGA_BASE 0x3D0 /* p207 */ + +/* CR80 - IO Control, p264 + */ +#define IO_CTNL 0x80 +#define EXTENDED_ATTR_CNTL 0x02 +#define EXTENDED_CRTC_CNTL 0x01 + +/* GR10 - Address mapping, p221 + */ +#define ADDRESS_MAPPING 0x10 +#define PAGE_TO_LOCAL_MEM_ENABLE 0x10 +#define GTT_MEM_MAP_ENABLE 0x08 +#define PACKED_MODE_ENABLE 0x04 +#define LINEAR_MODE_ENABLE 0x02 +#define PAGE_MAPPING_ENABLE 0x01 + +/* Blitter control, p378 + */ +#define BITBLT_CNTL 0x7000c +#define COLEXP_MODE 0x30 +#define COLEXP_8BPP 0x00 +#define COLEXP_16BPP 0x10 +#define COLEXP_24BPP 0x20 +#define COLEXP_RESERVED 0x30 +#define BITBLT_STATUS 0x01 + +/* p375. + */ +#define DISPLAY_CNTL 0x70008 +#define VGA_WRAP_MODE 0x02 +#define VGA_WRAP_AT_256KB 0x00 +#define VGA_NO_WRAP 0x02 +#define GUI_MODE 0x01 +#define STANDARD_VGA_MODE 0x00 +#define HIRES_MODE 0x01 + +/* p375 + */ +#define PIXPIPE_CONFIG_0 0x70009 +#define DAC_8_BIT 0x80 +#define DAC_6_BIT 0x00 +#define HW_CURSOR_ENABLE 0x10 +#define EXTENDED_PALETTE 0x01 + +/* p375 + */ +#define PIXPIPE_CONFIG_1 0x7000a +#define DISPLAY_COLOR_MODE 0x0F +#define DISPLAY_VGA_MODE 0x00 +#define DISPLAY_8BPP_MODE 0x02 +#define DISPLAY_15BPP_MODE 0x04 +#define DISPLAY_16BPP_MODE 0x05 +#define DISPLAY_24BPP_MODE 0x06 +#define DISPLAY_32BPP_MODE 0x07 + +/* p375 + */ +#define PIXPIPE_CONFIG_2 0x7000b +#define DISPLAY_GAMMA_ENABLE 0x08 +#define DISPLAY_GAMMA_DISABLE 0x00 +#define OVERLAY_GAMMA_ENABLE 0x04 +#define OVERLAY_GAMMA_DISABLE 0x00 + + +/* p380 + */ +#define DISPLAY_BASE 0x70020 +#define DISPLAY_BASE_MASK 0x03fffffc + + +/* Cursor control registers, pp383-384 + */ +#define CURSOR_CONTROL 0x70080 +#define CURSOR_ORIGIN_SCREEN 0x00 +#define CURSOR_ORIGIN_DISPLAY 0x10 +#define CURSOR_MODE 0x07 +#define CURSOR_MODE_DISABLE 0x00 +#define CURSOR_MODE_32_4C_AX 0x01 +#define CURSOR_MODE_64_3C 0x04 +#define CURSOR_MODE_64_4C_AX 0x05 +#define CURSOR_MODE_64_4C 0x06 +#define CURSOR_MODE_RESERVED 0x07 +#define CURSOR_BASEADDR 0x70084 +#define CURSOR_BASEADDR_MASK 0x1FFFFF00 +#define CURSOR_X_LO 0x70088 +#define CURSOR_X_HI 0x70089 +#define CURSOR_X_POS 0x00 +#define CURSOR_X_NEG 0x80 +#define CURSOR_Y_LO 0x7008A +#define CURSOR_Y_HI 0x7008B +#define CURSOR_Y_POS 0x00 +#define CURSOR_Y_NEG 0x80 + + + +/* Similar registers exist in Device 0 on the i810 (pp55-65), but I'm + * not sure they refer to local (graphics) memory. + * + * These details are for the local memory control registers, + * (pp301-310). The test machines are not equiped with local memory, + * so nothing is tested. Only a single row seems to be supported. + */ +#define DRAM_ROW_TYPE 0x3000 +#define DRAM_ROW_0 0x01 +#define DRAM_ROW_0_SDRAM 0x01 +#define DRAM_ROW_0_EMPTY 0x00 +#define DRAM_ROW_CNTL_LO 0x3001 +#define DRAM_PAGE_MODE_CTRL 0x10 +#define DRAM_RAS_TO_CAS_OVRIDE 0x08 +#define DRAM_CAS_LATENCY 0x04 +#define DRAM_RAS_TIMING 0x02 +#define DRAM_RAS_PRECHARGE 0x01 +#define DRAM_ROW_CNTL_HI 0x3002 +#define DRAM_REFRESH_RATE 0x18 +#define DRAM_REFRESH_DISABLE 0x00 +#define DRAM_REFRESH_60HZ 0x08 +#define DRAM_REFRESH_FAST_TEST 0x10 +#define DRAM_REFRESH_RESERVED 0x18 +#define DRAM_SMS 0x07 +#define DRAM_SMS_NORMAL 0x00 +#define DRAM_SMS_NOP_ENABLE 0x01 +#define DRAM_SMS_ABPCE 0x02 +#define DRAM_SMS_MRCE 0x03 +#define DRAM_SMS_CBRCE 0x04 + +/* p307 + */ +#define DPMS_SYNC_SELECT 0x5002 +#define VSYNC_CNTL 0x08 +#define VSYNC_ON 0x00 +#define VSYNC_OFF 0x08 +#define HSYNC_CNTL 0x02 +#define HSYNC_ON 0x00 +#define HSYNC_OFF 0x02 + + + +/* p317, 319 + */ +#define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */ +#define VCLK2_VCO_N 0x600a +#define VCLK2_VCO_DIV_SEL 0x6012 +#define POST_DIV_SELECT 0x70 +#define POST_DIV_1 0x00 +#define POST_DIV_2 0x10 +#define POST_DIV_4 0x20 +#define POST_DIV_8 0x30 +#define POST_DIV_16 0x40 +#define POST_DIV_32 0x50 +#define VCO_LOOP_DIV_BY_4M 0x00 +#define VCO_LOOP_DIV_BY_16M 0x04 + + +/* Instruction Parser Mode Register + * - p281 + * - 2 new bits. + */ +#define INST_PM 0x20c0 +#define AGP_SYNC_PACKET_FLUSH_ENABLE 0x20 /* reserved */ +#define SYNC_PACKET_FLUSH_ENABLE 0x10 +#define TWO_D_INST_DISABLE 0x08 +#define THREE_D_INST_DISABLE 0x04 +#define STATE_VAR_UPDATE_DISABLE 0x02 +#define PAL_STIP_DISABLE 0x01 + +#define INST_DONE 0x2090 +#define INST_PS 0x20c4 + +#define MEMMODE 0x20dc + + +/* Instruction parser error register. p279 + */ +#define IPEIR 0x2088 +#define IPEHR 0x208C + + +/* General error reporting regs, p296 + */ +#define EIR 0x20B0 +#define EMR 0x20B4 +#define ESR 0x20B8 +#define IP_ERR 0x0001 +#define ERROR_RESERVED 0xffc6 + + +/* Interrupt Control Registers + * - new bits for i810 + * - new register hwstam (mask) + */ +#define HWSTAM 0x2098 /* p290 */ +#define IER 0x20a0 /* p291 */ +#define IIR 0x20a4 /* p292 */ +#define IMR 0x20a8 /* p293 */ +#define ISR 0x20ac /* p294 */ +#define HW_ERROR 0x8000 +#define SYNC_STATUS_TOGGLE 0x1000 +#define DPY_0_FLIP_PENDING 0x0800 +#define DPY_1_FLIP_PENDING 0x0400 /* not implemented on i810 */ +#define OVL_0_FLIP_PENDING 0x0200 +#define OVL_1_FLIP_PENDING 0x0100 /* not implemented on i810 */ +#define DPY_0_VBLANK 0x0080 +#define DPY_0_EVENT 0x0040 +#define DPY_1_VBLANK 0x0020 /* not implemented on i810 */ +#define DPY_1_EVENT 0x0010 /* not implemented on i810 */ +#define HOST_PORT_EVENT 0x0008 /* */ +#define CAPTURE_EVENT 0x0004 /* */ +#define USER_DEFINED 0x0002 +#define BREAKPOINT 0x0001 + + +#define INTR_RESERVED (0x6000 | \ + DPY_1_FLIP_PENDING | \ + OVL_1_FLIP_PENDING | \ + DPY_1_VBLANK | \ + DPY_1_EVENT | \ + HOST_PORT_EVENT | \ + CAPTURE_EVENT ) + +/* FIFO Watermark and Burst Length Control Register + * + * - different offset and contents on i810 (p299) (fewer bits per field) + * - some overlay fields added + * - what does it all mean? + */ +#define FWATER_BLC 0x20d8 +#define MM_BURST_LENGTH 0x00700000 +#define MM_FIFO_WATERMARK 0x0001F000 +#define LM_BURST_LENGTH 0x00000700 +#define LM_FIFO_WATERMARK 0x0000001F + + +/* Fence/Tiling ranges [0..7] + */ +#define FENCE 0x2000 +#define FENCE_NR 8 + +#define FENCE_START_MASK 0x03F80000 +#define FENCE_X_MAJOR 0x00000000 +#define FENCE_Y_MAJOR 0x00001000 +#define FENCE_SIZE_MASK 0x00000700 +#define FENCE_SIZE_512K 0x00000000 +#define FENCE_SIZE_1M 0x00000100 +#define FENCE_SIZE_2M 0x00000200 +#define FENCE_SIZE_4M 0x00000300 +#define FENCE_SIZE_8M 0x00000400 +#define FENCE_SIZE_16M 0x00000500 +#define FENCE_SIZE_32M 0x00000600 +#define FENCE_PITCH_MASK 0x00000070 +#define FENCE_PITCH_1 0x00000000 +#define FENCE_PITCH_2 0x00000010 +#define FENCE_PITCH_4 0x00000020 +#define FENCE_PITCH_8 0x00000030 +#define FENCE_PITCH_16 0x00000040 +#define FENCE_PITCH_32 0x00000050 +#define FENCE_VALID 0x00000001 + + +/* Registers to control page table, p274 + */ +#define PGETBL_CTL 0x2020 +#define PGETBL_ADDR_MASK 0xFFFFF000 +#define PGETBL_ENABLE_MASK 0x00000001 +#define PGETBL_ENABLED 0x00000001 + +/* Register containing pge table error results, p276 + */ +#define PGE_ERR 0x2024 +#define PGE_ERR_ADDR_MASK 0xFFFFF000 +#define PGE_ERR_ID_MASK 0x00000038 +#define PGE_ERR_CAPTURE 0x00000000 +#define PGE_ERR_OVERLAY 0x00000008 +#define PGE_ERR_DISPLAY 0x00000010 +#define PGE_ERR_HOST 0x00000018 +#define PGE_ERR_RENDER 0x00000020 +#define PGE_ERR_BLITTER 0x00000028 +#define PGE_ERR_MAPPING 0x00000030 +#define PGE_ERR_CMD_PARSER 0x00000038 +#define PGE_ERR_TYPE_MASK 0x00000007 +#define PGE_ERR_INV_TABLE 0x00000000 +#define PGE_ERR_INV_PTE 0x00000001 +#define PGE_ERR_MIXED_TYPES 0x00000002 +#define PGE_ERR_PAGE_MISS 0x00000003 +#define PGE_ERR_ILLEGAL_TRX 0x00000004 +#define PGE_ERR_LOCAL_MEM 0x00000005 +#define PGE_ERR_TILED 0x00000006 + + + +/* Page table entries loaded via mmio region, p323 + */ +#define PTE_BASE 0x10000 +#define PTE_ADDR_MASK 0x3FFFF000 +#define PTE_TYPE_MASK 0x00000006 +#define PTE_LOCAL 0x00000002 +#define PTE_MAIN_UNCACHED 0x00000000 +#define PTE_MAIN_CACHED 0x00000006 +#define PTE_VALID_MASK 0x00000001 +#define PTE_VALID 0x00000001 + + +/* Ring buffer registers, p277, overview p19 + */ +#define LP_RING 0x2030 +#define HP_RING 0x2040 + +#define RING_TAIL 0x00 +#define TAIL_ADDR 0x000FFFF8 + +#define RING_HEAD 0x04 +#define HEAD_WRAP_COUNT 0xFFE00000 +#define HEAD_WRAP_ONE 0x00200000 +#define HEAD_ADDR 0x001FFFFC + +#define RING_START 0x08 +#define START_ADDR 0x00FFFFF8 + +#define RING_LEN 0x0C +#define RING_NR_PAGES 0x000FF000 +#define RING_REPORT_MASK 0x00000006 +#define RING_REPORT_64K 0x00000002 +#define RING_REPORT_128K 0x00000004 +#define RING_NO_REPORT 0x00000000 +#define RING_VALID_MASK 0x00000001 +#define RING_VALID 0x00000001 +#define RING_INVALID 0x00000000 + + + +/* BitBlt Instructions + * + * There are many more masks & ranges yet to add. + */ +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR00_OP_FULL_BLT 0x11400000 +#define BR00_OP_MONO_SRC_BLT 0x11800000 +#define BR00_OP_MONO_SRC_COPY_BLT 0x11000000 +#define BR00_OP_MONO_PAT_BLT 0x11C00000 +#define BR00_OP_MONO_SRC_COPY_IMMEDIATE_BLT (0x61 << 22) +#define BR00_OP_TEXT_IMMEDIATE_BLT 0xc000000 + + +#define BR00_TPCY_DISABLE 0x00000000 +#define BR00_TPCY_ENABLE 0x00000010 + +#define BR00_TPCY_ROP 0x00000000 +#define BR00_TPCY_NO_ROP 0x00000020 +#define BR00_TPCY_EQ 0x00000000 +#define BR00_TPCY_NOT_EQ 0x00000040 + +#define BR00_PAT_MSB_FIRST 0x00000000 /* ? */ + +#define BR00_PAT_VERT_ALIGN 0x000000e0 + +#define BR00_LENGTH 0x0000000F + +#define BR09_DEST_ADDR 0x03FFFFFF + +#define BR11_SOURCE_PITCH 0x00003FFF + +#define BR12_SOURCE_ADDR 0x03FFFFFF + +#define BR13_SOLID_PATTERN 0x80000000 +#define BR13_RIGHT_TO_LEFT 0x40000000 +#define BR13_LEFT_TO_RIGHT 0x00000000 +#define BR13_MONO_TRANSPCY 0x20000000 +#define BR13_USE_DYN_DEPTH 0x04000000 +#define BR13_DYN_8BPP 0x00000000 +#define BR13_DYN_16BPP 0x01000000 +#define BR13_DYN_24BPP 0x02000000 +#define BR13_ROP_MASK 0x00FF0000 +#define BR13_DEST_PITCH 0x0000FFFF +#define BR13_PITCH_SIGN_BIT 0x00008000 + +#define BR14_DEST_HEIGHT 0xFFFF0000 +#define BR14_DEST_WIDTH 0x0000FFFF + +#define BR15_PATTERN_ADDR 0x03FFFFFF + +#define BR16_SOLID_PAT_COLOR 0x00FFFFFF +#define BR16_BACKGND_PAT_CLR 0x00FFFFFF + +#define BR17_FGND_PAT_CLR 0x00FFFFFF + +#define BR18_SRC_BGND_CLR 0x00FFFFFF +#define BR19_SRC_FGND_CLR 0x00FFFFFF + + +/* Instruction parser instructions + */ + +#define INST_PARSER_CLIENT 0x00000000 +#define INST_OP_FLUSH 0x02000000 +#define INST_FLUSH_MAP_CACHE 0x00000001 + +#define INST_DEST_BUFFER_INFO 0x06800000 + +#define INST_FRONT_BUFFER_INFO 0x06000000 +#define FRONT_INFO_ASYNC_FLIP 1<<6 +#define FRONT_INFO_PITCH_B 8 + +#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) + + +/* Registers in the i810 host-pci bridge pci config space which affect + * the i810 graphics operations. + */ +#define SMRAM_MISCC 0x70 +#define GMS 0x000000c0 +#define GMS_DISABLE 0x00000000 +#define GMS_ENABLE_BARE 0x00000040 +#define GMS_ENABLE_512K 0x00000080 +#define GMS_ENABLE_1M 0x000000c0 +#define USMM 0x00000030 +#define USMM_DISABLE 0x00000000 +#define USMM_TSEG_ZERO 0x00000010 +#define USMM_TSEG_512K 0x00000020 +#define USMM_TSEG_1M 0x00000030 +#define GFX_MEM_WIN_SIZE 0x00010000 +#define GFX_MEM_WIN_32M 0x00010000 +#define GFX_MEM_WIN_64M 0x00000000 + +/* Overkill? I don't know. Need to figure out top of mem to make the + * SMRAM calculations come out. Linux seems to have problems + * detecting it all on its own, so this seems a reasonable double + * check to any user supplied 'mem=...' boot param. + * + * ... unfortunately this reg doesn't work according to spec on the + * test hardware. + */ +#define WHTCFG_PAMR_DRP 0x50 +#define SYS_DRAM_ROW_0_SHIFT 16 +#define SYS_DRAM_ROW_1_SHIFT 20 +#define DRAM_MASK 0x0f +#define DRAM_VALUE_0 0 +#define DRAM_VALUE_1 8 +/* No 2 value defined */ +#define DRAM_VALUE_3 16 +#define DRAM_VALUE_4 16 +#define DRAM_VALUE_5 24 +#define DRAM_VALUE_6 32 +#define DRAM_VALUE_7 32 +#define DRAM_VALUE_8 48 +#define DRAM_VALUE_9 64 +#define DRAM_VALUE_A 64 +#define DRAM_VALUE_B 96 +#define DRAM_VALUE_C 128 +#define DRAM_VALUE_D 128 +#define DRAM_VALUE_E 192 +#define DRAM_VALUE_F 256 /* nice one, geezer */ +#define LM_FREQ_MASK 0x10 +#define LM_FREQ_133 0x10 +#define LM_FREQ_100 0x00 + + + + +/* These are 3d state registers, but the state is invarient, so we let + * the X server handle it: + */ + + + +/* GFXRENDERSTATE_COLOR_CHROMA_KEY, p135 + */ +#define GFX_OP_COLOR_CHROMA_KEY ((0x3<<29)|(0x1d<<24)|(0x2<<16)|0x1) +#define CC1_UPDATE_KILL_WRITE (1<<28) +#define CC1_ENABLE_KILL_WRITE (1<<27) +#define CC1_DISABLE_KILL_WRITE 0 +#define CC1_UPDATE_COLOR_IDX (1<<26) +#define CC1_UPDATE_CHROMA_LOW (1<<25) +#define CC1_UPDATE_CHROMA_HI (1<<24) +#define CC1_CHROMA_LOW_MASK ((1<<24)-1) +#define CC2_COLOR_IDX_SHIFT 24 +#define CC2_COLOR_IDX_MASK (0xff<<24) +#define CC2_CHROMA_HI_MASK ((1<<24)-1) + + +#define GFX_CMD_CONTEXT_SEL ((0<<29)|(0x5<<23)) +#define CS_UPDATE_LOAD (1<<17) +#define CS_UPDATE_USE (1<<16) +#define CS_UPDATE_LOAD (1<<17) +#define CS_LOAD_CTX0 0 +#define CS_LOAD_CTX1 (1<<8) +#define CS_USE_CTX0 0 +#define CS_USE_CTX1 (1<<0) + +/* 3D Rendering Engine */ + +#define RENDER_CLIENT 0x60000000 + +/* Primitive rendering instruction */ + +#define GFX_PRIMITIVE 0x1f000000 +#define PRIMITIVE_TRIANGLE 0 << 18 +#define PRIMITIVE_TRI_STRIP 1 << 18 +#define PRIMITIVE_TRI_REV_STRIP 2 << 18 +#define PRIMITIVE_TRI_FAN 3 << 18 +#define PRIMITIVE_POLYGON 4 << 18 +#define PRIMITIVE_LINE 5 << 18 +#define PRIMITIVE_LINE_STRIP 6 << 18 +#define PRIMITIVE_RECTANGLE 7 << 18 + +/* Vertex format instruction */ +#define GFX_VERTEX_FORMAT 0x05000000 +#define VERTEX_0_TEXCOORDS 0 << 8 +#define VERTEX_1_TEXCOORDS 1 << 8 +#define VERTEX_2_TEXCOORDS 2 << 8 +#define VERTEX_SPECULAR_FOG 1 << 7 +#define VERTEX_DIFFUSE_ALPHA 1 << 6 +#define VERTEX_Z_OFFSET 1 << 5 +#define VERTEX_POS_XYZ 1 << 1 +#define VERTEX_POS_XYZ_RHW 2 << 1 +#define VERTEX_POS_XY 3 << 1 +#define VERTEX_POS_XY_RHW 4 << 1 + +/* Drawing Rectangle Info instruction */ + +#define GFX_DRAWING_RECTANGLE_INFO 0x1d800003 +#define GFX_DRAWING_CLIP_DISABLE 1<<31 + +/* Boolean enable 1 */ +#define GFX_BOOLEAN_ENA_1 0x03000000 +#define BOOL1_ALPHA_SETUP_MASK 1<<17 +#define BOOL1_ALPHA_SETUP_BIT 1<<16 +#define BOOL1_FOG_ENABLE_MASK 1<<7 +#define BOOL1_FOG_ENABLE_BIT 1<<6 +#define BOOL1_ALPHA_TEST_MASK 1<<5 +#define BOOL1_ALPHA_TEST_BIT 1<<4 +#define BOOL1_BLEND_ENABLE_MASK 1<<3 +#define BOOL1_BLEND_ENABLE_BIT 1<<2 +#define BOOL1_Z_ENABLE_MASK 1<<1 +#define BOOL1_Z_ENABLE_BIT 1<<0 + +/* Boolean enable 2 */ +#define GFX_BOOLEAN_ENA_2 0x04000000 +#define BOOL2_MAPPING_CACHE_MASK 1<<17 +#define BOOL2_MAPPING_CACHE_BIT 1<<16 +#define BOOL2_ALPHA_DITHER_MASK 1<<15 +#define BOOL2_ALPHA_DITHER_BIT 1<<14 +#define BOOL2_FOG_DITHER_MASK 1<<13 +#define BOOL2_FOG_DITHER_BIT 1<<12 +#define BOOL2_SPECULAR_DITHER_MASK 1<<11 +#define BOOL2_SPECULAR_DITHER_BIT 1<<10 +#define BOOL2_COLOR_DITHER_MASK 1<<9 +#define BOOL2_COLOR_DITHER_BIT 1<<8 +#define BOOL2_FB_WRITE_MASK 1<<3 +#define BOOL2_FB_WRITE_BIT 1<<2 +#define BOOL2_Z_WRITE_MASK 1<<1 +#define BOOL2_Z_WRITE_BIT 1<<0 + +/* Dest buffer variables */ + +#define GFX_DEST_BUFFER_VARIABLES 0x1d850000 + +#define DEST_BUF_VAR_8BIT 0 << 8 +#define DEST_BUF_VAR_555 1 << 8 +#define DEST_BUF_VAR_565 2 << 8 + +/* map color blend stages */ + +#define GFX_MAP_COLOR_BLEND_STAGES 0 + +#define MAP_BLEND_STAGE_B 20 +#define MAP_BLEND_ACC_SEL_MASK 1<<19 +#define MAP_BLEND_ACC_SEL_BIT 1<<18 +#define MAP_BLEND_ARG1_MASK 1<<17 +#define MAP_BLEND_ARG1_B 14 +#define MAP_BLEND_REPLICATE_ARG1 1<<13 +#define MAP_BLEND_INVERT_ARG1 1<<12 + +#define MAP_BLEND_ARG2_MASK 1<<11 +#define MAP_BLEND_ARG2_B 8 +#define MAP_BLEND_REPLICATE_ARG2 1<<7 +#define MAP_BLEND_INVERT_ARG2 1<<6 + +#define MAP_BLEND_COLOR_OP_MASK 1<<5 +#define MAP_BLEND_COLOR_OP_B 0 + +#define GFX_SCISSOR_ENABLE 0x1c800000 + +#define SCISSOR_ENABLE_MASK 1<<1 +#define SCISSOR_ENABLE_BIT 1<<0 diff --git a/xorg-server/hw/kdrive/i810/i810_video.c b/xorg-server/hw/kdrive/i810/i810_video.c new file mode 100644 index 000000000..ac881d51d --- /dev/null +++ b/xorg-server/hw/kdrive/i810/i810_video.c @@ -0,0 +1,1136 @@ +/* COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 2000, 2001 Nokia Home Communications + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. + +X Window System is a trademark of The Open Group */ + +/*************************************************************************** + +Copyright 2000 Intel Corporation. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, 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 INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + +/* + * i810_video.c: i810 KDrive Xv driver. + * Based on the XFree86 i810 Xv driver by Jonathan Bian. + * + * Authors: + * Jonathan Bian <jonathan.bian@intel.com> + * Pontus Lidman <pontus.lidman@nokia.com> + * + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" +#include "kxv.h" +#include "i810.h" + +#include <X11/extensions/Xv.h> + +#include "fourcc.h" + +typedef struct { + CARD32 size; + CARD32 offset; +} FBLinearRec, *FBLinearPtr; + +#define OFF_DELAY 250 /* milliseconds */ +#define FREE_DELAY 15000 + +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 +#define CLIENT_VIDEO_ON 0x04 + +#define TIMER_MASK (OFF_TIMER | FREE_TIMER) + +static KdVideoAdaptorPtr i810SetupImageVideo(ScreenPtr); +static void i810StopVideo(KdScreenInfo *, pointer, Bool); +static int i810SetPortAttribute(KdScreenInfo *, Atom, int, pointer); +static int i810GetPortAttribute(KdScreenInfo *, Atom, int *, pointer); +static void i810QueryBestSize(KdScreenInfo *, Bool, + short, short, short, short, unsigned int *, unsigned int *, pointer); +static int i810PutImage( KdScreenInfo *, DrawablePtr, + short, short, short, short, short, short, short, short, + int, unsigned char*, short, short, Bool, RegionPtr, pointer); +static int i810QueryImageAttributes(KdScreenInfo *, + int, unsigned short *, unsigned short *, int *, int *); + +static void i810BlockHandler(int, pointer, pointer, pointer); + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +static Atom xvBrightness, xvContrast, xvColorKey; + +#define IMAGE_MAX_WIDTH 720 +#define IMAGE_MAX_HEIGHT 576 +#define Y_BUF_SIZE (IMAGE_MAX_WIDTH * IMAGE_MAX_HEIGHT) + +#define OVERLAY_UPDATE(p) OUTREG(0x30000, p | 0x80000000); + +/* + * OV0CMD - Overlay Command Register + */ +#define VERTICAL_CHROMINANCE_FILTER 0x70000000 +#define VC_SCALING_OFF 0x00000000 +#define VC_LINE_REPLICATION 0x10000000 +#define VC_UP_INTERPOLATION 0x20000000 +#define VC_PIXEL_DROPPING 0x50000000 +#define VC_DOWN_INTERPOLATION 0x60000000 +#define VERTICAL_LUMINANCE_FILTER 0x0E000000 +#define VL_SCALING_OFF 0x00000000 +#define VL_LINE_REPLICATION 0x02000000 +#define VL_UP_INTERPOLATION 0x04000000 +#define VL_PIXEL_DROPPING 0x0A000000 +#define VL_DOWN_INTERPOLATION 0x0C000000 +#define HORIZONTAL_CHROMINANCE_FILTER 0x01C00000 +#define HC_SCALING_OFF 0x00000000 +#define HC_LINE_REPLICATION 0x00400000 +#define HC_UP_INTERPOLATION 0x00800000 +#define HC_PIXEL_DROPPING 0x01400000 +#define HC_DOWN_INTERPOLATION 0x01800000 +#define HORIZONTAL_LUMINANCE_FILTER 0x00380000 +#define HL_SCALING_OFF 0x00000000 +#define HL_LINE_REPLICATION 0x00080000 +#define HL_UP_INTERPOLATION 0x00100000 +#define HL_PIXEL_DROPPING 0x00280000 +#define HL_DOWN_INTERPOLATION 0x00300000 + +#define Y_ADJUST 0x00010000 +#define OV_BYTE_ORDER 0x0000C000 +#define UV_SWAP 0x00004000 +#define Y_SWAP 0x00008000 +#define Y_AND_UV_SWAP 0x0000C000 +#define SOURCE_FORMAT 0x00003C00 +#define RGB_555 0x00000800 +#define RGB_565 0x00000C00 +#define YUV_422 0x00002000 +#define YUV_411 0x00002400 +#define YUV_420 0x00003000 +#define YUV_410 0x00003800 +#define BUFFER_AND_FIELD 0x00000006 +#define BUFFER0_FIELD0 0x00000000 +#define BUFFER1_FIELD0 0x00000004 +#define OVERLAY_ENABLE 0x00000001 + +/* + * DOV0STA - Display/Overlay 0 Status Register + */ +#define DOV0STA 0x30008 + +#define MINUV_SCALE 0x1 + +#define RGB16ToColorKey(c) \ + (((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3)) + +#define RGB15ToColorKey(c) \ + (((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3)) + +Bool i810InitVideo(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + KdVideoAdaptorPtr *adaptors, *newAdaptors = NULL; + KdVideoAdaptorPtr newAdaptor = NULL; + int num_adaptors; + +/* fprintf(stderr,"i810InitVideo\n"); */ + + if (screen->fb[0].bitsPerPixel != 8) + { + newAdaptor = i810SetupImageVideo(pScreen); + } + + num_adaptors = KdXVListGenericAdaptors(screen, &adaptors); + + if(newAdaptor) { + if(!num_adaptors) { + num_adaptors = 1; + adaptors = &newAdaptor; + } else { + newAdaptors = /* need to free this someplace */ + xalloc((num_adaptors + 1) * sizeof(KdVideoAdaptorPtr*)); + if(newAdaptors) { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(KdVideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + } + } + + if(num_adaptors) + KdXVScreenInit(pScreen, adaptors, num_adaptors); + + if(newAdaptors) + xfree(newAdaptors); + return TRUE; +} + +/* client libraries expect an encoding */ +static KdVideoEncodingRec DummyEncoding[1] = +{ + { + 0, + "XV_IMAGE", + IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, + {1, 1} + } +}; + +#define NUM_FORMATS 3 + +static KdVideoFormatRec Formats[NUM_FORMATS] = +{ + {15, TrueColor}, {16, TrueColor}, {24, TrueColor} +}; + +#define NUM_ATTRIBUTES 3 + +static KdAttributeRec Attributes[NUM_ATTRIBUTES] = +{ + {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, + {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, + {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"} +}; + +#define NUM_IMAGES 4 + +static KdImageRec Images[NUM_IMAGES] = +{ + XVIMAGE_YUY2, + XVIMAGE_YV12, + XVIMAGE_I420, + XVIMAGE_UYVY +}; + +typedef struct { + CARD32 OBUF_0Y; + CARD32 OBUF_1Y; + CARD32 OBUF_0U; + CARD32 OBUF_0V; + CARD32 OBUF_1U; + CARD32 OBUF_1V; + CARD32 OV0STRIDE; + CARD32 YRGB_VPH; + CARD32 UV_VPH; + CARD32 HORZ_PH; + CARD32 INIT_PH; + CARD32 DWINPOS; + CARD32 DWINSZ; + CARD32 SWID; + CARD32 SWIDQW; + CARD32 SHEIGHT; + CARD32 YRGBSCALE; + CARD32 UVSCALE; + CARD32 OV0CLRC0; + CARD32 OV0CLRC1; + CARD32 DCLRKV; + CARD32 DCLRKM; + CARD32 SCLRKVH; + CARD32 SCLRKVL; + CARD32 SCLRKM; + CARD32 OV0CONF; + CARD32 OV0CMD; +} I810OverlayRegRec, *I810OverlayRegPtr; + +typedef struct { + CARD32 YBuf0offset; + CARD32 UBuf0offset; + CARD32 VBuf0offset; + + CARD32 YBuf1offset; + CARD32 UBuf1offset; + CARD32 VBuf1offset; + + unsigned char currentBuf; + + unsigned char brightness; + unsigned char contrast; + + RegionRec clip; + CARD32 colorKey; + + CARD32 videoStatus; + Time offTime; + Time freeTime; + FBLinearPtr linear; +} I810PortPrivRec, *I810PortPrivPtr; + +#define GET_PORT_PRIVATE(screen) \ + (I810PortPrivPtr)(((I810CardInfo *) (screen->card->driver))->adaptor->pPortPrivates[0].ptr) + +static void i810ResetVideo(KdScreenInfo *screen) +{ + ScreenPtr pScreen = screen->pScreen; + KdScreenPriv(pScreen); + KdCardInfo *card = pScreenPriv->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + + I810PortPrivPtr pPriv = i810c->adaptor->pPortPrivates[0].ptr; + I810OverlayRegPtr overlay = (I810OverlayRegPtr) (i810c->FbBase + i810c->OverlayStart); + + /* + * Default to maximum image size in YV12 + */ + + overlay->YRGB_VPH = 0; + overlay->UV_VPH = 0; + overlay->HORZ_PH = 0; + overlay->INIT_PH = 0; + overlay->DWINPOS = 0; + overlay->DWINSZ = (IMAGE_MAX_HEIGHT << 16) | IMAGE_MAX_WIDTH; + overlay->SWID = IMAGE_MAX_WIDTH | (IMAGE_MAX_WIDTH << 15); + overlay->SWIDQW = (IMAGE_MAX_WIDTH >> 3) | (IMAGE_MAX_WIDTH << 12); + overlay->SHEIGHT = IMAGE_MAX_HEIGHT | (IMAGE_MAX_HEIGHT << 15); + overlay->YRGBSCALE = 0x80004000; /* scale factor 1 */ + overlay->UVSCALE = 0x80004000; /* scale factor 1 */ + overlay->OV0CLRC0 = 0x4000; /* brightness: 0 contrast: 1.0 */ + overlay->OV0CLRC1 = 0x80; /* saturation: bypass */ + + /* + * Enable destination color keying + */ + switch(screen->fb[0].depth) { + case 16: overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey); + overlay->DCLRKM = 0x80070307; + break; + case 15: overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey); + overlay->DCLRKM = 0x80070707; + break; + default: overlay->DCLRKV = pPriv->colorKey; + overlay->DCLRKM = 0x80000000; + break; + } + + overlay->SCLRKVH = 0; + overlay->SCLRKVL = 0; + overlay->SCLRKM = 0; /* source color key disable */ + overlay->OV0CONF = 0; /* two 720 pixel line buffers */ + + overlay->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | Y_ADJUST | + YUV_420; + + OVERLAY_UPDATE(i810c->OverlayPhysical); +} + + +static KdVideoAdaptorPtr +i810SetupImageVideo(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + KdCardInfo *card = pScreenPriv->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + + + KdVideoAdaptorPtr adapt; + I810PortPrivPtr pPriv; + +/* fprintf(stderr,"i810SetupImageVideo\n"); */ + + if(!(adapt = xcalloc(1, sizeof(KdVideoAdaptorRec) + + sizeof(I810PortPrivRec) + + sizeof(DevUnion)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = "I810 Video Overlay"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion*)(&adapt[1]); + + pPriv = (I810PortPrivPtr)(&adapt->pPortPrivates[1]); + + adapt->pPortPrivates[0].ptr = (pointer)(pPriv); + adapt->pAttributes = Attributes; + adapt->nImages = NUM_IMAGES; + adapt->nAttributes = NUM_ATTRIBUTES; + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = i810StopVideo; + adapt->SetPortAttribute = i810SetPortAttribute; + adapt->GetPortAttribute = i810GetPortAttribute; + adapt->QueryBestSize = i810QueryBestSize; + adapt->PutImage = i810PutImage; + adapt->QueryImageAttributes = i810QueryImageAttributes; + + pPriv->colorKey = i810c->colorKey & ((1 << screen->fb[0].depth) - 1); + pPriv->videoStatus = 0; + pPriv->brightness = 0; + pPriv->contrast = 128; + pPriv->linear = NULL; + pPriv->currentBuf = 0; + + /* gotta uninit this someplace */ + REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); + + i810c->adaptor = adapt; + + i810c->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = i810BlockHandler; + + xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); + xvContrast = MAKE_ATOM("XV_CONTRAST"); + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + + i810ResetVideo(screen); + + return adapt; +} + + +/* I810ClipVideo - + + Takes the dst box in standard X BoxRec form (top and left + edges inclusive, bottom and right exclusive). The new dst + box is returned. The source boundaries are given (x1, y1 + inclusive, x2, y2 exclusive) and returned are the new source + boundaries in 16.16 fixed point. +*/ + +static void +I810ClipVideo( + BoxPtr dst, + INT32 *x1, + INT32 *x2, + INT32 *y1, + INT32 *y2, + BoxPtr extents, /* extents of the clip region */ + INT32 width, + INT32 height +){ + INT32 vscale, hscale, delta; + int diff; + + hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1); + vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1); + + *x1 <<= 16; *x2 <<= 16; + *y1 <<= 16; *y2 <<= 16; + + diff = extents->x1 - dst->x1; + if(diff > 0) { + dst->x1 = extents->x1; + *x1 += diff * hscale; + } + diff = dst->x2 - extents->x2; + if(diff > 0) { + dst->x2 = extents->x2; + *x2 -= diff * hscale; + } + diff = extents->y1 - dst->y1; + if(diff > 0) { + dst->y1 = extents->y1; + *y1 += diff * vscale; + } + diff = dst->y2 - extents->y2; + if(diff > 0) { + dst->y2 = extents->y2; + *y2 -= diff * vscale; + } + + if(*x1 < 0) { + diff = (- *x1 + hscale - 1)/ hscale; + dst->x1 += diff; + *x1 += diff * hscale; + } + delta = *x2 - (width << 16); + if(delta > 0) { + diff = (delta + hscale - 1)/ hscale; + dst->x2 -= diff; + *x2 -= diff * hscale; + } + if(*y1 < 0) { + diff = (- *y1 + vscale - 1)/ vscale; + dst->y1 += diff; + *y1 += diff * vscale; + } + delta = *y2 - (height << 16); + if(delta > 0) { + diff = (delta + vscale - 1)/ vscale; + dst->y2 -= diff; + *y2 -= diff * vscale; + } +} + +static void +i810StopVideo(KdScreenInfo *screen, pointer data, Bool exit) +{ + I810PortPrivPtr pPriv = (I810PortPrivPtr)data; + KdCardInfo *card = screen->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + + I810OverlayRegPtr overlay = (I810OverlayRegPtr) (i810c->FbBase + i810c->OverlayStart); + + REGION_EMPTY(screen->pScreen, &pPriv->clip); + + if(exit) { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + overlay->OV0CMD &= 0xFFFFFFFE; + OVERLAY_UPDATE(i810c->OverlayPhysical); + } + if(pPriv->linear) { + xfree(pPriv->linear); + pPriv->linear = NULL; + } + pPriv->videoStatus = 0; + } else { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + pPriv->videoStatus |= OFF_TIMER; + pPriv->offTime = currentTime.milliseconds + OFF_DELAY; + } + } + +} + +static int +i810SetPortAttribute( + KdScreenInfo *screen, + Atom attribute, + int value, + pointer data +){ + I810PortPrivPtr pPriv = (I810PortPrivPtr)data; + KdCardInfo *card = screen->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + + I810OverlayRegPtr overlay = (I810OverlayRegPtr) (i810c->FbBase + i810c->OverlayStart); + + if(attribute == xvBrightness) { + if((value < -128) || (value > 127)) + return BadValue; + pPriv->brightness = value; + overlay->OV0CLRC0 &= 0xFFFFFF00; + overlay->OV0CLRC0 |= value; + OVERLAY_UPDATE(i810c->OverlayPhysical); + } else + if(attribute == xvContrast) { + if((value < 0) || (value > 255)) + return BadValue; + pPriv->contrast = value; + overlay->OV0CLRC0 &= 0xFFFE00FF; + overlay->OV0CLRC0 |= value << 9; + OVERLAY_UPDATE(i810c->OverlayPhysical); + } else + if(attribute == xvColorKey) { + pPriv->colorKey = value; + switch(screen->fb[0].depth) { + case 16: overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey); + break; + case 15: overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey); + break; + default: overlay->DCLRKV = pPriv->colorKey; + break; + } + OVERLAY_UPDATE(i810c->OverlayPhysical); + REGION_EMPTY(screen->pScreen, &pPriv->clip); + } else return BadMatch; + + return Success; +} + +static int +i810GetPortAttribute( + KdScreenInfo *screen, + Atom attribute, + int *value, + pointer data +){ + I810PortPrivPtr pPriv = (I810PortPrivPtr)data; + + if(attribute == xvBrightness) { + *value = pPriv->brightness; + } else + if(attribute == xvContrast) { + *value = pPriv->contrast; + } else + if(attribute == xvColorKey) { + *value = pPriv->colorKey; + } else return BadMatch; + + return Success; +} + +static void +i810QueryBestSize( + KdScreenInfo *screen, + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, + pointer data +){ + *p_w = drw_w; + *p_h = drw_h; +} + + +static void +I810CopyPackedData( + KdScreenInfo *screen, + unsigned char *buf, + int srcPitch, + int dstPitch, + int top, + int left, + int h, + int w + ) +{ + KdCardInfo *card = screen->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + I810PortPrivPtr pPriv = i810c->adaptor->pPortPrivates[0].ptr; + unsigned char *src, *dst; + + src = buf + (top*srcPitch) + (left<<1); + + if (pPriv->currentBuf == 0) + dst = i810c->FbBase + pPriv->YBuf0offset; + else + dst = i810c->FbBase + pPriv->YBuf1offset; + + w <<= 1; + while(h--) { + memcpy(dst, src, w); + src += srcPitch; + dst += dstPitch; + } +} + +static void +i810CopyPlanarData( + KdScreenInfo *screen, + unsigned char *buf, + int srcPitch, + int dstPitch, /* of chroma */ + int srcH, + int top, + int left, + int h, + int w, + int id + ) +{ + KdCardInfo *card = screen->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + I810PortPrivPtr pPriv = i810c->adaptor->pPortPrivates[0].ptr; + int i; + unsigned char *src1, *src2, *src3, *dst1, *dst2, *dst3; + + /* Copy Y data */ + src1 = buf + (top*srcPitch) + left; + if (pPriv->currentBuf == 0) + dst1 = i810c->FbBase + pPriv->YBuf0offset; + else + dst1 = i810c->FbBase + pPriv->YBuf1offset; + + for (i = 0; i < h; i++) { + memcpy(dst1, src1, w); + src1 += srcPitch; + dst1 += dstPitch << 1; + } + + /* Copy V data for YV12, or U data for I420 */ + src2 = buf + (srcH*srcPitch) + ((top*srcPitch)>>2) + (left>>1); + if (pPriv->currentBuf == 0) { + if (id == FOURCC_I420) + dst2 = i810c->FbBase + pPriv->UBuf0offset; + else + dst2 = i810c->FbBase + pPriv->VBuf0offset; + } else { + if (id == FOURCC_I420) + dst2 = i810c->FbBase + pPriv->UBuf1offset; + else + dst2 = i810c->FbBase + pPriv->VBuf1offset; + } + + for (i = 0; i < h/2; i++) { + memcpy(dst2, src2, w/2); + src2 += srcPitch>>1; + dst2 += dstPitch; + } + + /* Copy U data for YV12, or V data for I420 */ + src3 = buf + (srcH*srcPitch) + ((srcH*srcPitch)>>2) + ((top*srcPitch)>>2) + (left>>1); + if (pPriv->currentBuf == 0) { + if (id == FOURCC_I420) + dst3 = i810c->FbBase + pPriv->VBuf0offset; + else + dst3 = i810c->FbBase + pPriv->UBuf0offset; + } else { + if (id == FOURCC_I420) + dst3 = i810c->FbBase + pPriv->VBuf1offset; + else + dst3 = i810c->FbBase + pPriv->UBuf1offset; + } + + for (i = 0; i < h/2; i++) { + memcpy(dst3, src3, w/2); + src3 += srcPitch>>1; + dst3 += dstPitch; + } +} + +static void +i810DisplayVideo( + KdScreenInfo *screen, + int id, + short width, short height, + int dstPitch, /* of chroma for 4:2:0 */ + int x1, int y1, int x2, int y2, + BoxPtr dstBox, + short src_w, short src_h, + short drw_w, short drw_h +){ + KdCardInfo *card = screen->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + I810PortPrivPtr pPriv = i810c->adaptor->pPortPrivates[0].ptr; + I810OverlayRegPtr overlay = (I810OverlayRegPtr) (i810c->FbBase + i810c->OverlayStart); + int xscaleInt, xscaleFract, yscaleInt, yscaleFract; + int xscaleIntUV = 0, xscaleFractUV = 0, yscaleIntUV = 0, yscaleFractUV = 0; + unsigned int swidth; + + switch(id) { + case FOURCC_YV12: + case FOURCC_I420: + swidth = (width + 7) & ~7; + overlay->SWID = (swidth << 15) | swidth; + overlay->SWIDQW = (swidth << 12) | (swidth >> 3); + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + swidth = ((width + 3) & ~3) << 1; + overlay->SWID = swidth; + overlay->SWIDQW = swidth >> 3; + break; + } + + overlay->SHEIGHT = height | (height << 15); + overlay->DWINPOS = (dstBox->y1 << 16) | dstBox->x1; + overlay->DWINSZ = ((dstBox->y2 - dstBox->y1) << 16) | + (dstBox->x2 - dstBox->x1); + + /* buffer locations */ + overlay->OBUF_0Y = pPriv->YBuf0offset; + overlay->OBUF_1Y = pPriv->YBuf1offset; + overlay->OBUF_0U = pPriv->UBuf0offset; + overlay->OBUF_0V = pPriv->VBuf0offset; + overlay->OBUF_1U = pPriv->UBuf1offset; + overlay->OBUF_1V = pPriv->VBuf1offset; + + /* + * Calculate horizontal and vertical scaling factors, default to 1:1 + */ + overlay->YRGBSCALE = 0x80004000; + overlay->UVSCALE = 0x80004000; + + /* + * Initially, YCbCr and Overlay Enable and + * vertical chrominance up interpolation and horozontal chrominance + * up interpolation + */ + overlay->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | Y_ADJUST | + OVERLAY_ENABLE; + + if ((drw_w != src_w) || (drw_h != src_h)) + { + xscaleInt = (src_w / drw_w) & 0x3; + xscaleFract = (src_w << 12) / drw_w; + yscaleInt = (src_h / drw_h) & 0x3; + yscaleFract = (src_h << 12) / drw_h; + + overlay->YRGBSCALE = (xscaleInt << 15) | + ((xscaleFract & 0xFFF) << 3) | + (yscaleInt) | + ((yscaleFract & 0xFFF) << 20); + + if (drw_w > src_w) + { + /* horizontal up-scaling */ + overlay->OV0CMD &= ~HORIZONTAL_CHROMINANCE_FILTER; + overlay->OV0CMD &= ~HORIZONTAL_LUMINANCE_FILTER; + overlay->OV0CMD |= (HC_UP_INTERPOLATION | HL_UP_INTERPOLATION); + } + + if (drw_h > src_h) + { + /* vertical up-scaling */ + overlay->OV0CMD &= ~VERTICAL_CHROMINANCE_FILTER; + overlay->OV0CMD &= ~VERTICAL_LUMINANCE_FILTER; + overlay->OV0CMD |= (VC_UP_INTERPOLATION | VL_UP_INTERPOLATION); + } + + if (drw_w < src_w) + { + /* horizontal down-scaling */ + overlay->OV0CMD &= ~HORIZONTAL_CHROMINANCE_FILTER; + overlay->OV0CMD &= ~HORIZONTAL_LUMINANCE_FILTER; + overlay->OV0CMD |= (HC_DOWN_INTERPOLATION | HL_DOWN_INTERPOLATION); + } + + if (drw_h < src_h) + { + /* vertical down-scaling */ + overlay->OV0CMD &= ~VERTICAL_CHROMINANCE_FILTER; + overlay->OV0CMD &= ~VERTICAL_LUMINANCE_FILTER; + overlay->OV0CMD |= (VC_DOWN_INTERPOLATION | VL_DOWN_INTERPOLATION); + } + + /* now calculate the UV scaling factor */ + + if (xscaleFract) + { + xscaleFractUV = xscaleFract >> MINUV_SCALE; + overlay->OV0CMD &= ~HC_DOWN_INTERPOLATION; + overlay->OV0CMD |= HC_UP_INTERPOLATION; + } + + if (xscaleInt) + { + xscaleIntUV = xscaleInt >> MINUV_SCALE; + if (xscaleIntUV) + { + overlay->OV0CMD &= ~HC_UP_INTERPOLATION; + } + } + + if (yscaleFract) + { + yscaleFractUV = yscaleFract >> MINUV_SCALE; + overlay->OV0CMD &= ~VC_DOWN_INTERPOLATION; + overlay->OV0CMD |= VC_UP_INTERPOLATION; + } + + if (yscaleInt) + { + yscaleIntUV = yscaleInt >> MINUV_SCALE; + if (yscaleIntUV) + { + overlay->OV0CMD &= ~VC_UP_INTERPOLATION; + overlay->OV0CMD |= VC_DOWN_INTERPOLATION; + } + } + + overlay->UVSCALE = yscaleIntUV | ((xscaleFractUV & 0xFFF) << 3) | + ((yscaleFractUV & 0xFFF) << 20); + } + + switch(id) { + case FOURCC_YV12: + case FOURCC_I420: + overlay->OV0STRIDE = (dstPitch << 1) | (dstPitch << 16); + overlay->OV0CMD &= ~SOURCE_FORMAT; + overlay->OV0CMD |= YUV_420; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + overlay->OV0STRIDE = dstPitch; + overlay->OV0CMD &= ~SOURCE_FORMAT; + overlay->OV0CMD |= YUV_422; + overlay->OV0CMD &= ~OV_BYTE_ORDER; + if (id == FOURCC_UYVY) + overlay->OV0CMD |= Y_SWAP; + break; + } + + overlay->OV0CMD &= ~BUFFER_AND_FIELD; + if (pPriv->currentBuf == 0) + overlay->OV0CMD |= BUFFER0_FIELD0; + else + overlay->OV0CMD |= BUFFER1_FIELD0; + + OVERLAY_UPDATE(i810c->OverlayPhysical); + +} + +static FBLinearPtr +i810AllocateMemory( + KdScreenInfo *screen, + FBLinearPtr linear, + int size +){ + KdCardInfo *card=screen->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + FBLinearPtr new_linear; + + if(linear) { + if(linear->size >= size) + return linear; + else + ErrorF("Ran out of memory for overlay buffer, requested size = %d\n",size); + } + + new_linear = xalloc(sizeof(FBLinearRec)); + new_linear->size = i810c->XvMem.Size; + new_linear->offset = i810c->XvMem.Start; + +/* fprintf(stderr,"Overlay mem offset %lx\n",new_linear->offset); */ + + return new_linear; +} + +static int +i810PutImage(KdScreenInfo *screen, + DrawablePtr pDraw, + short src_x, + short src_y, + short drw_x, + short drw_y, + short src_w, + short src_h, + short drw_w, + short drw_h, + int id, + unsigned char *buf, + short width, + short height, + Bool sync, + RegionPtr clipBoxes, + pointer data) +{ + KdCardInfo *card = screen->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + I810PortPrivPtr pPriv = (I810PortPrivPtr)data; + INT32 x1, x2, y1, y2; + int srcPitch, dstPitch; + int top, left, npixels, nlines, size; + BoxRec dstBox; + + /* Clip */ + x1 = src_x; + x2 = src_x + src_w; + y1 = src_y; + y2 = src_y + src_h; + + dstBox.x1 = drw_x; + dstBox.x2 = drw_x + drw_w; + dstBox.y1 = drw_y; + dstBox.y2 = drw_y + drw_h; + + I810ClipVideo(&dstBox, &x1, &x2, &y1, &y2, + REGION_EXTENTS(pScreen, clipBoxes), width, height); + + if((x1 >= x2) || (y1 >= y2)) + return Success; + + switch(id) { + case FOURCC_YV12: + case FOURCC_I420: + srcPitch = (width + 3) & ~3; + dstPitch = ((width >> 1) + 7) & ~7; /* of chroma */ + size = dstPitch * height * 3; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + srcPitch = (width << 1); + dstPitch = (srcPitch + 7) & ~7; + size = dstPitch * height; + break; + } + + if(!(pPriv->linear = i810AllocateMemory(screen, pPriv->linear, + (screen->fb[0].bitsPerPixel == 16) ? size : (size >> 1)))) + return BadAlloc; + + /* fixup pointers */ + pPriv->YBuf0offset = pPriv->linear->offset; + pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height); + pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height >> 1); + + pPriv->YBuf1offset = pPriv->linear->offset + size; + pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height); + pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height >> 1); + + /* wait for the last rendered buffer to be flipped in */ + while (((INREG(DOV0STA)&0x00100000)>>20) != pPriv->currentBuf); + + /* buffer swap */ + if (pPriv->currentBuf == 0) + pPriv->currentBuf = 1; + else + pPriv->currentBuf = 0; + + /* copy data */ + top = y1 >> 16; + left = (x1 >> 16) & ~1; + npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; + + switch(id) { + case FOURCC_YV12: + case FOURCC_I420: + top &= ~1; + nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; + i810CopyPlanarData(screen, buf, srcPitch, dstPitch, height, top, left, + nlines, npixels, id); + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + nlines = ((y2 + 0xffff) >> 16) - top; + I810CopyPackedData(screen, buf, srcPitch, dstPitch, top, left, nlines, + npixels); + break; + } + + /* update cliplist */ + if(!REGION_EQUAL(screen->pScreen, &pPriv->clip, clipBoxes)) { + REGION_COPY(screen->pScreen, &pPriv->clip, clipBoxes); + KXVPaintRegion (pDraw, &pPriv->clip, pPriv->colorKey); + } + + + i810DisplayVideo(screen, id, width, height, dstPitch, + x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); + + pPriv->videoStatus = CLIENT_VIDEO_ON; + + return Success; +} + + +static int +i810QueryImageAttributes( + KdScreenInfo *screen, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets +){ + int size, tmp; + + if(*w > 720) *w = 720; + if(*h > 576) *h = 576; + + *w = (*w + 1) & ~1; + if(offsets) offsets[0] = 0; + + switch(id) { + case FOURCC_YV12: + case FOURCC_I420: + *h = (*h + 1) & ~1; + size = (*w + 3) & ~3; + if(pitches) pitches[0] = size; + size *= *h; + if(offsets) offsets[1] = size; + tmp = ((*w >> 1) + 3) & ~3; + if(pitches) pitches[1] = pitches[2] = tmp; + tmp *= (*h >> 1); + size += tmp; + if(offsets) offsets[2] = size; + size += tmp; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + size = *w << 1; + if(pitches) pitches[0] = size; + size *= *h; + break; + } + + return size; +} + +static void +i810BlockHandler ( + int i, + pointer blockData, + pointer pTimeout, + pointer pReadmask +){ + ScreenPtr pScreen = screenInfo.screens[i]; + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + KdCardInfo *card = screen->card; + I810CardInfo *i810c = (I810CardInfo *) card->driver; + I810PortPrivPtr pPriv = GET_PORT_PRIVATE(screen); + I810OverlayRegPtr overlay = (I810OverlayRegPtr) (i810c->FbBase + i810c->OverlayStart); + + pScreen->BlockHandler = i810c->BlockHandler; + + (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); + + pScreen->BlockHandler = i810BlockHandler; + + if(pPriv->videoStatus & TIMER_MASK) { + UpdateCurrentTime(); + if(pPriv->videoStatus & OFF_TIMER) { + if(pPriv->offTime < currentTime.milliseconds) { + /* Turn off the overlay */ + overlay->OV0CMD &= 0xFFFFFFFE; + OVERLAY_UPDATE(i810c->OverlayPhysical); + + pPriv->videoStatus = FREE_TIMER; + pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; + } + } else { /* FREE_TIMER */ + if(pPriv->freeTime < currentTime.milliseconds) { + if(pPriv->linear) { + xfree(pPriv->linear); + pPriv->linear = NULL; + } + pPriv->videoStatus = 0; + } + } + } +} diff --git a/xorg-server/hw/kdrive/i810/i810draw.c b/xorg-server/hw/kdrive/i810/i810draw.c new file mode 100644 index 000000000..b571efbe0 --- /dev/null +++ b/xorg-server/hw/kdrive/i810/i810draw.c @@ -0,0 +1,352 @@ +/* COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 2000, 2001 Nokia Home Communications + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. + +X Window System is a trademark of The Open Group */ + +/* Hardware accelerated drawing for KDrive i810 driver. + Author: Pontus Lidman <pontus.lidman@nokia.com> +*/ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" +#include "kaa.h" +#ifdef XV +#include "kxv.h" +#endif +#include "i810.h" +#include "i810_reg.h" + +//#include "Xmd.h" +#include "gcstruct.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "mistruct.h" +#include "dixfontstr.h" +#include "fb.h" +#include "migc.h" +#include "miline.h" +#include "picturestr.h" + +#define NUM_STACK_RECTS 1024 + +i810ScreenInfo *accel_i810s; + +static int +i810WaitLpRing(i810ScreenInfo *i810s, int n, int timeout_millis) +{ + i810CardInfo *i810c = i810s->i810c; + I810RingBuffer *ring = &(i810c->LpRing); + int iters = 0; + int start = 0; + int now = 0; + int last_head = 0; + int first = 0; + + /* If your system hasn't moved the head pointer in 2 seconds, I'm going to + * call it crashed. + */ + if (timeout_millis == 0) + timeout_millis = 2000; + + if (I810_DEBUG) { + fprintf(stderr, "i810WaitLpRing %d\n", n); + first = GetTimeInMillis(); + } + + while (ring->space < n) + { + int i; + + ring->head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR; + ring->space = ring->head - (ring->tail+8); + + if (ring->space < 0) + ring->space += ring->mem.Size; + + iters++; + now = GetTimeInMillis(); + if ( start == 0 || now < start || ring->head != last_head) { + if (I810_DEBUG) + if (now > start) + fprintf(stderr, "space: %d wanted %d\n", ring->space, n ); + start = now; + last_head = ring->head; + } else if ( now - start > timeout_millis ) { + + i810PrintErrorState(i810c); + fprintf(stderr, "space: %d wanted %d\n", ring->space, n ); + FatalError("lockup\n"); + } + + for (i = 0 ; i < 2000 ; i++) + ; + } + + if (I810_DEBUG) + { + now = GetTimeInMillis(); + if (now - first) { + fprintf(stderr,"Elapsed %d ms\n", now - first); + fprintf(stderr, "space: %d wanted %d\n", ring->space, n ); + } + } + + return iters; +} + +static void +i810Sync(i810ScreenInfo *i810s) +{ + i810CardInfo *i810c = i810s->i810c; + LP_RING_LOCALS; + + if (I810_DEBUG) + fprintf(stderr, "i810Sync\n"); + + /* Send a flush instruction and then wait till the ring is empty. + * This is stronger than waiting for the blitter to finish as it also + * flushes the internal graphics caches. + */ + BEGIN_LP_RING(2); + OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); + OUT_RING( 0 ); /* pad to quadword */ + ADVANCE_LP_RING(); + + i810WaitLpRing(i810s, i810c->LpRing.mem.Size - 8, 0); + + i810c->LpRing.space = i810c->LpRing.mem.Size - 8; + i810c->nextColorExpandBuf = 0; +} + +static void +i810WaitMarker(ScreenPtr pScreen, int marker) +{ + KdScreenPriv(pScreen); + i810ScreenInfo(pScreenPriv); + + i810Sync(i810s); +} + +#if 0 +static void +i810EmitInvarientState(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + i810CardInfo(pScreenPriv); + i810ScreenInfo(pScreenPriv); + LP_RING_LOCALS; + + BEGIN_LP_RING( 10 ); + + OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); + OUT_RING( GFX_CMD_CONTEXT_SEL | CS_UPDATE_USE | CS_USE_CTX0 ); + OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); + OUT_RING( 0 ); + + + OUT_RING( GFX_OP_COLOR_CHROMA_KEY ); + OUT_RING( CC1_UPDATE_KILL_WRITE | + CC1_DISABLE_KILL_WRITE | + CC1_UPDATE_COLOR_IDX | + CC1_UPDATE_CHROMA_LOW | + CC1_UPDATE_CHROMA_HI | + 0); + OUT_RING( 0 ); + OUT_RING( 0 ); + + /* No depth buffer in KDrive yet */ + /* OUT_RING( CMD_OP_Z_BUFFER_INFO ); */ + /* OUT_RING( pI810->DepthBuffer.Start | pI810->auxPitchBits); */ + + ADVANCE_LP_RING(); +} +#endif + +static unsigned int i810PatternRop[16] = { + 0x00, /* GXclear */ + 0xA0, /* GXand */ + 0x50, /* GXandReverse */ + 0xF0, /* GXcopy */ + 0x0A, /* GXandInvert */ + 0xAA, /* GXnoop */ + 0x5A, /* GXxor */ + 0xFA, /* GXor */ + 0x05, /* GXnor */ + 0xA5, /* GXequiv */ + 0x55, /* GXinvert */ + 0xF5, /* GXorReverse */ + 0x0F, /* GXcopyInvert */ + 0xAF, /* GXorInverted */ + 0x5F, /* GXnand */ + 0xFF /* GXset */ +}; + +static Bool +i810PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) +{ + KdScreenPriv(pPix->drawable.pScreen); + i810ScreenInfo(pScreenPriv); + i810CardInfo(pScreenPriv); + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF( "i810PrepareSolid color: %x rop: %x mask: %x\n", + fg, alu, pm); + + /* Color blit, p166 */ + i810c->BR[13] = BR13_SOLID_PATTERN | + (i810PatternRop[alu] << 16) | + (pPix->drawable.pScreen->width * i810c->cpp); + i810c->BR[16] = fg; + + accel_i810s = i810s; + + return TRUE; +} + +static void +i810Solid(int x1, int y1, int x2, int y2) +{ + I810ScreenInfo *i810s = accel_i810s; + I810CardInfo *i810c = i810s->i810c; + LP_RING_LOCALS; + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF( "i810SubsequentFillRectSolid %d,%d %d,%d\n", x1, y1, x2, y2); + + BEGIN_LP_RING(6); + + OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); + OUT_RING( i810c->BR[13] ); + OUT_RING( ((y2 - y1) << 16) | ((x2 - x1) * i810c->cpp)); + OUT_RING( i810c->bufferOffset + y1 * i810s->pitch + x1 * i810c->cpp ); + + OUT_RING( i810c->BR[16]); + OUT_RING( 0 ); /* pad to quadword */ + + ADVANCE_LP_RING(); +} + +static void +i810DoneSolid(void) +{ +} + +static Bool +i810PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, Pixel pm) +{ + return FALSE; +} + +static void +i810RefreshRing(i810CardInfo *i810c) +{ + i810c->LpRing.head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR; + i810c->LpRing.tail = INREG(LP_RING + RING_TAIL); + i810c->LpRing.space = i810c->LpRing.head - (i810c->LpRing.tail+8); + if (i810c->LpRing.space < 0) + i810c->LpRing.space += i810c->LpRing.mem.Size; +} + + +static void +i810SetRingRegs(i810CardInfo *i810c) +{ + unsigned int itemp; + + OUTREG(LP_RING + RING_TAIL, 0 ); + OUTREG(LP_RING + RING_HEAD, 0 ); + + itemp = INREG(LP_RING + RING_START); + itemp &= ~(START_ADDR); + itemp |= i810c->LpRing.mem.Start; + OUTREG(LP_RING + RING_START, itemp ); + + itemp = INREG(LP_RING + RING_LEN); + itemp &= ~(RING_NR_PAGES | RING_REPORT_MASK | RING_VALID_MASK); + itemp |= ((i810c->LpRing.mem.Size-4096) | RING_NO_REPORT | RING_VALID); + OUTREG(LP_RING + RING_LEN, itemp ); +} + +Bool +i810InitAccel(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + i810ScreenInfo(pScreenPriv); + i810CardInfo(pScreenPriv); + + memset(&i810s->kaa, 0, sizeof(KaaScreenInfoRec)); + i810s->kaa.waitMarker = i810WaitMarker; + i810s->kaa.PrepareSolid = i810PrepareSolid; + i810s->kaa.Solid = i810Solid; + i810s->kaa.DoneSolid = i810DoneSolid; + i810s->kaa.PrepareCopy = i810PrepareCopy; + i810s->kaa.Copy = NULL; + i810s->kaa.DoneCopy = NULL; + + i810s->pitch = pScreen->width * i810c->cpp; + + return FALSE; +} + +void +i810EnableAccel(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + i810CardInfo(pScreenPriv); + + if (i810c->LpRing.mem.Size == 0) { + ErrorF("No memory for LpRing!! Acceleration not functional!!\n"); + } + + i810SetRingRegs(i810c); + + kaaMarkSync (pScreen); +} + + +void +i810DisableAccel(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + i810CardInfo(pScreenPriv); + i810ScreenInfo(pScreenPriv); + + i810RefreshRing(i810c); + i810Sync(i810s); +} + +void +i810FiniAccel(ScreenPtr pScreen) +{ +} diff --git a/xorg-server/hw/kdrive/i810/i810draw.h b/xorg-server/hw/kdrive/i810/i810draw.h new file mode 100644 index 000000000..7c8c04489 --- /dev/null +++ b/xorg-server/hw/kdrive/i810/i810draw.h @@ -0,0 +1,46 @@ +/* COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 2000, 2001 Nokia Home Communications + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. + +X Window System is a trademark of The Open Group */ + +/* Hardware accelerated drawing for KDrive i810 driver, header file. + Author: Pontus Lidman <pontus.lidman@nokia.com> +*/ + + +#ifndef _I810DRAW_H_ +#define _I810DRAW_H_ + +void i810RefreshRing(KdScreenInfo *screen); +int i810WaitLpRing( KdScreenInfo *screen, int n, int timeout_millis ); +void i810Sync( KdScreenInfo *screen ); + +#endif /* _I810DRAW_H_ */ diff --git a/xorg-server/hw/kdrive/i810/i810stub.c b/xorg-server/hw/kdrive/i810/i810stub.c new file mode 100644 index 000000000..3109984e0 --- /dev/null +++ b/xorg-server/hw/kdrive/i810/i810stub.c @@ -0,0 +1,92 @@ +/* COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 2000, 2001 Nokia Home Communications + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. + +X Window System is a trademark of The Open Group */ + +/* Stub functions for the i810 KDrive driver + Author: Pontus Lidman <pontus.lidman@nokia.com> +*/ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" +#include "kxv.h" +#include "i810.h" +#include "klinux.h" + +static const int i810Cards[]={ + PCI_CHIP_I810, + PCI_CHIP_I810_DC100, + PCI_CHIP_I810_E +}; + +#define numI810Cards (sizeof(i810Cards) / sizeof(i810Cards[0])) + +void +InitCard (char *name) +{ + KdCardAttr attr; + int i; + + for (i = 0; i < numI810Cards; i++) + if (LinuxFindPci (0x8086, i810Cards[i], 0, &attr)) + KdCardInfoAdd (&i810Funcs, &attr, (void *) i810Cards[i]); +} + + +void +InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv) +{ + KdInitOutput (pScreenInfo, argc, argv); +} + +void +InitInput (int argc, char **argv) +{ + KdOsAddInputDrivers (); + KdInitInput (); +} + +void +ddxUseMsg (void) +{ + KdUseMsg(); +} + +int +ddxProcessArgument (int argc, char **argv, int i) +{ + int ret; + + ret = KdProcessArgument(argc, argv, i); + return ret; +} |