summaryrefslogtreecommitdiff
path: root/Source/DirectFB/gfxdrivers/matrox
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/gfxdrivers/matrox')
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/Makefile.am47
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/Makefile.in618
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/matrox.c2930
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/matrox.h157
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/matrox_3d.c627
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/matrox_3d.h36
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/matrox_bes.c783
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/matrox_crtc2.c751
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/matrox_maven.c785
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/matrox_maven.h64
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/matrox_screen_crtc2.c279
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/matrox_spic.c314
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/matrox_state.c810
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/matrox_state.h70
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/mmio.h118
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/regs.h454
16 files changed, 8843 insertions, 0 deletions
diff --git a/Source/DirectFB/gfxdrivers/matrox/Makefile.am b/Source/DirectFB/gfxdrivers/matrox/Makefile.am
new file mode 100755
index 0000000..ca445ba
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/Makefile.am
@@ -0,0 +1,47 @@
+## Makefile.am for DirectFB/src/core/gfxcards/matrox
+
+INCLUDES = \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/systems
+
+matrox_LTLIBRARIES = libdirectfb_matrox.la
+
+if BUILD_STATIC
+matrox_DATA = $(matrox_LTLIBRARIES:.la=.o)
+endif
+
+matroxdir = $(MODULEDIR)/gfxdrivers
+
+libdirectfb_matrox_la_SOURCES = \
+ matrox.c \
+ matrox.h \
+ matrox_3d.c \
+ matrox_3d.h \
+ matrox_bes.c \
+ matrox_crtc2.c \
+ matrox_maven.c \
+ matrox_maven.h \
+ matrox_screen_crtc2.c \
+ matrox_spic.c \
+ matrox_state.c \
+ matrox_state.h \
+ regs.h \
+ mmio.h
+
+libdirectfb_matrox_la_LDFLAGS = \
+ -module \
+ -avoid-version \
+ $(DFB_LDFLAGS)
+
+libdirectfb_matrox_la_LIBADD = -lm \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+
+
+include $(top_srcdir)/rules/libobject.make
+
diff --git a/Source/DirectFB/gfxdrivers/matrox/Makefile.in b/Source/DirectFB/gfxdrivers/matrox/Makefile.in
new file mode 100755
index 0000000..f9a3608
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/Makefile.in
@@ -0,0 +1,618 @@
+# 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@
+target_triplet = @target@
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/rules/libobject.make
+subdir = gfxdrivers/matrox
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(matroxdir)" "$(DESTDIR)$(matroxdir)"
+matroxLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(matrox_LTLIBRARIES)
+libdirectfb_matrox_la_DEPENDENCIES = \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+am_libdirectfb_matrox_la_OBJECTS = matrox.lo matrox_3d.lo \
+ matrox_bes.lo matrox_crtc2.lo matrox_maven.lo \
+ matrox_screen_crtc2.lo matrox_spic.lo matrox_state.lo
+libdirectfb_matrox_la_OBJECTS = $(am_libdirectfb_matrox_la_OBJECTS)
+libdirectfb_matrox_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libdirectfb_matrox_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(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 = $(libdirectfb_matrox_la_SOURCES)
+DIST_SOURCES = $(libdirectfb_matrox_la_SOURCES)
+matroxDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(matrox_DATA)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ASFLAGS = @ASFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@
+DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@
+DFB_LDFLAGS = @DFB_LDFLAGS@
+DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@
+DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@
+DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@
+DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@
+DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@
+DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@
+DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@
+DIRECTFB_VERSION = @DIRECTFB_VERSION@
+DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@
+DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@
+DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@
+DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@
+DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@
+DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@
+DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@
+DSYMUTIL = @DSYMUTIL@
+DYNLIB = @DYNLIB@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_PROVIDER = @FREETYPE_PROVIDER@
+FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@
+FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@
+FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@
+GIF_PROVIDER = @GIF_PROVIDER@
+GREP = @GREP@
+HAVE_LINUX = @HAVE_LINUX@
+INCLUDEDIR = @INCLUDEDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@
+JPEG_PROVIDER = @JPEG_PROVIDER@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPNG_CONFIG = @LIBPNG_CONFIG@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_BINARY = @LT_BINARY@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MKDIR_P = @MKDIR_P@
+MODULEDIR = @MODULEDIR@
+MODULEDIRNAME = @MODULEDIRNAME@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+OSX_LIBS = @OSX_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@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PNG_PROVIDER = @PNG_PROVIDER@
+RANLIB = @RANLIB@
+RUNTIME_SYSROOT = @RUNTIME_SYSROOT@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOPATH = @SOPATH@
+STRIP = @STRIP@
+SYSCONFDIR = @SYSCONFDIR@
+SYSFS_LIBS = @SYSFS_LIBS@
+THREADFLAGS = @THREADFLAGS@
+THREADLIB = @THREADLIB@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_LIBS = @TSLIB_LIBS@
+VERSION = @VERSION@
+VNC_CFLAGS = @VNC_CFLAGS@
+VNC_CONFIG = @VNC_CONFIG@
+VNC_LIBS = @VNC_LIBS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+ZLIB_LIBS = @ZLIB_LIBS@
+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@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/systems
+
+matrox_LTLIBRARIES = libdirectfb_matrox.la
+@BUILD_STATIC_TRUE@matrox_DATA = $(matrox_LTLIBRARIES:.la=.o)
+matroxdir = $(MODULEDIR)/gfxdrivers
+libdirectfb_matrox_la_SOURCES = \
+ matrox.c \
+ matrox.h \
+ matrox_3d.c \
+ matrox_3d.h \
+ matrox_bes.c \
+ matrox_crtc2.c \
+ matrox_maven.c \
+ matrox_maven.h \
+ matrox_screen_crtc2.c \
+ matrox_spic.c \
+ matrox_state.c \
+ matrox_state.h \
+ regs.h \
+ mmio.h
+
+libdirectfb_matrox_la_LDFLAGS = \
+ -module \
+ -avoid-version \
+ $(DFB_LDFLAGS)
+
+libdirectfb_matrox_la_LIBADD = -lm \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/rules/libobject.make $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu gfxdrivers/matrox/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu gfxdrivers/matrox/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-matroxLTLIBRARIES: $(matrox_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(matroxdir)" || $(MKDIR_P) "$(DESTDIR)$(matroxdir)"
+ @list='$(matrox_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(matroxLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(matroxdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(matroxLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(matroxdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-matroxLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(matrox_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(matroxdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(matroxdir)/$$p"; \
+ done
+
+clean-matroxLTLIBRARIES:
+ -test -z "$(matrox_LTLIBRARIES)" || rm -f $(matrox_LTLIBRARIES)
+ @list='$(matrox_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libdirectfb_matrox.la: $(libdirectfb_matrox_la_OBJECTS) $(libdirectfb_matrox_la_DEPENDENCIES)
+ $(libdirectfb_matrox_la_LINK) -rpath $(matroxdir) $(libdirectfb_matrox_la_OBJECTS) $(libdirectfb_matrox_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matrox.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matrox_3d.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matrox_bes.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matrox_crtc2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matrox_maven.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matrox_screen_crtc2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matrox_spic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matrox_state.Plo@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
+install-matroxDATA: $(matrox_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(matroxdir)" || $(MKDIR_P) "$(DESTDIR)$(matroxdir)"
+ @list='$(matrox_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(matroxDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(matroxdir)/$$f'"; \
+ $(matroxDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(matroxdir)/$$f"; \
+ done
+
+uninstall-matroxDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(matrox_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(matroxdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(matroxdir)/$$f"; \
+ done
+
+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 $(LTLIBRARIES) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(matroxdir)" "$(DESTDIR)$(matroxdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-matroxLTLIBRARIES \
+ 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-matroxDATA install-matroxLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+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
+
+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-matroxDATA uninstall-matroxLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-matroxLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-matroxDATA install-matroxLTLIBRARIES 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-matroxDATA \
+ uninstall-matroxLTLIBRARIES
+
+%.o: .libs/%.a %.la
+ rm -f $<.tmp/*.o
+ if test -d $<.tmp; then rmdir $<.tmp; fi
+ mkdir $<.tmp
+ (cd $<.tmp && $(AR) x ../../$<)
+ $(LD) -o $@ -r $<.tmp/*.o
+ rm -f $<.tmp/*.o && rmdir $<.tmp
+
+.PHONY: $(LTLIBRARIES:%.la=.libs/%.a)
+# 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/Source/DirectFB/gfxdrivers/matrox/matrox.c b/Source/DirectFB/gfxdrivers/matrox/matrox.c
new file mode 100755
index 0000000..d797251
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/matrox.c
@@ -0,0 +1,2930 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <fbdev/fb.h>
+
+#include <directfb.h>
+
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+#include <core/state.h>
+#include <core/gfxcard.h>
+#include <core/palette.h>
+
+#include <gfx/util.h>
+
+#include <misc/conf.h>
+
+#include <core/graphics_driver.h>
+
+
+DFB_GRAPHICS_DRIVER( matrox )
+
+#include "regs.h"
+#include "mmio.h"
+#include "matrox.h"
+#include "matrox_3d.h"
+#include "matrox_state.h"
+
+
+static bool matroxFillRectangle ( void *drv, void *dev, DFBRectangle *rect );
+static bool matroxFillRectangle_2P ( void *drv, void *dev, DFBRectangle *rect );
+static bool matroxFillRectangle_3P ( void *drv, void *dev, DFBRectangle *rect );
+static bool matroxFillRectangle_422( void *drv, void *dev, DFBRectangle *rect );
+
+static bool matroxBlit2D ( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy );
+static bool matroxBlit2D_2P ( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy );
+static bool matroxBlit2D_3P ( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy );
+static bool matroxBlit2D_422( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy );
+static bool matroxBlit2D_Old( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy );
+
+static bool matroxBlit3D ( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy );
+static bool matroxBlit3D_2P ( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy );
+static bool matroxBlit3D_3P ( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy );
+static bool matroxBlit3D_422( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy );
+
+static bool matroxStretchBlit ( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect );
+static bool matroxStretchBlit_2P ( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect );
+static bool matroxStretchBlit_3P ( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect );
+static bool matroxStretchBlit_422( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect );
+
+
+static bool matroxBlit2D_F ( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy );
+static bool matroxBlit2D_2P_F ( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy );
+static bool matroxBlit2D_3P_F ( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy );
+static bool matroxBlit2D_422_F( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy );
+static bool matroxBlit2D_Old_F( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy );
+
+static bool matroxBlit3D_F ( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy );
+
+static bool matroxStretchBlit_F ( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect );
+static bool matroxStretchBlit_2P_F ( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect );
+static bool matroxStretchBlit_3P_F ( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect );
+static bool matroxStretchBlit_422_F( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect );
+
+
+
+
+/* Millennium */
+
+#define MATROX_2064W_DRAWING_FLAGS (DSDRAW_SRC_PREMULTIPLY)
+
+#define MATROX_2064W_BLITTING_FLAGS (DSBLIT_NOFX)
+
+#define MATROX_2064W_DRAWING_FUNCTIONS (DFXL_FILLRECTANGLE | \
+ DFXL_DRAWRECTANGLE | \
+ DFXL_DRAWLINE | \
+ DFXL_FILLTRIANGLE)
+
+#define MATROX_2064W_BLITTING_FUNCTIONS (DFXL_BLIT)
+
+
+/* Old cards (Mystique, Millennium II) */
+
+#define MATROX_OLD_DRAWING_FLAGS (DSDRAW_SRC_PREMULTIPLY)
+
+#define MATROX_OLD_BLITTING_FLAGS (DSBLIT_SRC_COLORKEY)
+
+#define MATROX_OLD_DRAWING_FUNCTIONS (DFXL_FILLRECTANGLE | \
+ DFXL_DRAWRECTANGLE | \
+ DFXL_DRAWLINE | \
+ DFXL_FILLTRIANGLE)
+
+#define MATROX_OLD_BLITTING_FUNCTIONS (DFXL_BLIT)
+
+
+/* G100 */
+
+#define MATROX_G100_DRAWING_FLAGS (DSDRAW_SRC_PREMULTIPLY)
+
+#define MATROX_G100_BLITTING_FLAGS (DSBLIT_SRC_COLORKEY | \
+ /*DSBLIT_BLEND_ALPHACHANNEL |*/ \
+ /*DSBLIT_BLEND_COLORALPHA |*/ \
+ DSBLIT_COLORIZE | \
+ DSBLIT_SRC_PREMULTCOLOR)
+
+#define MATROX_G100_DRAWING_FUNCTIONS (DFXL_FILLRECTANGLE | \
+ DFXL_DRAWRECTANGLE | \
+ DFXL_DRAWLINE | \
+ DFXL_FILLTRIANGLE)
+
+#define MATROX_G100_BLITTING_FUNCTIONS (DFXL_BLIT | \
+ DFXL_STRETCHBLIT)
+
+
+/* G200/G400 */
+
+#define MATROX_G200G400_DRAWING_FLAGS (DSDRAW_BLEND | \
+ DSDRAW_SRC_PREMULTIPLY)
+
+#define MATROX_G200G400_BLITTING_FLAGS (DSBLIT_SRC_COLORKEY | \
+ DSBLIT_BLEND_ALPHACHANNEL | \
+ DSBLIT_BLEND_COLORALPHA | \
+ DSBLIT_COLORIZE | \
+ DSBLIT_DEINTERLACE | \
+ DSBLIT_SRC_PREMULTIPLY | \
+ DSBLIT_SRC_PREMULTCOLOR)
+
+#define MATROX_G200G400_DRAWING_FUNCTIONS (DFXL_FILLRECTANGLE | \
+ DFXL_DRAWRECTANGLE | \
+ DFXL_DRAWLINE | \
+ DFXL_FILLTRIANGLE)
+
+#define MATROX_G200G400_BLITTING_FUNCTIONS (DFXL_BLIT | \
+ DFXL_STRETCHBLIT | \
+ DFXL_TEXTRIANGLES)
+
+
+#define MATROX_USE_TMU(state, accel) \
+ ((state)->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | \
+ DSBLIT_BLEND_COLORALPHA | \
+ DSBLIT_COLORIZE | \
+ DSBLIT_DEINTERLACE | \
+ DSBLIT_SRC_PREMULTIPLY | \
+ DSBLIT_SRC_PREMULTCOLOR) || \
+ ((state)->destination->config.format != (state)->source->config.format && \
+ (state)->destination->config.format != DSPF_I420 && \
+ (state)->destination->config.format != DSPF_YV12) || \
+ (accel) & (DFXL_STRETCHBLIT | DFXL_TEXTRIANGLES))
+
+#define MATROX_USE_3D(state, accel) \
+ ((DFB_DRAWING_FUNCTION( accel ) && ((state)->drawingflags & DSDRAW_BLEND)) || \
+ (DFB_BLITTING_FUNCTION( accel ) && MATROX_USE_TMU( state, accel )))
+
+static void
+matroxEngineReset( void *drv, void *dev )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mga_waitidle( mdrv, mdev );
+
+ mga_waitfifo( mdrv, mdev, 11 );
+ mga_out32( mmio, 0, TDUALSTAGE0 ); /* multi texture registers */
+ mga_out32( mmio, 0, TDUALSTAGE1 );
+ mga_out32( mmio, 0, ALPHAXINC ); /* alpha increments */
+ mga_out32( mmio, 0, ALPHAYINC );
+ mga_out32( mmio, 0, DR6 ); /* red increments */
+ mga_out32( mmio, 0, DR7 );
+ mga_out32( mmio, 0, DR10 ); /* green increments */
+ mga_out32( mmio, 0, DR11 );
+ mga_out32( mmio, 0, DR14 ); /* blue increments */
+ mga_out32( mmio, 0, DR15 );
+ mga_out32( mmio, 0, BCOL );
+
+ mga_waitfifo( mdrv, mdev, 5 );
+ mga_out32( mmio, 0, TMR1 );
+ mga_out32( mmio, 0, TMR2 );
+ mga_out32( mmio, 0, TMR4 );
+ mga_out32( mmio, 0, TMR5 );
+ mga_out32( mmio, 0x100000, TMR8 );
+
+ /*
+ * Plane write mask is not supported on G100 with SDRAM.
+ * The chip goes crazy if PLNWT is written.
+ */
+ if (mdrv->accelerator != FB_ACCEL_MATROX_MGAG100) {
+ mga_waitfifo( mdrv, mdev, 1 );
+ mga_out32( mmio, 0xFFFFFFFF, PLNWT );
+ }
+}
+
+static DFBResult
+matroxEngineSync( void *drv, void *dev )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ mga_waitidle( mdrv, mdev );
+
+ return DFB_OK;
+}
+
+static void
+matroxFlushTextureCache( void *drv, void *dev )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ mga_waitfifo( mdrv, mdev, 1 );
+ mga_out32( mdrv->mmio_base, 0, TEXORG1 );
+}
+
+static void
+matroxFlushReadCache( void *drv, void *dev )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+
+ mga_out8( mdrv->mmio_base, 0, CACHEFLUSH );
+}
+
+static bool
+matrox_check_blend( MatroxDeviceData *mdev,
+ CardState *state )
+{
+ switch (state->src_blend) {
+ case DSBF_SRCCOLOR:
+ case DSBF_INVSRCCOLOR:
+ return false;
+ case DSBF_SRCALPHASAT:
+ if (!mdev->g550_matrox && state->dst_blend == DSBF_ZERO)
+ return false;
+ default:
+ break;
+ }
+
+ switch (state->dst_blend) {
+ case DSBF_DESTCOLOR:
+ case DSBF_INVDESTCOLOR:
+ case DSBF_SRCALPHASAT:
+ return false;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+static void
+matrox2064WCheckState( void *drv, void *dev,
+ CardState *state, DFBAccelerationMask accel )
+{
+ /* FIXME: 24bit support */
+ switch (state->destination->config.format) {
+ case DSPF_LUT8:
+ if (DFB_BLITTING_FUNCTION( accel ))
+ return;
+ case DSPF_RGB332:
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ case DSPF_A8:
+ break;
+ default:
+ return;
+ }
+
+ if (DFB_DRAWING_FUNCTION( accel )) {
+ if (state->drawingflags & ~MATROX_2064W_DRAWING_FLAGS)
+ return;
+
+ state->accel |= MATROX_2064W_DRAWING_FUNCTIONS;
+ }
+ else {
+ if (state->source->config.format != state->destination->config.format)
+ return;
+
+ if (state->blittingflags & ~MATROX_2064W_BLITTING_FLAGS)
+ return;
+
+ state->accel |= MATROX_2064W_BLITTING_FUNCTIONS;
+ }
+}
+
+static void
+matroxOldCheckState( void *drv, void *dev,
+ CardState *state, DFBAccelerationMask accel )
+{
+ /* FIXME: 24bit support */
+ switch (state->destination->config.format) {
+ case DSPF_LUT8:
+ if (DFB_BLITTING_FUNCTION( accel ))
+ return;
+ case DSPF_RGB332:
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ case DSPF_A8:
+ break;
+ default:
+ return;
+ }
+
+ if (DFB_DRAWING_FUNCTION( accel )) {
+ if (state->drawingflags & ~MATROX_OLD_DRAWING_FLAGS)
+ return;
+
+ state->accel |= MATROX_OLD_DRAWING_FUNCTIONS;
+ }
+ else {
+ if (state->source->config.format != state->destination->config.format)
+ return;
+
+ if (state->blittingflags & ~MATROX_OLD_BLITTING_FLAGS)
+ return;
+
+ state->accel |= MATROX_OLD_BLITTING_FUNCTIONS;
+ }
+}
+
+static void
+matroxG100CheckState( void *drv, void *dev,
+ CardState *state, DFBAccelerationMask accel )
+{
+ /* FIXME: 24bit support */
+ switch (state->destination->config.format) {
+ case DSPF_LUT8:
+ if (DFB_BLITTING_FUNCTION( accel ))
+ return;
+ case DSPF_A8:
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ if (DFB_BLITTING_FUNCTION( accel ) && MATROX_USE_TMU( state, accel ))
+ return;
+ case DSPF_RGB332:
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ break;
+ default:
+ return;
+ }
+
+ if (DFB_DRAWING_FUNCTION( accel )) {
+ if (state->drawingflags & ~MATROX_G100_DRAWING_FLAGS)
+ return;
+
+ state->accel |= MATROX_G100_DRAWING_FUNCTIONS;
+ }
+ else {
+ if (state->blittingflags & ~MATROX_G100_BLITTING_FLAGS)
+ return;
+
+ /* using the texture mapping unit? */
+ if (MATROX_USE_TMU( state, accel )) {
+ int max_width = 2048;
+
+ /* TMU has no 32bit support */
+ switch (state->source->config.format) {
+ case DSPF_LUT8:
+ case DSPF_RGB332:
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ break;
+ default:
+ return;
+ }
+
+ /* Interleaved source -> pitch must be doubled */
+ if ((state->source->config.caps & (DSCAPS_INTERLACED |
+ DSCAPS_SEPARATED)) == DSCAPS_INTERLACED &&
+ (state->destination->config.caps & DSCAPS_INTERLACED ||
+ state->blittingflags & DSBLIT_DEINTERLACE))
+ max_width = 1024;
+
+ /* TMU limits */
+ if (state->source->config.size.w < 8 ||
+ state->source->config.size.h < 8 ||
+ state->source->config.size.w > max_width ||
+ state->source->config.size.h > 2048)
+ return;
+
+ state->accel |= MATROX_G100_BLITTING_FUNCTIONS;
+ }
+ else {
+ /* source and destination formats equal, no stretching is done */
+ state->accel |= accel;
+ }
+ }
+}
+
+static void
+matroxG200CheckState( void *drv, void *dev,
+ CardState *state, DFBAccelerationMask accel )
+{
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ /* FIXME: 24bit support */
+ switch (state->destination->config.format) {
+ case DSPF_NV12:
+ case DSPF_NV21:
+ if ((accel & DFXL_FILLRECTANGLE && !state->drawingflags) ||
+ (accel & DFXL_BLIT && !state->blittingflags &&
+ state->source->config.format == state->destination->config.format))
+ break;
+ return;
+ case DSPF_YUY2:
+ if ((accel & DFXL_FILLRECTANGLE && !state->drawingflags) ||
+ (accel & (DFXL_BLIT | DFXL_STRETCHBLIT) &&
+ !(state->blittingflags & ~DSBLIT_DEINTERLACE) &&
+ state->source->config.format == state->destination->config.format))
+ break;
+ return;
+ case DSPF_LUT8:
+ if (DFB_BLITTING_FUNCTION( accel ))
+ return;
+ case DSPF_A8:
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ if (MATROX_USE_3D( state, accel ))
+ return;
+ case DSPF_RGB332:
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ break;
+ default:
+ return;
+ }
+
+ if (DFB_DRAWING_FUNCTION( accel )) {
+ if (state->drawingflags & ~MATROX_G200G400_DRAWING_FLAGS)
+ return;
+
+ if (state->drawingflags & DSDRAW_BLEND &&
+ !matrox_check_blend( mdev, state ))
+ return;
+
+ state->accel |= MATROX_G200G400_DRAWING_FUNCTIONS;
+ }
+ else {
+ bool use_tmu = MATROX_USE_TMU( state, accel );
+
+ switch (state->source->config.format) {
+ case DSPF_NV12:
+ case DSPF_NV21:
+ if (state->destination->config.format != state->source->config.format)
+ return;
+ break;
+ case DSPF_A8:
+ if (use_tmu)
+ return;
+ case DSPF_LUT8:
+ case DSPF_RGB332:
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ case DSPF_YUY2:
+ break;
+ default:
+ return;
+ }
+
+ if (state->blittingflags & ~MATROX_G200G400_BLITTING_FLAGS)
+ return;
+
+ if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
+ if (!matrox_check_blend( mdev, state ))
+ return;
+
+ if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY &&
+ (state->src_blend != DSBF_ONE ||
+ (state->dst_blend != DSBF_INVSRCALPHA &&
+ state->dst_blend != DSBF_INVSRCCOLOR)))
+ return;
+ } else {
+ if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY)
+ return;
+ }
+
+ if (use_tmu) {
+ int max_width = 2048;
+
+ /* Interleaved source -> pitch must be doubled */
+ if ((state->source->config.caps & (DSCAPS_INTERLACED |
+ DSCAPS_SEPARATED)) == DSCAPS_INTERLACED &&
+ (state->destination->config.caps & DSCAPS_INTERLACED ||
+ state->blittingflags & DSBLIT_DEINTERLACE) &&
+ state->destination->config.format != DSPF_YUY2)
+ max_width = 1024;
+
+ if (state->source->config.size.w < 8 ||
+ state->source->config.size.h < 8 ||
+ state->source->config.size.w > max_width ||
+ state->source->config.size.h > 2048)
+ return;
+
+ state->accel |= MATROX_G200G400_BLITTING_FUNCTIONS;
+ }
+ else {
+ /* source and destination formats equal, no stretching is done */
+ state->accel |= accel;
+ }
+ }
+}
+
+static void
+matroxG400CheckState( void *drv, void *dev,
+ CardState *state, DFBAccelerationMask accel )
+{
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ /* FIXME: 24bit support */
+ switch (state->destination->config.format) {
+ case DSPF_I420:
+ case DSPF_YV12:
+ if ((accel & DFXL_FILLRECTANGLE && !state->drawingflags) ||
+ (accel & (DFXL_BLIT | DFXL_STRETCHBLIT) &&
+ !(state->blittingflags & ~DSBLIT_DEINTERLACE) &&
+ (state->source->config.format == DSPF_I420 ||
+ state->source->config.format == DSPF_YV12)))
+ break;
+ return;
+ case DSPF_NV12:
+ case DSPF_NV21:
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ if ((accel & DFXL_FILLRECTANGLE && !state->drawingflags) ||
+ (accel & (DFXL_BLIT | DFXL_STRETCHBLIT) &&
+ !(state->blittingflags & ~DSBLIT_DEINTERLACE) &&
+ state->source->config.format == state->destination->config.format))
+ break;
+ return;
+ case DSPF_LUT8:
+ case DSPF_ALUT44:
+ if (DFB_BLITTING_FUNCTION( accel ))
+ return;
+ case DSPF_A8:
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ if (MATROX_USE_3D( state, accel ))
+ return;
+ case DSPF_RGB332:
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ break;
+ default:
+ return;
+ }
+
+ if (DFB_DRAWING_FUNCTION( accel )) {
+ if (state->drawingflags & ~MATROX_G200G400_DRAWING_FLAGS)
+ return;
+
+ if (state->drawingflags & DSDRAW_BLEND &&
+ !matrox_check_blend( mdev, state ))
+ return;
+
+ state->accel |= MATROX_G200G400_DRAWING_FUNCTIONS;
+ }
+ else {
+ bool use_tmu = MATROX_USE_TMU( state, accel );
+
+ switch (state->source->config.format) {
+ case DSPF_I420:
+ case DSPF_YV12:
+ if (state->destination->config.format != DSPF_I420 &&
+ state->destination->config.format != DSPF_YV12)
+ return;
+ break;
+ case DSPF_NV12:
+ case DSPF_NV21:
+ if (state->destination->config.format != state->source->config.format)
+ return;
+ break;
+ case DSPF_RGB332:
+ if (use_tmu)
+ return;
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ case DSPF_A8:
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ break;
+ default:
+ return;
+ }
+
+ if (state->blittingflags & ~MATROX_G200G400_BLITTING_FLAGS)
+ return;
+
+ if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
+ if (!matrox_check_blend( mdev, state ))
+ return;
+
+ if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY &&
+ (state->src_blend != DSBF_ONE ||
+ (state->dst_blend != DSBF_INVSRCALPHA &&
+ state->dst_blend != DSBF_INVSRCCOLOR)))
+ return;
+ } else {
+ if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY)
+ return;
+ }
+
+ if (use_tmu) {
+ int max_width = 2048;
+
+ /* Interleaved source -> pitch must be doubled */
+ if ((state->source->config.caps & (DSCAPS_INTERLACED |
+ DSCAPS_SEPARATED)) == DSCAPS_INTERLACED &&
+ (state->destination->config.caps & DSCAPS_INTERLACED ||
+ state->blittingflags & DSBLIT_DEINTERLACE) &&
+ state->destination->config.format != DSPF_YUY2 &&
+ state->destination->config.format != DSPF_UYVY)
+ max_width = 1024;
+
+ if (state->source->config.size.w < 8 ||
+ state->source->config.size.h < 8 ||
+ state->source->config.size.w > max_width ||
+ state->source->config.size.h > 2048)
+ return;
+
+ state->accel |= MATROX_G200G400_BLITTING_FUNCTIONS;
+ }
+ else {
+ /* source and destination formats equal, no stretching is done */
+ state->accel |= accel;
+ }
+ }
+}
+
+static void
+matroxSetState( void *drv, void *dev,
+ GraphicsDeviceFuncs *funcs,
+ CardState *state, DFBAccelerationMask accel )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ bool prev_blit_fields = mdev->blit_fields;
+
+ if (state->mod_hw == SMF_ALL) {
+ mdev->valid = 0;
+
+ /*
+ * Work around TMU bug(?), under some unclear circumstances
+ * the TMU's read address (src & dst) gets corrupted (negative offset
+ * applied to written values) until soft reset occured.
+ */
+ if (mdrv->accelerator == FB_ACCEL_MATROX_MGAG200)
+ mga_waitidle( mdrv, mdev );
+ }
+ else if (state->mod_hw) {
+ if (state->mod_hw & SMF_COLOR)
+ MGA_INVALIDATE( m_drawColor | m_blitColor | m_color );
+
+ if (state->mod_hw & SMF_CLIP)
+ MGA_INVALIDATE( m_clip );
+
+ if (state->mod_hw & SMF_DESTINATION)
+ MGA_INVALIDATE( m_destination | m_clip | m_color | m_Source | m_source );
+
+ if (state->mod_hw & SMF_SOURCE)
+ MGA_INVALIDATE( m_Source | m_source | m_SrcKey | m_srckey | m_blitBlend );
+ else if (state->mod_hw & SMF_SRC_COLORKEY)
+ MGA_INVALIDATE( m_SrcKey | m_srckey );
+
+ if (state->mod_hw & SMF_DRAWING_FLAGS)
+ MGA_INVALIDATE( m_drawColor | m_color );
+
+ if (state->mod_hw & SMF_BLITTING_FLAGS)
+ MGA_INVALIDATE( m_Source | m_SrcKey | m_blitBlend | m_blitColor );
+
+ if (state->mod_hw & (SMF_DST_BLEND | SMF_SRC_BLEND))
+ MGA_INVALIDATE( m_blitBlend | m_drawBlend );
+ }
+
+ switch (accel) {
+ case DFXL_BLIT:
+ mdev->blit_deinterlace = state->blittingflags & DSBLIT_DEINTERLACE;
+ mdev->blit_fields = !mdev->blit_deinterlace &&
+ state->source->config.caps & DSCAPS_INTERLACED &&
+ state->destination->config.caps & DSCAPS_INTERLACED &&
+ (state->source->config.caps & DSCAPS_SEPARATED ||
+ state->destination->config.caps & DSCAPS_SEPARATED);
+ break;
+ case DFXL_STRETCHBLIT:
+ mdev->blit_deinterlace = state->blittingflags & DSBLIT_DEINTERLACE;
+ mdev->blit_fields = !mdev->blit_deinterlace &&
+ state->source->config.caps & DSCAPS_INTERLACED &&
+ state->destination->config.caps & DSCAPS_INTERLACED;
+ break;
+ default:
+ mdev->blit_deinterlace = 0;
+ mdev->blit_fields = 0;
+ }
+
+ if (prev_blit_fields != mdev->blit_fields)
+ MGA_INVALIDATE( m_destination | m_source | m_Source );
+
+ switch (accel) {
+ case DFXL_FILLRECTANGLE:
+ case DFXL_DRAWRECTANGLE:
+ case DFXL_DRAWLINE:
+ case DFXL_FILLTRIANGLE:
+ if (state->drawingflags & DSDRAW_BLEND) {
+ mdev->draw_blend = 1;
+ matrox_validate_drawColor( mdrv, mdev, state );
+ matrox_validate_drawBlend( mdrv, mdev, state );
+ }
+ else {
+ mdev->draw_blend = 0;
+ matrox_validate_color( mdrv, mdev, state );
+ }
+
+ switch (state->destination->config.format) {
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ funcs->FillRectangle = matroxFillRectangle_422;
+ state->set = DFXL_FILLRECTANGLE;
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ funcs->FillRectangle = matroxFillRectangle_3P;
+ state->set = DFXL_FILLRECTANGLE;
+ break;
+ case DSPF_NV12:
+ case DSPF_NV21:
+ funcs->FillRectangle = matroxFillRectangle_2P;
+ state->set = DFXL_FILLRECTANGLE;
+ break;
+ default:
+ funcs->FillRectangle = matroxFillRectangle;
+ state->set = DFXL_FILLRECTANGLE | DFXL_DRAWRECTANGLE |
+ DFXL_DRAWLINE | DFXL_FILLTRIANGLE;
+ }
+ break;
+ case DFXL_BLIT:
+ case DFXL_STRETCHBLIT:
+ case DFXL_TEXTRIANGLES:
+ mdev->blit_src_colorkey = state->blittingflags & DSBLIT_SRC_COLORKEY;
+
+ if (MATROX_USE_TMU( state, accel )) {
+ if (state->blittingflags & (DSBLIT_BLEND_COLORALPHA |
+ DSBLIT_COLORIZE |
+ DSBLIT_SRC_PREMULTCOLOR))
+ matrox_validate_blitColor( mdrv, mdev, state );
+
+ switch (state->destination->config.format) {
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ if (mdev->blit_fields) {
+ funcs->Blit = NULL;
+ funcs->StretchBlit = matroxStretchBlit_422_F;
+ } else {
+ funcs->Blit = matroxBlit3D_422;
+ funcs->StretchBlit = matroxStretchBlit_422;
+ }
+ state->set = DFXL_BLIT | DFXL_STRETCHBLIT;
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ if (mdev->blit_fields) {
+ funcs->Blit = NULL;
+ funcs->StretchBlit = matroxStretchBlit_3P_F;
+ } else {
+ funcs->Blit = matroxBlit3D_3P;
+ funcs->StretchBlit = matroxStretchBlit_3P;
+ }
+ state->set = DFXL_BLIT | DFXL_STRETCHBLIT;
+ break;
+ case DSPF_NV12:
+ case DSPF_NV21:
+ if (mdev->blit_fields) {
+ funcs->Blit = NULL;
+ funcs->StretchBlit = matroxStretchBlit_2P_F;
+ } else {
+ funcs->Blit = matroxBlit3D_2P;
+ funcs->StretchBlit = matroxStretchBlit_2P;
+ }
+ state->set = DFXL_BLIT | DFXL_STRETCHBLIT;
+ break;
+ default:
+ if (mdev->blit_fields) {
+ funcs->Blit = matroxBlit3D_F;
+ funcs->StretchBlit = matroxStretchBlit_F;
+ } else {
+ funcs->Blit = matroxBlit3D;
+ funcs->StretchBlit = matroxStretchBlit;
+ }
+ state->set = DFXL_BLIT | DFXL_STRETCHBLIT | DFXL_TEXTRIANGLES;
+ }
+
+ matrox_validate_blitBlend( mdrv, mdev, state );
+ matrox_validate_Source( mdrv, mdev, state );
+
+ matrox_validate_SrcKey( mdrv, mdev, state );
+ }
+ else {
+ switch (state->destination->config.format) {
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ funcs->Blit = mdev->blit_fields ?
+ matroxBlit2D_422_F : matroxBlit2D_422;
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ funcs->Blit = mdev->blit_fields ?
+ matroxBlit2D_3P_F : matroxBlit2D_3P;
+ break;
+ case DSPF_NV12:
+ case DSPF_NV21:
+ funcs->Blit = mdev->blit_fields ?
+ matroxBlit2D_2P_F : matroxBlit2D_2P;
+ break;
+ default:
+ if (mdev->old_matrox)
+ funcs->Blit = mdev->blit_fields ?
+ matroxBlit2D_Old_F : matroxBlit2D_Old;
+ else
+ funcs->Blit = mdev->blit_fields ?
+ matroxBlit2D_F : matroxBlit2D;
+ }
+
+ matrox_validate_source( mdrv, mdev, state );
+
+ if (mdev->blit_src_colorkey)
+ matrox_validate_srckey( mdrv, mdev, state );
+
+ state->set = DFXL_BLIT;
+ }
+ break;
+ default:
+ D_BUG( "unexpected drawing/blitting function!" );
+ break;
+ }
+
+ matrox_validate_destination( mdrv, mdev, state );
+
+ if (!MGA_IS_VALID( m_clip )) {
+ mdev->clip = state->clip;
+ if (state->destination->config.format == DSPF_YUY2 ||
+ state->destination->config.format == DSPF_UYVY) {
+ mdev->clip.x1 /= 2;
+ mdev->clip.x2 /= 2;
+ }
+ if (mdev->blit_fields) {
+ mdev->clip.y1 /= 2;
+ mdev->clip.y2 /= 2;
+ }
+ matrox_set_clip( mdrv, mdev, &mdev->clip );
+ MGA_VALIDATE( m_clip );
+ }
+
+ state->mod_hw = 0;
+}
+
+/******************************************************************************/
+
+static void
+matrox_fill_rectangle( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ DFBRectangle *rect )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mga_waitfifo( mdrv, mdev, 3 );
+
+ if (mdev->draw_blend)
+ mga_out32( mmio, BOP_COPY | SHFTZERO | SGNZERO |
+ ARZERO | ATYPE_I | OP_TRAP, DWGCTL );
+ else
+ mga_out32( mmio, TRANSC | BOP_COPY | SHFTZERO | SGNZERO | ARZERO |
+ SOLID | mdev->atype_blk_rstr | OP_TRAP, DWGCTL );
+
+ mga_out32( mmio, (RS16(rect->x + rect->w) << 16) | RS16(rect->x), FXBNDRY );
+ mga_out32( mmio, (RS16(rect->y) << 16) | RS16(rect->h), YDSTLEN | EXECUTE );
+}
+
+static bool
+matroxFillRectangle( void *drv, void *dev, DFBRectangle *rect )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ matrox_fill_rectangle( mdrv, mdev, rect );
+
+ return true;
+}
+
+static bool
+matroxFillRectangle_2P( void *drv, void *dev, DFBRectangle *rect )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ matrox_fill_rectangle( mdrv, mdev, rect );
+
+ rect->x /= 2;
+ rect->y /= 2;
+ rect->w = (rect->w + 1) / 2;
+ rect->h = (rect->h + 1) / 2;
+
+ /* CbCr plane */
+ mga_waitfifo( mdrv, mdev, 7 );
+ mga_out32( mmio, PW16 | NODITHER, MACCESS );
+ mga_out32( mmio, mdev->color[1], FCOL );
+ mga_out32( mmio, mdev->dst_pitch/2, PITCH );
+ mga_out32( mmio, mdev->dst_offset[0][1], DSTORG );
+
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y1 / 4) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y2 / 4) & 0xFFFFFF, YBOT );
+ mga_out32( mmio, ((mdev->clip.x2/2 & 0x0FFF) << 16) | (mdev->clip.x1/2 & 0x0FFF), CXBNDRY );
+
+ matrox_fill_rectangle( mdrv, mdev, rect );
+
+ /* Restore registers */
+ mga_waitfifo( mdrv, mdev, 4 );
+ mga_out32( mmio, PW8 | BYPASS332 | NODITHER, MACCESS );
+ mga_out32( mmio, mdev->color[0], FCOL );
+ mga_out32( mmio, mdev->dst_pitch, PITCH );
+ mga_out32( mmio, mdev->dst_offset[0][0], DSTORG );
+
+ matrox_set_clip( mdrv, mdev, &mdev->clip );
+
+ return true;
+}
+
+static bool
+matroxFillRectangle_3P( void *drv, void *dev, DFBRectangle *rect )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ matrox_fill_rectangle( mdrv, mdev, rect );
+
+ rect->x /= 2;
+ rect->y /= 2;
+ rect->w = (rect->w + 1) / 2;
+ rect->h = (rect->h + 1) / 2;
+
+ /* Cb plane */
+ mga_waitfifo( mdrv, mdev, 6 );
+ mga_out32( mmio, mdev->color[1], FCOL );
+ mga_out32( mmio, mdev->dst_pitch/2, PITCH );
+ mga_out32( mmio, mdev->dst_offset[0][1], DSTORG );
+
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y1 / 4) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y2 / 4) & 0xFFFFFF, YBOT );
+ mga_out32( mmio, ((mdev->clip.x2/2 & 0x0FFF) << 16) | (mdev->clip.x1/2 & 0x0FFF), CXBNDRY );
+
+ matrox_fill_rectangle( mdrv, mdev, rect );
+
+ /* Cr plane */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->color[2], FCOL );
+ mga_out32( mmio, mdev->dst_offset[0][2], DSTORG );
+
+ matrox_fill_rectangle( mdrv, mdev, rect );
+
+ /* Restore registers */
+ mga_waitfifo( mdrv, mdev, 3 );
+ mga_out32( mmio, mdev->color[0], FCOL );
+ mga_out32( mmio, mdev->dst_pitch, PITCH );
+ mga_out32( mmio, mdev->dst_offset[0][0], DSTORG );
+
+ matrox_set_clip( mdrv, mdev, &mdev->clip );
+
+ return true;
+}
+
+static bool
+matroxFillRectangle_422( void *drv, void *dev, DFBRectangle *rect )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ rect->x /= 2;
+ rect->w = (rect->w + 1) / 2;
+
+ matrox_fill_rectangle( mdrv, mdev, rect );
+
+ return true;
+}
+
+static bool
+matroxDrawRectangle( void *drv, void *dev, DFBRectangle *rect )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mga_waitfifo( mdrv, mdev, 6 );
+
+ if (mdev->draw_blend)
+ mga_out32( mmio, BLTMOD_BFCOL | BOP_COPY | ATYPE_I |
+ OP_AUTOLINE_OPEN, DWGCTL );
+ else
+ mga_out32( mmio, BLTMOD_BFCOL | BOP_COPY | SHFTZERO | SOLID |
+ ATYPE_RSTR | OP_AUTOLINE_OPEN, DWGCTL );
+
+ mga_out32(mmio, RS16(rect->x) |
+ (RS16(rect->y) << 16),
+ XYSTRT);
+
+ mga_out32(mmio, RS16(rect->x + rect->w-1) | (RS16(rect->y) << 16),
+ XYEND | EXECUTE);
+
+ mga_out32(mmio, RS16(rect->x + rect->w-1) |
+ (RS16(rect->y + rect->h-1) << 16),
+ XYEND | EXECUTE);
+
+ mga_out32(mmio, RS16(rect->x) |
+ (RS16(rect->y + rect->h-1) << 16),
+ XYEND | EXECUTE);
+
+ mga_out32(mmio, RS16(rect->x) |
+ (RS16(rect->y) << 16),
+ XYEND | EXECUTE);
+
+ return true;
+}
+
+static bool
+matroxDrawLine( void *drv, void *dev, DFBRegion *line )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mga_waitfifo( mdrv, mdev, 3 );
+
+ if (mdev->draw_blend)
+ mga_out32( mmio, BLTMOD_BFCOL | BOP_COPY | ATYPE_I |
+ OP_AUTOLINE_CLOSE,
+ DWGCTL );
+ else
+ mga_out32( mmio, BLTMOD_BFCOL | BOP_COPY | SHFTZERO | SOLID |
+ ATYPE_RSTR | OP_AUTOLINE_CLOSE,
+ DWGCTL );
+
+ mga_out32( mmio, RS16(line->x1) | (RS16(line->y1) << 16),
+ XYSTRT );
+
+ mga_out32( mmio, RS16(line->x2) | (RS16(line->y2) << 16),
+ XYEND | EXECUTE );
+
+ return true;
+}
+
+/******************************************************************************/
+
+static void
+matrox_fill_trapezoid( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ int Xl, int Xr, int X2l,
+ int X2r, int Y, int dY )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ int dxl = X2l - Xl;
+ int dxr = ++X2r - ++Xr;
+
+ int dXl = ABS(dxl);
+ int dXr = ABS(dxr);
+
+ u32 sgn = 0;
+
+ mga_waitfifo( mdrv, mdev, 6 );
+
+ mga_out32( mmio, dY, AR0 );
+ mga_out32( mmio, - dXl, AR1 );
+ mga_out32( mmio, - dXl, AR2 );
+ mga_out32( mmio, - dXr, AR4 );
+ mga_out32( mmio, - dXr, AR5 );
+ mga_out32( mmio, dY, AR6 );
+
+ if (dxl < 0)
+ sgn |= SDXL;
+ if (dxr < 0)
+ sgn |= SDXR;
+
+ mga_waitfifo( mdrv, mdev, 3 );
+
+ mga_out32( mmio, sgn, SGN );
+ mga_out32( mmio, (RS16(Xr) << 16) | RS16(Xl), FXBNDRY );
+ mga_out32( mmio, (RS16(Y) << 16) | RS16(dY), YDSTLEN | EXECUTE );
+}
+
+static bool
+matroxFillTriangle( void *drv, void *dev, DFBTriangle *tri )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mga_waitfifo( mdrv, mdev, 1 );
+
+ if (mdev->draw_blend)
+ mga_out32( mmio, BOP_COPY | SHFTZERO | ATYPE_I | OP_TRAP,
+ DWGCTL );
+ else
+ mga_out32( mmio, TRANSC | BOP_COPY | SHFTZERO |
+ SOLID | mdev->atype_blk_rstr | OP_TRAP,
+ DWGCTL );
+
+ dfb_sort_triangle( tri );
+
+ if (tri->y2 == tri->y3) {
+ matrox_fill_trapezoid( mdrv, mdev, tri->x1, tri->x1,
+ MIN( tri->x2, tri->x3 ), MAX( tri->x2, tri->x3 ),
+ tri->y1, tri->y3 - tri->y1 + 1 );
+ } else
+ if (tri->y1 == tri->y2) {
+ matrox_fill_trapezoid( mdrv, mdev,
+ MIN( tri->x1, tri->x2 ), MAX( tri->x1, tri->x2 ),
+ tri->x3, tri->x3, tri->y1, tri->y3 - tri->y1 + 1 );
+ }
+ else {
+ int majDx = tri->x3 - tri->x1;
+ int majDy = tri->y3 - tri->y1;
+ int topDx = tri->x2 - tri->x1;
+ int topDy = tri->y2 - tri->y1;
+ int botDy = tri->y3 - tri->y2;
+
+ int topXperY = (topDx << 20) / topDy;
+ int X2a = tri->x1 + (((topXperY * topDy) + (1<<19)) >> 20);
+
+ int majXperY = (majDx << 20) / majDy;
+ int majX2 = tri->x1 + (((majXperY * topDy) + (1<<19)) >> 20);
+ int majX2a = majX2 - ((majXperY + (1<<19)) >> 20);
+
+ matrox_fill_trapezoid( mdrv, mdev, tri->x1, tri->x1,
+ MIN( X2a, majX2a ), MAX( X2a, majX2a ),
+ tri->y1, topDy );
+ matrox_fill_trapezoid( mdrv, mdev,
+ MIN( tri->x2, majX2 ), MAX( tri->x2, majX2 ),
+ tri->x3, tri->x3, tri->y2, botDy + 1 );
+ }
+
+ return true;
+}
+
+/******************************************************************************/
+
+static void
+matroxDoBlit2D_Old( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ int sx, int sy,
+ int dx, int dy,
+ int w, int h,
+ int pitch, int offset )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ u32 dwgctl = BLTMOD_BFCOL | BOP_COPY | SHFTZERO | ATYPE_RSTR | OP_BITBLT;
+ u32 start, end;
+ u32 sgn = 0;
+ s32 pixelpitch = pitch;
+
+ if (sx < dx)
+ sgn |= BLIT_LEFT;
+ if (sy < dy)
+ sgn |= BLIT_UP;
+
+ if (sgn & BLIT_UP) {
+ sy += h - 1;
+ dy += h - 1;
+ }
+
+ start = sy * pixelpitch + sx + offset;
+
+ w--;
+
+ end = w;
+
+ if (sgn & BLIT_LEFT) {
+ start += w;
+ end = -end;
+ }
+
+ if (sgn & BLIT_UP)
+ pixelpitch = -pixelpitch;
+
+ if (mdev->blit_src_colorkey)
+ dwgctl |= TRANSC;
+
+ mga_waitfifo( mdrv, mdev, 7 );
+ mga_out32( mmio, dwgctl, DWGCTL );
+ mga_out32( mmio, pixelpitch & 0x3FFFFF, AR5 );
+ mga_out32( mmio, start & 0xFFFFFF, AR3 );
+ mga_out32( mmio, end & 0x3FFFF, AR0 );
+ mga_out32( mmio, sgn, SGN );
+ mga_out32( mmio, (RS16(dx+w) << 16) | RS16(dx), FXBNDRY );
+ mga_out32( mmio, (RS16(dy) << 16) | RS16(h), YDSTLEN | EXECUTE );
+}
+
+static bool
+matroxBlit2D_Old( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ matroxDoBlit2D_Old( mdrv, mdev,
+ rect->x, rect->y,
+ dx, dy,
+ rect->w, rect->h,
+ mdev->src_pitch,
+ mdev->src_offset[0][0] );
+
+ return true;
+}
+
+static bool
+matroxBlit2D_Old_F( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+ int src_field, dst_field;
+
+ src_field = rect->y & 1;
+ dst_field = dy & 1;
+
+ /* fisrt field */
+ mga_waitfifo( mdrv, mdev, 1 );
+ mga_out32( mmio, mdev->dst_offset[dst_field][0], DSTORG );
+
+ matroxDoBlit2D_Old( mdrv, mdev,
+ rect->x, rect->y/2,
+ dx, dy/2,
+ rect->w, (rect->h+1)/2,
+ mdev->src_pitch,
+ mdev->src_offset[src_field][0] );
+
+ /* Second field */
+ mga_waitfifo( mdrv, mdev, 1 );
+ mga_out32( mmio, mdev->dst_offset[!dst_field][0], DSTORG );
+
+ matroxDoBlit2D_Old( mdrv, mdev,
+ rect->x, (rect->y+1)/2,
+ dx, (dy+1)/2,
+ rect->w, rect->h/2,
+ mdev->src_pitch,
+ mdev->src_offset[!src_field][0] );
+
+ /* Restore registers */
+ mga_waitfifo( mdrv, mdev, 1 );
+ mga_out32( mmio, mdev->dst_offset[0][0], DSTORG );
+
+ return true;
+}
+
+/******************************************************************************/
+
+static void
+matroxDoBlit2D( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ int sx, int sy,
+ int dx, int dy,
+ int w, int h,
+ int pitch )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ u32 dwgctl = BLTMOD_BFCOL | BOP_COPY | SHFTZERO | ATYPE_RSTR | OP_BITBLT;
+ u32 start, end;
+ u32 sgn = 0;
+ s32 pixelpitch = pitch;
+
+ if (sx < dx)
+ sgn |= BLIT_LEFT;
+ if (sy < dy)
+ sgn |= BLIT_UP;
+
+ if (sgn & BLIT_UP) {
+ sy += h - 1;
+ dy += h - 1;
+ }
+
+ start = end = sy * pixelpitch + sx;
+
+ w--;
+
+ if (sgn & BLIT_LEFT)
+ start += w;
+ else
+ end += w;
+
+ if (sgn & BLIT_UP)
+ pixelpitch = -pixelpitch;
+
+ if (mdev->blit_src_colorkey)
+ dwgctl |= TRANSC;
+
+ mga_waitfifo( mdrv, mdev, 7 );
+ mga_out32( mmio, dwgctl, DWGCTL );
+ mga_out32( mmio, pixelpitch & 0x3FFFFF, AR5 );
+ mga_out32( mmio, start & 0xFFFFFF, AR3 );
+ mga_out32( mmio, end & 0x3FFFFF, AR0 );
+ mga_out32( mmio, sgn, SGN );
+ mga_out32( mmio, (RS16(dx+w) << 16) | RS16(dx), FXBNDRY );
+ mga_out32( mmio, (RS16(dy) << 16) | RS16(h), YDSTLEN | EXECUTE );
+}
+
+static bool
+matroxBlit2D( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, rect->y,
+ dx, dy,
+ rect->w, rect->h,
+ mdev->src_pitch );
+
+ return true;
+}
+
+static bool
+matroxBlit2D_2P( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, rect->y,
+ dx, dy,
+ rect->w, rect->h,
+ mdev->src_pitch );
+
+ rect->x &= ~1;
+ rect->y /= 2;
+ rect->w = (rect->w + 1) & ~1;
+ rect->h = (rect->h + 1) / 2;
+ dx &= ~1;
+ dy /= 2;
+
+ /* CbCr plane */
+ mga_waitfifo( mdrv, mdev, 4 );
+ mga_out32( mmio, mdev->src_offset[0][1], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[0][1], DSTORG );
+
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y1 / 2) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y2 / 2) & 0xFFFFFF, YBOT );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, rect->y,
+ dx, dy,
+ rect->w, rect->h,
+ mdev->src_pitch );
+
+ /* Restore registers */
+ mga_waitfifo( mdrv, mdev, 4 );
+ mga_out32( mmio, mdev->src_offset[0][0], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[0][0], DSTORG );
+
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y1) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y2) & 0xFFFFFF, YBOT );
+
+ return true;
+}
+
+static bool
+matroxBlit2D_3P( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, rect->y,
+ dx, dy,
+ rect->w, rect->h,
+ mdev->src_pitch );
+
+ rect->x /= 2;
+ rect->y /= 2;
+ rect->w = (rect->w + 1) / 2;
+ rect->h = (rect->h + 1) / 2;
+ dx /= 2;
+ dy /= 2;
+
+ /* Cb plane */
+ mga_waitfifo( mdrv, mdev, 6 );
+ mga_out32( mmio, mdev->src_offset[0][1], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[0][1], DSTORG );
+ mga_out32( mmio, mdev->dst_pitch/2, PITCH );
+
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y1 / 4) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y2 / 4) & 0xFFFFFF, YBOT );
+ mga_out32( mmio, ((mdev->clip.x2/2 & 0x0FFF) << 16) | (mdev->clip.x1/2 & 0x0FFF), CXBNDRY );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, rect->y,
+ dx, dy,
+ rect->w, rect->h,
+ mdev->src_pitch/2 );
+
+ /* Cr plane */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[0][2], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[0][2], DSTORG );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, rect->y,
+ dx, dy,
+ rect->w, rect->h,
+ mdev->src_pitch/2 );
+
+ /* Restore registers */
+ mga_waitfifo( mdrv, mdev, 3 );
+ mga_out32( mmio, mdev->src_offset[0][0], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[0][0], DSTORG );
+ mga_out32( mmio, mdev->dst_pitch, PITCH );
+
+ matrox_set_clip( mdrv, mdev, &mdev->clip );
+
+ return true;
+}
+
+static bool
+matroxBlit2D_422( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ dx /= 2;
+ rect->x /= 2;
+ rect->w = (rect->w + 1) / 2;
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, rect->y,
+ dx, dy,
+ rect->w, rect->h,
+ mdev->src_pitch );
+
+ return true;
+}
+
+static bool
+matroxBlit2D_F( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+ int src_field, dst_field;
+
+ src_field = rect->y & 1;
+ dst_field = dy & 1;
+
+ /* First field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[src_field][0], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[dst_field][0], DSTORG );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, rect->y/2,
+ dx, dy/2,
+ rect->w, (rect->h+1)/2,
+ mdev->src_pitch );
+
+ /* Second field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[!src_field][0], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[!dst_field][0], DSTORG );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, (rect->y+1)/2,
+ dx, (dy+1)/2,
+ rect->w, rect->h/2,
+ mdev->src_pitch );
+
+ /* Restore registers */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[0][0], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[0][0], DSTORG );
+
+ return true;
+}
+
+static bool
+matroxBlit2D_2P_F( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+ int src_field, dst_field;
+
+ src_field = rect->y & 1;
+ dst_field = dy & 1;
+
+ /* Y plane */
+ /* First field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[src_field][0], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[dst_field][0], DSTORG );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, rect->y/2,
+ dx, dy/2,
+ rect->w, (rect->h+1)/2,
+ mdev->src_pitch );
+
+ /* Second field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[!src_field][0], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[!dst_field][0], DSTORG );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, (rect->y+1)/2,
+ dx, (dy+1)/2,
+ rect->w, rect->h/2,
+ mdev->src_pitch );
+
+ /* Subsampling */
+ rect->x &= ~1;
+ rect->y /= 2;
+ rect->w = (rect->w + 1) & ~1;
+ rect->h = (rect->h + 1) / 2;
+ dx &= ~1;
+ dy /= 2;
+
+ mga_waitfifo( mdrv, mdev, 4 );
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y1/2) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y2/2) & 0xFFFFFF, YBOT );
+
+ /* CbCr plane */
+ /* First field */
+ mga_out32( mmio, mdev->src_offset[src_field][1], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[dst_field][1], DSTORG );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, rect->y/2,
+ dx, dy/2,
+ rect->w, (rect->h+1)/2,
+ mdev->src_pitch );
+
+ /* Second field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[!src_field][1], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[!dst_field][1], DSTORG );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, (rect->y+1)/2,
+ dx, (dy+1)/2,
+ rect->w, rect->h/2,
+ mdev->src_pitch );
+
+ /* Restore registers */
+ mga_waitfifo( mdrv, mdev, 4 );
+ mga_out32( mmio, mdev->src_offset[0][0], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[0][0], DSTORG );
+
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y1) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y2) & 0xFFFFFF, YBOT );
+
+ return true;
+}
+
+static bool
+matroxBlit2D_3P_F( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+ int src_field, dst_field;
+
+ src_field = rect->y & 1;
+ dst_field = dy & 1;
+
+ /* Y plane */
+ /* First field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[src_field][0], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[dst_field][0], DSTORG );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, rect->y/2,
+ dx, dy/2,
+ rect->w, (rect->h+1)/2,
+ mdev->src_pitch );
+
+ /* Second field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[!src_field][0], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[!dst_field][0], DSTORG );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, (rect->y+1)/2,
+ dx, (dy+1)/2,
+ rect->w, rect->h/2,
+ mdev->src_pitch );
+
+ /* Subsampling */
+ rect->x /= 2;
+ rect->y /= 2;
+ rect->w = (rect->w + 1) / 2;
+ rect->h = (rect->h + 1) / 2;
+ dx /= 2;
+ dy /= 2;
+
+ mga_waitfifo( mdrv, mdev, 6 );
+ mga_out32( mmio, mdev->dst_pitch/2, PITCH );
+
+ mga_out32( mmio, (mdev->dst_pitch/2 * mdev->clip.y1/2) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_pitch/2 * mdev->clip.y2/2) & 0xFFFFFF, YBOT );
+ mga_out32( mmio, ((mdev->clip.x2/2 & 0x0FFF) << 16) | (mdev->clip.x1/2 & 0x0FFF), CXBNDRY );
+
+ /* Cb plane */
+ /* First field */
+ mga_out32( mmio, mdev->src_offset[src_field][1], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[dst_field][1], DSTORG );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, rect->y/2,
+ dx, dy/2,
+ rect->w, (rect->h+1)/2,
+ mdev->src_pitch/2 );
+
+ /* Second field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[!src_field][1], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[!dst_field][1], DSTORG );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, (rect->y+1)/2,
+ dx, (dy+1)/2,
+ rect->w, rect->h/2,
+ mdev->src_pitch/2 );
+
+ /* Cr plane */
+ /* First field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[src_field][2], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[dst_field][2], DSTORG );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, rect->y/2,
+ dx, dy/2,
+ rect->w, (rect->h+1)/2,
+ mdev->src_pitch/2 );
+
+ /* Second field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[!src_field][2], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[!dst_field][2], DSTORG );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, (rect->y+1)/2,
+ dx, (dy+1)/2,
+ rect->w, rect->h/2,
+ mdev->src_pitch/2 );
+
+ /* Restore registers */
+ mga_waitfifo( mdrv, mdev, 3 );
+ mga_out32( mmio, mdev->dst_pitch, PITCH );
+
+ mga_out32( mmio, mdev->src_offset[0][0], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[0][0], DSTORG );
+
+ matrox_set_clip( mdrv, mdev, &mdev->clip );
+
+ return true;
+}
+
+static bool
+matroxBlit2D_422_F( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+ int src_field, dst_field;
+
+ src_field = rect->y & 1;
+ dst_field = dy & 1;
+
+ dx /= 2;
+ rect->x /= 2;
+ rect->w = (rect->w + 1) / 2;
+
+ /* First field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[src_field][0], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[dst_field][0], DSTORG );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, rect->y/2,
+ dx, dy/2,
+ rect->w, (rect->h+1)/2,
+ mdev->src_pitch );
+
+ /* Second field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[!src_field][0], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[!dst_field][0], DSTORG );
+
+ matroxDoBlit2D( mdrv, mdev,
+ rect->x, (rect->y+1)/2,
+ dx, (dy+1)/2,
+ rect->w, rect->h/2,
+ mdev->src_pitch );
+
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[0][0], SRCORG );
+ mga_out32( mmio, mdev->dst_offset[0][0], DSTORG );
+
+ return true;
+}
+
+/******************************************************************************/
+
+static inline void
+matroxDoBlitTMU( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ int sx, int sy,
+ int dx, int dy,
+ int sw, int sh,
+ int dw, int dh,
+ int w2, int h2,
+ bool filter )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ s32 startx, starty, incx, incy;
+
+ if (mdev->blit_deinterlace) {
+ sy /= 2;
+ sh /= 2;
+ }
+
+ incx = (sw << (20 - w2)) / dw;
+ incy = (sh << (20 - h2)) / dh;
+
+ startx = sx << (20 - w2);
+ starty = sy << (20 - h2);
+
+ if (mdev->blit_deinterlace && !mdev->field)
+ starty += (0x80000 >> h2);
+
+ mga_waitfifo( mdrv, mdev, 8);
+
+ mga_out32( mmio, BOP_COPY | SHFTZERO | SGNZERO | ARZERO | ATYPE_I | OP_TEXTURE_TRAP, DWGCTL );
+
+ if (filter)
+ mga_out32( mmio, (0x10<<21) | MAG_BILIN | MIN_BILIN, TEXFILTER );
+ else
+ mga_out32( mmio, (0x10<<21) | MAG_NRST | MIN_NRST, TEXFILTER );
+
+ mga_out32( mmio, incx, TMR0 );
+ mga_out32( mmio, incy, TMR3 );
+ mga_out32( mmio, startx, TMR6 );
+ mga_out32( mmio, starty, TMR7 );
+ mga_out32( mmio, (RS16(dx+dw) << 16) | RS16(dx), FXBNDRY );
+ mga_out32( mmio, (RS16(dy) << 16) | RS16(dh), YDSTLEN | EXECUTE );
+}
+
+static inline void
+matroxBlitTMU( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ DFBRectangle *srect,
+ DFBRectangle *drect,
+ bool filter )
+{
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, srect->y,
+ drect->x, drect->y,
+ srect->w, srect->h,
+ drect->w, drect->h,
+ mdev->w2, mdev->h2,
+ filter );
+}
+
+static inline void
+matroxBlitTMU_2P( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ DFBRectangle *srect,
+ DFBRectangle *drect,
+ bool filter )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ u32 texctl;
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, srect->y,
+ drect->x, drect->y,
+ srect->w, srect->h,
+ drect->w, drect->h,
+ mdev->w2, mdev->h2,
+ filter );
+
+ srect->x /= 2;
+ srect->y /= 2;
+ srect->w = (srect->w + 1) / 2;
+ srect->h = (srect->h + 1) / 2;
+ drect->x /= 2;
+ drect->y /= 2;
+ drect->w = (drect->w + 1) / 2;
+ drect->h = (drect->h + 1) / 2;
+
+ texctl = mdev->texctl & ~(TPITCHEXT | TFORMAT);
+ texctl |= (((mdev->src_pitch/2) << 9) & TPITCHEXT) | TW16;
+
+ /* CbCr plane */
+ mga_waitfifo( mdrv, mdev, 10 );
+ mga_out32( mmio, texctl, TEXCTL );
+ mga_out32( mmio, ( (((u32)(mdev->w/2 - 1) & 0x7ff) << 18) |
+ (((u32)(3 - mdev->w2) & 0x3f) << 9) |
+ (((u32)(mdev->w2 + 3) & 0x3f) ) ), TEXWIDTH );
+ mga_out32( mmio, ( (((u32)(mdev->h/2 - 1) & 0x7ff) << 18) |
+ (((u32)(3 - mdev->h2) & 0x3f) << 9) |
+ (((u32)(mdev->h2 + 3) & 0x3f) ) ), TEXHEIGHT );
+ mga_out32( mmio, mdev->src_offset[0][1], TEXORG );
+
+ mga_out32( mmio, mdev->dst_pitch/2, PITCH );
+ mga_out32( mmio, PW16 | NODITHER, MACCESS );
+ mga_out32( mmio, mdev->dst_offset[0][1], DSTORG );
+
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y1 / 4) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y2 / 4) & 0xFFFFFF, YBOT );
+ mga_out32( mmio, ((mdev->clip.x2/2 & 0x0FFF) << 16) | (mdev->clip.x1/2 & 0x0FFF), CXBNDRY );
+
+ /* No filtering since we're not using real RGB16 data */
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, srect->y,
+ drect->x, drect->y,
+ srect->w, srect->h,
+ drect->w, drect->h,
+ mdev->w2-1, mdev->h2-1,
+ false );
+
+ /* Restore registers */
+ mga_waitfifo( mdrv, mdev, 7 );
+ mga_out32( mmio, mdev->texctl, TEXCTL );
+ mga_out32( mmio, ( (((u32)(mdev->w - 1) & 0x7ff) << 18) |
+ (((u32)(4 - mdev->w2) & 0x3f) << 9) |
+ (((u32)(mdev->w2 + 4) & 0x3f) ) ), TEXWIDTH );
+ mga_out32( mmio, ( (((u32)(mdev->h - 1) & 0x7ff) << 18) |
+ (((u32)(4 - mdev->h2) & 0x3f) << 9) |
+ (((u32)(mdev->h2 + 4) & 0x3f) ) ), TEXHEIGHT );
+ mga_out32( mmio, mdev->src_offset[0][0], TEXORG );
+
+ mga_out32( mmio, mdev->dst_pitch, PITCH );
+ mga_out32( mmio, PW8 | BYPASS332 | NODITHER, MACCESS );
+ mga_out32( mmio, mdev->dst_offset[0][0], DSTORG );
+
+ matrox_set_clip( mdrv, mdev, &mdev->clip );
+}
+
+static inline void
+matroxBlitTMU_3P( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ DFBRectangle *srect,
+ DFBRectangle *drect,
+ bool filter )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ u32 texctl;
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, srect->y,
+ drect->x, drect->y,
+ srect->w, srect->h,
+ drect->w, drect->h,
+ mdev->w2, mdev->h2,
+ filter );
+
+ srect->x /= 2;
+ srect->y /= 2;
+ srect->w = (srect->w + 1) / 2;
+ srect->h = (srect->h + 1) / 2;
+ drect->x /= 2;
+ drect->y /= 2;
+ drect->w = (drect->w + 1) / 2;
+ drect->h = (drect->h + 1) / 2;
+
+ texctl = mdev->texctl & ~TPITCHEXT;
+ texctl |= ((mdev->src_pitch/2) << 9) & TPITCHEXT;
+
+ /* Cb plane */
+ mga_waitfifo( mdrv, mdev, 9 );
+ mga_out32( mmio, texctl, TEXCTL );
+ mga_out32( mmio, ( (((u32)(mdev->w/2 - 1) & 0x7ff) << 18) |
+ (((u32)(3 - mdev->w2) & 0x3f) << 9) |
+ (((u32)(mdev->w2 + 3) & 0x3f) ) ), TEXWIDTH );
+ mga_out32( mmio, ( (((u32)(mdev->h/2 - 1) & 0x7ff) << 18) |
+ (((u32)(3 - mdev->h2) & 0x3f) << 9) |
+ (((u32)(mdev->h2 + 3) & 0x3f) ) ), TEXHEIGHT );
+ mga_out32( mmio, mdev->src_offset[0][1], TEXORG );
+
+ mga_out32( mmio, mdev->dst_pitch/2, PITCH );
+ mga_out32( mmio, mdev->dst_offset[0][1], DSTORG );
+
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y1 / 4) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_pitch * mdev->clip.y2 / 4) & 0xFFFFFF, YBOT );
+ mga_out32( mmio, ((mdev->clip.x2/2 & 0x0FFF) << 16) | (mdev->clip.x1/2 & 0x0FFF), CXBNDRY );
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, srect->y,
+ drect->x, drect->y,
+ srect->w, srect->h,
+ drect->w, drect->h,
+ mdev->w2-1, mdev->h2-1,
+ filter );
+
+ /* Cr plane */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[0][2], TEXORG );
+
+ mga_out32( mmio, mdev->dst_offset[0][2], DSTORG );
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, srect->y,
+ drect->x, drect->y,
+ srect->w, srect->h,
+ drect->w, drect->h,
+ mdev->w2-1, mdev->h2-1,
+ filter );
+
+ /* Restore registers */
+ mga_waitfifo( mdrv, mdev, 6 );
+ mga_out32( mmio, mdev->texctl, TEXCTL );
+ mga_out32( mmio, ( (((u32)(mdev->w - 1) & 0x7ff) << 18) |
+ (((u32)(4 - mdev->w2) & 0x3f) << 9) |
+ (((u32)(mdev->w2 + 4) & 0x3f) ) ), TEXWIDTH );
+ mga_out32( mmio, ( (((u32)(mdev->h - 1) & 0x7ff) << 18) |
+ (((u32)(4 - mdev->h2) & 0x3f) << 9) |
+ (((u32)(mdev->h2 + 4) & 0x3f) ) ), TEXHEIGHT );
+ mga_out32( mmio, mdev->src_offset[0][0], TEXORG );
+
+ mga_out32( mmio, mdev->dst_pitch, PITCH );
+ mga_out32( mmio, mdev->dst_offset[0][0], DSTORG );
+
+ matrox_set_clip( mdrv, mdev, &mdev->clip );
+}
+
+static bool
+matroxStretchBlit( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ matroxBlitTMU( mdrv, mdev, srect, drect, true );
+
+ return true;
+}
+
+static bool
+matroxStretchBlit_2P( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ matroxBlitTMU_2P( mdrv, mdev, srect, drect, true );
+
+ return true;
+}
+
+static bool
+matroxStretchBlit_3P( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ matroxBlitTMU_3P( mdrv, mdev, srect, drect, true );
+
+ return true;
+}
+
+static bool
+matroxStretchBlit_422( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ srect->x /= 2;
+ srect->w = (srect->w + 1) / 2;
+ drect->x /= 2;
+ drect->w = (drect->w + 1) / 2;
+
+ matroxBlitTMU( mdrv, mdev, srect, drect, true );
+
+ return true;
+}
+
+static bool
+matroxBlit3D( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ DFBRectangle drect = { dx, dy, rect->w, rect->h };
+
+ matroxBlitTMU( mdrv, mdev, rect, &drect, mdev->blit_deinterlace );
+
+ return true;
+}
+
+static bool
+matroxBlit3D_2P( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ DFBRectangle drect = { dx, dy, rect->w, rect->h };
+
+ matroxBlitTMU_2P( mdrv, mdev, rect, &drect, mdev->blit_deinterlace );
+
+ return true;
+}
+
+static bool
+matroxBlit3D_3P( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ DFBRectangle drect = { dx, dy, rect->w, rect->h };
+
+ matroxBlitTMU_3P( mdrv, mdev, rect, &drect, mdev->blit_deinterlace );
+
+ return true;
+}
+
+static bool
+matroxBlit3D_422( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ DFBRectangle drect= { dx, dy, rect->w, rect->h };
+
+ rect->x /= 2;
+ rect->w = (rect->w + 1) / 2;
+ drect.x /= 2;
+ drect.w = (drect.w + 1) / 2;
+
+ matroxBlitTMU( mdrv, mdev, rect, &drect, mdev->blit_deinterlace );
+
+ return true;
+}
+
+static void
+matroxBlitTMU_F( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ DFBRectangle *srect,
+ DFBRectangle *drect,
+ bool filter )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ int src_field, dst_field;
+
+ src_field = srect->y & 1;
+ dst_field = drect->y & 1;
+
+ /* First field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[src_field][0], TEXORG );
+ mga_out32( mmio, mdev->dst_offset[dst_field][0], DSTORG );
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, srect->y/2,
+ drect->x, drect->y/2,
+ srect->w, (srect->h+1)/2,
+ drect->w, (drect->h+1)/2,
+ mdev->w2, mdev->h2, filter );
+
+ /* Second field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[!src_field][0], TEXORG );
+ mga_out32( mmio, mdev->dst_offset[!dst_field][0], DSTORG );
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, (srect->y+1)/2,
+ drect->x, (drect->y+1)/2,
+ srect->w, srect->h/2,
+ drect->w, drect->h/2,
+ mdev->w2, mdev->h2, filter );
+
+ /* Restore registers */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[0][0], TEXORG );
+ mga_out32( mmio, mdev->dst_offset[0][0], DSTORG );
+}
+
+static bool
+matroxBlit3D_F( void *drv, void *dev,
+ DFBRectangle *rect, int dx, int dy )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ DFBRectangle drect = { dx, dy, rect->w, rect->h };
+
+ matroxBlitTMU_F( mdrv, mdev, rect, &drect, false );
+
+ return true;
+}
+
+static bool
+matroxStretchBlit_F( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ matroxBlitTMU_F( mdrv, mdev, srect, drect, true );
+
+ return true;
+}
+
+static bool
+matroxStretchBlit_422_F( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+
+ srect->x /= 2;
+ srect->w = (srect->w + 1) / 2;
+ drect->x /= 2;
+ drect->w = (drect->w + 1) / 2;
+
+ matroxBlitTMU_F( mdrv, mdev, srect, drect, true );
+
+ return true;
+}
+
+static bool
+matroxStretchBlit_2P_F( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+ int src_field, dst_field;
+ u32 texctl;
+
+ src_field = srect->y & 1;
+ dst_field = drect->y & 1;
+
+ /* Y plane */
+ /* First field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[src_field][0], TEXORG );
+ mga_out32( mmio, mdev->dst_offset[dst_field][0], DSTORG );
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, srect->y/2,
+ drect->x, drect->y/2,
+ srect->w, (srect->h+1)/2,
+ drect->w, (drect->h+1)/2,
+ mdev->w2, mdev->h2, true );
+
+ /* Second field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[!src_field][0], TEXORG );
+ mga_out32( mmio, mdev->dst_offset[!dst_field][0], DSTORG );
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, (srect->y+1)/2,
+ drect->x, (drect->y+1)/2,
+ srect->w, srect->h/2,
+ drect->w, drect->h/2,
+ mdev->w2, mdev->h2, true );
+
+ /* Subsampling */
+ srect->x /= 2;
+ srect->y /= 2;
+ srect->w = (srect->w + 1) / 2;
+ srect->h = (srect->h + 1) / 2;
+ drect->x /= 2;
+ drect->y /= 2;
+ drect->w = (drect->w + 1) / 2;
+ drect->h = (drect->h + 1) / 2;
+
+ texctl = mdev->texctl & ~(TPITCHEXT | TFORMAT);
+ texctl |= (((mdev->src_pitch/2) << 9) & TPITCHEXT) | TW16;
+
+ mga_waitfifo( mdrv, mdev, 10 );
+ mga_out32( mmio, texctl, TEXCTL );
+ mga_out32( mmio, ( (((u32)(mdev->w/2 - 1) & 0x7ff) << 18) |
+ (((u32)(3 - mdev->w2) & 0x3f) << 9) |
+ (((u32)(mdev->w2 + 3) & 0x3f) ) ), TEXWIDTH );
+ mga_out32( mmio, ( (((u32)(mdev->h/2 - 1) & 0x7ff) << 18) |
+ (((u32)(3 - mdev->h2) & 0x3f) << 9) |
+ (((u32)(mdev->h2 + 3) & 0x3f) ) ), TEXHEIGHT );
+ mga_out32( mmio, mdev->dst_pitch/2, PITCH );
+ mga_out32( mmio, PW16 | NODITHER, MACCESS );
+ mga_out32( mmio, (mdev->dst_pitch/2 * mdev->clip.y1/2) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_pitch/2 * mdev->clip.y2/2) & 0xFFFFFF, YBOT );
+ mga_out32( mmio, ((mdev->clip.x2/2 & 0x0FFF) << 16) | (mdev->clip.x1/2 & 0x0FFF), CXBNDRY );
+
+ /* CbCr plane */
+ /* First field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[src_field][1], TEXORG );
+ mga_out32( mmio, mdev->dst_offset[dst_field][1], DSTORG );
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, srect->y/2,
+ drect->x, drect->y/2,
+ srect->w, (srect->h+1)/2,
+ drect->w, (drect->h+1)/2,
+ mdev->w2-1, mdev->h2-1, true );
+
+ /* Second field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[!src_field][1], TEXORG );
+ mga_out32( mmio, mdev->dst_offset[!dst_field][1], DSTORG );
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, (srect->y+1)/2,
+ drect->x, (drect->y+1)/2,
+ srect->w, srect->h/2,
+ drect->w, drect->h/2,
+ mdev->w2-1, mdev->h2-1, true );
+
+ /* Restore registers */
+ mga_waitfifo( mdrv, mdev, 7 );
+ mga_out32( mmio, mdev->texctl, TEXCTL );
+ mga_out32( mmio, ( (((u32)(mdev->w - 1) & 0x7ff) << 18) |
+ (((u32)(4 - mdev->w2) & 0x3f) << 9) |
+ (((u32)(mdev->w2 + 4) & 0x3f) ) ), TEXWIDTH );
+ mga_out32( mmio, ( (((u32)(mdev->h - 1) & 0x7ff) << 18) |
+ (((u32)(4 - mdev->h2) & 0x3f) << 9) |
+ (((u32)(mdev->h2 + 4) & 0x3f) ) ), TEXHEIGHT );
+ mga_out32( mmio, mdev->dst_pitch, PITCH );
+ mga_out32( mmio, PW8 | BYPASS332 | NODITHER, MACCESS );
+
+ mga_out32( mmio, mdev->src_offset[0][0], TEXORG );
+ mga_out32( mmio, mdev->dst_offset[0][0], DSTORG );
+
+ matrox_set_clip( mdrv, mdev, &mdev->clip );
+
+ return true;
+}
+
+static bool
+matroxStretchBlit_3P_F( void *drv, void *dev,
+ DFBRectangle *srect, DFBRectangle *drect )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+ int src_field, dst_field;
+ u32 texctl;
+
+ src_field = srect->y & 1;
+ dst_field = drect->y & 1;
+
+ /* Y plane */
+ /* First field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[src_field][0], TEXORG );
+ mga_out32( mmio, mdev->dst_offset[dst_field][0], DSTORG );
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, srect->y/2,
+ drect->x, drect->y/2,
+ srect->w, (srect->h+1)/2,
+ drect->w, (drect->h+1)/2,
+ mdev->w2, mdev->h2, true );
+
+ /* Second field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[!src_field][0], TEXORG );
+ mga_out32( mmio, mdev->dst_offset[!dst_field][0], DSTORG );
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, (srect->y+1)/2,
+ drect->x, (drect->y+1)/2,
+ srect->w, srect->h/2,
+ drect->w, drect->h/2,
+ mdev->w2, mdev->h2, true );
+
+ /* Subsampling */
+ srect->x /= 2;
+ srect->y /= 2;
+ srect->w = (srect->w + 1) / 2;
+ srect->h = (srect->h + 1) / 2;
+ drect->x /= 2;
+ drect->y /= 2;
+ drect->w = (drect->w + 1) / 2;
+ drect->h = (drect->h + 1) / 2;
+
+ texctl = mdev->texctl & ~TPITCHEXT;
+ texctl |= ((mdev->src_pitch/2) << 9) & TPITCHEXT;
+
+ mga_waitfifo( mdrv, mdev, 9 );
+ mga_out32( mmio, texctl, TEXCTL );
+ mga_out32( mmio, ( (((u32)(mdev->w/2 - 1) & 0x7ff) << 18) |
+ (((u32)(3 - mdev->w2) & 0x3f) << 9) |
+ (((u32)(mdev->w2 + 3) & 0x3f) ) ), TEXWIDTH );
+ mga_out32( mmio, ( (((u32)(mdev->h/2 - 1) & 0x7ff) << 18) |
+ (((u32)(3 - mdev->h2) & 0x3f) << 9) |
+ (((u32)(mdev->h2 + 3) & 0x3f) ) ), TEXHEIGHT );
+ mga_out32( mmio, mdev->dst_pitch/2, PITCH );
+ mga_out32( mmio, (mdev->dst_pitch/2 * mdev->clip.y1/2) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_pitch/2 * mdev->clip.y2/2) & 0xFFFFFF, YBOT );
+ mga_out32( mmio, ((mdev->clip.x2/2 & 0x0FFF) << 16) | (mdev->clip.x1/2 & 0x0FFF), CXBNDRY );
+
+ /* Cb plane */
+ /* First field */
+ mga_out32( mmio, mdev->src_offset[src_field][1], TEXORG );
+ mga_out32( mmio, mdev->dst_offset[dst_field][1], DSTORG );
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, srect->y/2,
+ drect->x, drect->y/2,
+ srect->w, (srect->h+1)/2,
+ drect->w, (drect->h+1)/2,
+ mdev->w2-1, mdev->h2-1, true );
+
+ /* Second field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[!src_field][1], TEXORG );
+ mga_out32( mmio, mdev->dst_offset[!dst_field][1], DSTORG );
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, (srect->y+1)/2,
+ drect->x, (drect->y+1)/2,
+ srect->w, srect->h/2,
+ drect->w, drect->h/2,
+ mdev->w2-1, mdev->h2-1, true );
+
+ /* Cr plane */
+ /* First field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[src_field][2], TEXORG );
+ mga_out32( mmio, mdev->dst_offset[dst_field][2], DSTORG );
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, srect->y/2,
+ drect->x, drect->y/2,
+ srect->w, (srect->h+1)/2,
+ drect->w, (drect->h+1)/2,
+ mdev->w2-1, mdev->h2-1, true );
+
+ /* Second field */
+ mga_waitfifo( mdrv, mdev, 2 );
+ mga_out32( mmio, mdev->src_offset[!src_field][2], TEXORG );
+ mga_out32( mmio, mdev->dst_offset[!dst_field][2], DSTORG );
+
+ matroxDoBlitTMU( mdrv, mdev,
+ srect->x, (srect->y+1)/2,
+ drect->x, (drect->y+1)/2,
+ srect->w, srect->h/2,
+ drect->w, drect->h/2,
+ mdev->w2-1, mdev->h2-1, true );
+
+ /* Restore registers */
+ mga_waitfifo( mdrv, mdev, 6 );
+ mga_out32( mmio, mdev->texctl, TEXCTL );
+ mga_out32( mmio, ( (((u32)(mdev->w - 1) & 0x7ff) << 18) |
+ (((u32)(4 - mdev->w2) & 0x3f) << 9) |
+ (((u32)(mdev->w2 + 4) & 0x3f) ) ), TEXWIDTH );
+ mga_out32( mmio, ( (((u32)(mdev->h - 1) & 0x7ff) << 18) |
+ (((u32)(4 - mdev->h2) & 0x3f) << 9) |
+ (((u32)(mdev->h2 + 4) & 0x3f) ) ), TEXHEIGHT );
+ mga_out32( mmio, mdev->dst_pitch, PITCH );
+
+ mga_out32( mmio, mdev->src_offset[0][0], TEXORG );
+ mga_out32( mmio, mdev->dst_offset[0][0], DSTORG );
+
+ matrox_set_clip( mdrv, mdev, &mdev->clip );
+
+ return true;
+}
+
+/******************************************************************************/
+
+static u32 pci_config_in32( unsigned int bus,
+ unsigned int slot,
+ unsigned int func,
+ u8 reg )
+{
+ char filename[512];
+ int fd;
+ u32 val;
+
+ snprintf( filename, 512,
+ "/proc/bus/pci/%02x/%02x.%x",
+ bus, slot, func );
+
+ fd = open( filename, O_RDONLY );
+ if (fd < 0)
+ return 0;
+
+ if (lseek( fd, reg, SEEK_SET ) != reg) {
+ close( fd );
+ return 0;
+ }
+
+ if (read( fd, &val, 4 ) != 4) {
+ close( fd );
+ return 0;
+ }
+
+ close( fd );
+
+#ifdef WORDS_BIGENDIAN
+ return ((val & 0xff000000) >> 24) |
+ ((val & 0x00ff0000) >> 8) |
+ ((val & 0x0000ff00) << 8) |
+ ((val & 0x000000ff) << 24);
+#else
+ return val;
+#endif
+}
+
+static DFBResult matrox_find_pci_device( MatroxDeviceData *mdev,
+ unsigned int *bus,
+ unsigned int *slot,
+ unsigned int *func )
+{
+ unsigned int vendor, device, devfn;
+ unsigned long addr0, addr1;
+ char line[512];
+ FILE *file;
+
+ file = fopen( "/proc/bus/pci/devices", "r" );
+ if (!file) {
+ D_PERROR( "DirectFB/Matrox: "
+ "Error opening `/proc/bus/pci/devices'!\n" );
+ return errno2result( errno );
+ }
+
+ while (fgets( line, 512, file )) {
+ if (sscanf( line, "%02x%02x\t%04x%04x\t%*x\t%lx\t%lx",
+ bus, &devfn, &vendor, &device, &addr0, &addr1 ) != 6)
+ continue;
+
+ if (vendor != PCI_VENDOR_ID_MATROX)
+ continue;
+
+ *slot = (devfn >> 3) & 0x1F;
+ *func = devfn & 0x07;
+
+ addr0 &= ~0xFUL;
+ addr1 &= ~0xFUL;
+
+ switch (device) {
+ case PCI_DEVICE_ID_MATROX_G550_AGP:
+ case PCI_DEVICE_ID_MATROX_G400_AGP:
+ if (addr0 == (mdev->fb.physical & ~0x1FFFFFF)) {
+ fclose( file );
+ return DFB_OK;
+ }
+ break;
+
+ case PCI_DEVICE_ID_MATROX_G200_PCI:
+ case PCI_DEVICE_ID_MATROX_G200_AGP:
+ case PCI_DEVICE_ID_MATROX_G100_PCI:
+ case PCI_DEVICE_ID_MATROX_G100_AGP:
+ case PCI_DEVICE_ID_MATROX_2164W_PCI:
+ case PCI_DEVICE_ID_MATROX_2164W_AGP:
+ if (addr0 == mdev->fb.physical) {
+ fclose( file );
+ return DFB_OK;
+ }
+ break;
+
+ case PCI_DEVICE_ID_MATROX_1064SG_PCI:
+ case PCI_DEVICE_ID_MATROX_1064SG_AGP:
+ if ((pci_config_in32( *bus, *slot, *func, 0x08 ) & 0xFF) > 0x02) {
+ /* Mystique 220 (1164SG) */
+ if (addr0 == mdev->fb.physical) {
+ fclose( file );
+ return DFB_OK;
+ }
+ } else {
+ /* Mystique (1064SG) */
+ if (addr1 == mdev->fb.physical) {
+ fclose( file );
+ return DFB_OK;
+ }
+ }
+ break;
+
+ case PCI_DEVICE_ID_MATROX_2064W_PCI:
+ if (addr1 == mdev->fb.physical) {
+ fclose( file );
+ return DFB_OK;
+ }
+ break;
+ }
+ }
+
+ D_ERROR( "DirectFB/Matrox: Can't find device in `/proc/bus/pci'!\n" );
+
+ fclose( file );
+ return DFB_INIT;
+}
+
+/* exported symbols */
+
+static int
+driver_probe( CoreGraphicsDevice *device )
+{
+ switch (dfb_gfxcard_get_accelerator( device )) {
+ case FB_ACCEL_MATROX_MGA2064W: /* Matrox 2064W (Millennium) */
+ case FB_ACCEL_MATROX_MGA1064SG: /* Matrox 1064SG/1164SG (Mystique) */
+ case FB_ACCEL_MATROX_MGA2164W: /* Matrox 2164W (Millennium II) */
+ case FB_ACCEL_MATROX_MGA2164W_AGP: /* Matrox 2164W (Millennium II) */
+ case FB_ACCEL_MATROX_MGAG100: /* Matrox G100 */
+ case FB_ACCEL_MATROX_MGAG200: /* Matrox G200 */
+ case FB_ACCEL_MATROX_MGAG400: /* Matrox G400/G450/G550 */
+ return 1;
+ }
+
+ return 0;
+}
+
+static void
+driver_get_info( CoreGraphicsDevice *device,
+ GraphicsDriverInfo *info )
+{
+ /* fill driver info structure */
+ snprintf( info->name,
+ DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH,
+ "Matrox G-Series/Millennium/Mystique" );
+
+ snprintf( info->vendor,
+ DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH,
+ "directfb.org" );
+
+ info->version.major = 0;
+ info->version.minor = 7;
+
+ info->driver_data_size = sizeof (MatroxDriverData);
+ info->device_data_size = sizeof (MatroxDeviceData);
+}
+
+static DFBResult
+driver_init_driver( CoreGraphicsDevice *device,
+ GraphicsDeviceFuncs *funcs,
+ void *driver_data,
+ void *device_data,
+ CoreDFB *core )
+{
+ MatroxDriverData *mdrv = driver_data;
+
+ mdrv->mmio_base = (volatile u8*) dfb_gfxcard_map_mmio( device, 0, -1 );
+ if (!mdrv->mmio_base)
+ return DFB_IO;
+
+ mdrv->device_data = device_data;
+ mdrv->maven_fd = -1;
+ mdrv->accelerator = dfb_gfxcard_get_accelerator( device );
+
+ switch (mdrv->accelerator) {
+ case FB_ACCEL_MATROX_MGAG400:
+ funcs->CheckState = matroxG400CheckState;
+ break;
+
+ case FB_ACCEL_MATROX_MGAG200:
+ if (!dfb_config->font_format)
+ dfb_config->font_format = DSPF_ARGB;
+ funcs->CheckState = matroxG200CheckState;
+ break;
+
+ case FB_ACCEL_MATROX_MGAG100:
+ funcs->CheckState = matroxG100CheckState;
+ break;
+
+ case FB_ACCEL_MATROX_MGA1064SG:
+ case FB_ACCEL_MATROX_MGA2164W:
+ case FB_ACCEL_MATROX_MGA2164W_AGP:
+ funcs->CheckState = matroxOldCheckState;
+ break;
+
+ case FB_ACCEL_MATROX_MGA2064W:
+ funcs->CheckState = matrox2064WCheckState;
+ break;
+ }
+
+ funcs->SetState = matroxSetState;
+ funcs->EngineReset = matroxEngineReset;
+ funcs->EngineSync = matroxEngineSync;
+ funcs->FlushTextureCache = matroxFlushTextureCache;
+ funcs->FlushReadCache = matroxFlushReadCache;
+
+ funcs->DrawRectangle = matroxDrawRectangle;
+ funcs->DrawLine = matroxDrawLine;
+ funcs->FillTriangle = matroxFillTriangle;
+ funcs->TextureTriangles = matroxTextureTriangles;
+
+ /* will be set dynamically: funcs->FillRectangle, funcs->Blit, funcs->StretchBlit */
+
+ /* Generic CRTC1 support */
+ mdrv->primary = dfb_screens_at( DSCID_PRIMARY );
+
+ /* G200/G400/G450/G550 Backend Scaler Support */
+ if (mdrv->accelerator == FB_ACCEL_MATROX_MGAG200 ||
+ mdrv->accelerator == FB_ACCEL_MATROX_MGAG400)
+ dfb_layers_register( mdrv->primary, driver_data, &matroxBesFuncs );
+
+ /* G400/G450/G550 CRTC2 support */
+ if (mdrv->accelerator == FB_ACCEL_MATROX_MGAG400 &&
+ dfb_config->matrox_crtc2)
+ {
+ mdrv->secondary = dfb_screens_register( device, driver_data,
+ &matroxCrtc2ScreenFuncs );
+
+ dfb_layers_register( mdrv->secondary, driver_data, &matroxCrtc2Funcs );
+ dfb_layers_register( mdrv->secondary, driver_data, &matroxSpicFuncs );
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+driver_init_device( CoreGraphicsDevice *device,
+ GraphicsDeviceInfo *device_info,
+ void *driver_data,
+ void *device_data )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) device_data;
+ volatile u8 *mmio = mdrv->mmio_base;
+ unsigned int bus, slot, func;
+ bool g450, g550, sgram = false;
+ DFBResult ret;
+
+ mdev->fb.physical = dfb_gfxcard_memory_physical( device, 0 );
+
+ switch (mdrv->accelerator) {
+ case FB_ACCEL_MATROX_MGAG400:
+ if ((ret = matrox_find_pci_device( mdev, &bus, &slot, &func )))
+ return ret;
+
+ g550 = ((pci_config_in32( bus, slot, func, 0x00 ) >> 16) == PCI_DEVICE_ID_MATROX_G550_AGP);
+ g450 = ((pci_config_in32( bus, slot, func, 0x08 ) & 0xFF) >= 0x80);
+ sgram = ((pci_config_in32( bus, slot, func, 0x40 ) & 0x4000) == 0x4000);
+ snprintf( device_info->name,
+ DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "%s",
+ g550 ? "G550" : g450 ? "G450" : "G400" );
+ mdev->g450_matrox = g450 || g550;
+ mdev->g550_matrox = g550;
+
+ mdev->fb.offset = mdev->fb.physical & 0x1FFFFFF;
+ break;
+ case FB_ACCEL_MATROX_MGAG200:
+ if ((ret = matrox_find_pci_device( mdev, &bus, &slot, &func )))
+ return ret;
+
+ sgram = ((pci_config_in32( bus, slot, func, 0x40 ) & 0x4000) == 0x4000);
+ snprintf( device_info->name,
+ DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "G200" );
+ break;
+ case FB_ACCEL_MATROX_MGAG100:
+ mdev->old_matrox = true;
+ sgram = false; /* FIXME: can we detect this? */
+ snprintf( device_info->name,
+ DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "G100" );
+ break;
+ case FB_ACCEL_MATROX_MGA2064W:
+ mdev->old_matrox = true;
+ sgram = true;
+ snprintf( device_info->name,
+ DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "Millennium (2064W)" );
+ break;
+ case FB_ACCEL_MATROX_MGA1064SG:
+ if ((ret = matrox_find_pci_device( mdev, &bus, &slot, &func )))
+ return ret;
+
+ mdev->old_matrox = true;
+ sgram = ((pci_config_in32( bus, slot, func, 0x40 ) & 0x4000) == 0x4000);
+ snprintf( device_info->name,
+ DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "%s",
+ ((pci_config_in32( bus, slot, func, 0x08 ) & 0xFF) > 0x02) ?
+ "Mystique 220 (1164SG)" : "Mystique (1064SG)" );
+ break;
+ case FB_ACCEL_MATROX_MGA2164W:
+ case FB_ACCEL_MATROX_MGA2164W_AGP:
+ mdev->old_matrox = true;
+ sgram = true;
+ snprintf( device_info->name,
+ DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "Millennium II (2164W)" );
+ break;
+ }
+
+ snprintf( device_info->vendor,
+ DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "Matrox" );
+
+
+ /* set hardware capabilities */
+ device_info->caps.flags = CCF_CLIPPING;
+
+ switch (mdrv->accelerator) {
+ case FB_ACCEL_MATROX_MGAG400:
+ device_info->caps.accel = MATROX_G200G400_DRAWING_FUNCTIONS |
+ MATROX_G200G400_BLITTING_FUNCTIONS;
+ device_info->caps.drawing = MATROX_G200G400_DRAWING_FLAGS;
+ device_info->caps.blitting = MATROX_G200G400_BLITTING_FLAGS;
+ break;
+
+ case FB_ACCEL_MATROX_MGAG200:
+ device_info->caps.accel = MATROX_G200G400_DRAWING_FUNCTIONS |
+ MATROX_G200G400_BLITTING_FUNCTIONS;
+ device_info->caps.drawing = MATROX_G200G400_DRAWING_FLAGS;
+ device_info->caps.blitting = MATROX_G200G400_BLITTING_FLAGS;
+ break;
+
+ case FB_ACCEL_MATROX_MGAG100:
+ device_info->caps.accel = MATROX_G100_DRAWING_FUNCTIONS |
+ MATROX_G100_BLITTING_FUNCTIONS;
+ device_info->caps.drawing = MATROX_G100_DRAWING_FLAGS;
+ device_info->caps.blitting = MATROX_G100_BLITTING_FLAGS;
+ break;
+
+ case FB_ACCEL_MATROX_MGA1064SG:
+ case FB_ACCEL_MATROX_MGA2164W:
+ case FB_ACCEL_MATROX_MGA2164W_AGP:
+ device_info->caps.accel = MATROX_OLD_DRAWING_FUNCTIONS |
+ MATROX_OLD_BLITTING_FUNCTIONS;
+ device_info->caps.drawing = MATROX_OLD_DRAWING_FLAGS;
+ device_info->caps.blitting = MATROX_OLD_BLITTING_FLAGS;
+ break;
+
+ case FB_ACCEL_MATROX_MGA2064W:
+ device_info->caps.accel = MATROX_2064W_DRAWING_FUNCTIONS |
+ MATROX_2064W_BLITTING_FUNCTIONS;
+ device_info->caps.drawing = MATROX_2064W_DRAWING_FLAGS;
+ device_info->caps.blitting = MATROX_2064W_BLITTING_FLAGS;
+ break;
+ }
+
+ /* set hardware limitations */
+ device_info->limits.surface_byteoffset_alignment = 128;
+ device_info->limits.surface_pixelpitch_alignment = 32;
+ device_info->limits.surface_bytepitch_alignment = 64;
+
+ /* YUY2 / UYVY is handled as 32bit so pixelpitch alignment must be doubled. */
+ device_info->limits.surface_pixelpitch_alignment = 64;
+
+ mdev->atype_blk_rstr = (sgram || dfb_config->matrox_sgram) ? ATYPE_BLK : ATYPE_RSTR;
+ /*
+ * Pitch must be a multiple of 64 bytes for block write to work.
+ * SRCORG/DSTORG must be a multiple of 64.
+ * I420/YV12 subsampling makes the actual requirement 128 bytes.
+ */
+ if (mdrv->accelerator == FB_ACCEL_MATROX_MGAG400)
+ device_info->limits.surface_bytepitch_alignment = 128;
+
+ /* soft reset to fix eventually corrupted TMU read offset on G200 */
+ if (mdrv->accelerator == FB_ACCEL_MATROX_MGAG200) {
+ u32 ien = mga_in32( mmio, IEN );
+ mga_out32( mmio, 1, RST );
+ usleep(10);
+ mga_out32( mmio, 0, RST );
+ mga_out32( mmio, ien, IEN );
+ }
+
+ if (mdrv->accelerator == FB_ACCEL_MATROX_MGA2064W)
+ mdev->idle_status = 0;
+ else
+ mdev->idle_status = ENDPRDMASTS;
+
+ switch (mdrv->accelerator) {
+ case FB_ACCEL_MATROX_MGAG100:
+ case FB_ACCEL_MATROX_MGAG200:
+ if ((ret = dfb_palette_create( NULL, 256, &mdev->rgb332_palette )) != DFB_OK)
+ return ret;
+ dfb_palette_generate_rgb332_map( mdev->rgb332_palette );
+
+ mdev->tlut_offset = dfb_gfxcard_reserve_memory( device, 2 * 256 );
+ }
+
+ return DFB_OK;
+}
+
+static void
+driver_close_device( CoreGraphicsDevice *device,
+ void *driver_data,
+ void *device_data )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) device_data;
+
+ if (mdev->rgb332_palette)
+ dfb_palette_unref( mdev->rgb332_palette );
+
+ /* reset DSTORG as matroxfb does not */
+ mga_waitfifo( mdrv, mdev, 1 );
+ mga_out32( mdrv->mmio_base, 0, DSTORG );
+
+ /* make sure BES registers get updated (besvcnt) */
+ mga_out32( mdrv->mmio_base, 0, BESGLOBCTL );
+ /* make sure overlay is off */
+ mga_out32( mdrv->mmio_base, 0, BESCTL );
+
+
+ D_DEBUG( "DirectFB/Matrox: FIFO Performance Monitoring:\n" );
+ D_DEBUG( "DirectFB/Matrox: %9d matrox_waitfifo calls\n",
+ mdev->waitfifo_calls );
+ D_DEBUG( "DirectFB/Matrox: %9d register writes (matrox_waitfifo sum)\n",
+ mdev->waitfifo_sum );
+ D_DEBUG( "DirectFB/Matrox: %9d FIFO wait cycles (depends on CPU)\n",
+ mdev->fifo_waitcycles );
+ D_DEBUG( "DirectFB/Matrox: %9d IDLE wait cycles (depends on CPU)\n",
+ mdev->idle_waitcycles );
+ D_DEBUG( "DirectFB/Matrox: %9d FIFO space cache hits (depends on CPU)\n",
+ mdev->fifo_cache_hits );
+ D_DEBUG( "DirectFB/Matrox: Conclusion:\n" );
+ D_DEBUG( "DirectFB/Matrox: Average register writes/matrox_waitfifo call: %.2f\n",
+ mdev->waitfifo_sum/(float)(mdev->waitfifo_calls) );
+ D_DEBUG( "DirectFB/Matrox: Average wait cycles/matrox_waitfifo call: %.2f\n",
+ mdev->fifo_waitcycles/(float)(mdev->waitfifo_calls) );
+ D_DEBUG( "DirectFB/Matrox: Average fifo space cache hits: %02d%%\n",
+ (int)(100 * mdev->fifo_cache_hits/(float)(mdev->waitfifo_calls)) );
+}
+
+static void
+driver_close_driver( CoreGraphicsDevice *device,
+ void *driver_data )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+
+ dfb_gfxcard_unmap_mmio( device, mdrv->mmio_base, -1 );
+}
+
diff --git a/Source/DirectFB/gfxdrivers/matrox/matrox.h b/Source/DirectFB/gfxdrivers/matrox/matrox.h
new file mode 100755
index 0000000..70062bf
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/matrox.h
@@ -0,0 +1,157 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef ___MATROX_H__
+#define ___MATROX_H__
+
+#include <dfb_types.h>
+
+#include <core/layers.h>
+#include <core/screens.h>
+
+#define PCI_VENDOR_ID_MATROX 0x102B
+#define PCI_DEVICE_ID_MATROX_2064W_PCI 0x0519
+#define PCI_DEVICE_ID_MATROX_1064SG_PCI 0x051A
+#define PCI_DEVICE_ID_MATROX_2164W_PCI 0x051B
+#define PCI_DEVICE_ID_MATROX_1064SG_AGP 0x051E
+#define PCI_DEVICE_ID_MATROX_2164W_AGP 0x051F
+#define PCI_DEVICE_ID_MATROX_G100_PCI 0x1000
+#define PCI_DEVICE_ID_MATROX_G100_AGP 0x1001
+#define PCI_DEVICE_ID_MATROX_G200_PCI 0x0520
+#define PCI_DEVICE_ID_MATROX_G200_AGP 0x0521
+#define PCI_DEVICE_ID_MATROX_G400_AGP 0x0525
+#define PCI_DEVICE_ID_MATROX_G550_AGP 0x2527
+
+typedef enum {
+ m_Source = 0x0001,
+ m_source = 0x0002,
+
+ m_drawColor = 0x0010,
+ m_blitColor = 0x0020,
+ m_color = 0x0040,
+
+ m_SrcKey = 0x0100,
+ m_srckey = 0x0200,
+
+ m_drawBlend = 0x1000,
+ m_blitBlend = 0x2000,
+
+ m_destination = 0x4000,
+ m_clip = 0x8000,
+} MatroxStateBits;
+
+#define MGA_VALIDATE(b) (mdev->valid |= (b))
+#define MGA_INVALIDATE(b) (mdev->valid &= ~(b))
+#define MGA_IS_VALID(b) (mdev->valid & (b))
+
+typedef struct {
+ /* Old cards are older than G200/G400, e.g. Mystique or Millennium */
+ bool old_matrox;
+ /* G450/G550 */
+ bool g450_matrox;
+ /* G550 */
+ bool g550_matrox;
+
+ /* FIFO Monitoring */
+ unsigned int fifo_space;
+ unsigned int waitfifo_sum;
+ unsigned int waitfifo_calls;
+ unsigned int fifo_waitcycles;
+ unsigned int idle_waitcycles;
+ unsigned int fifo_cache_hits;
+
+ /* ATYPE_BLK or ATYPE_RSTR, depending on SGRAM setting */
+ u32 atype_blk_rstr;
+
+ /* State handling */
+ MatroxStateBits valid;
+
+ /* Stored values */
+ int dst_pitch;
+ int dst_offset[2][3];
+ int src_pitch;
+ int src_offset[2][3];
+ int w, h, w2, h2;
+ u32 color[3];
+
+ bool draw_blend;
+ bool blit_src_colorkey;
+
+ bool blit_deinterlace;
+ bool blit_fields;
+ int field;
+
+ bool depth_buffer;
+
+ u32 texctl;
+
+ u32 idle_status;
+
+ DFBRegion clip;
+
+ struct {
+ unsigned long offset;
+ unsigned long physical;
+ } fb;
+ unsigned int tlut_offset;
+ CorePalette *rgb332_palette;
+
+ bool crtc2_separated;
+} MatroxDeviceData;
+
+typedef struct {
+ int accelerator;
+ int maven_fd;
+ volatile u8 *mmio_base;
+
+ CoreScreen *primary;
+ CoreScreen *secondary;
+
+ MatroxDeviceData *device_data;
+} MatroxDriverData;
+
+
+extern DisplayLayerFuncs matroxBesFuncs;
+extern DisplayLayerFuncs matroxCrtc2Funcs;
+extern DisplayLayerFuncs matroxSpicFuncs;
+
+extern ScreenFuncs matroxCrtc2ScreenFuncs;
+
+static inline int mga_log2( int val )
+{
+ register int ret = 0;
+
+ while (val >> ++ret);
+
+ if ((1 << --ret) < val)
+ ret++;
+
+ return ret;
+}
+
+#endif
diff --git a/Source/DirectFB/gfxdrivers/matrox/matrox_3d.c b/Source/DirectFB/gfxdrivers/matrox/matrox_3d.c
new file mode 100755
index 0000000..f3753b0
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/matrox_3d.c
@@ -0,0 +1,627 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <fbdev/fb.h>
+
+#include <math.h>
+
+#include <directfb.h>
+
+#include <direct/messages.h>
+#include <direct/types.h>
+
+#include "regs.h"
+#include "mmio.h"
+#include "matrox.h"
+#include "matrox_3d.h"
+
+
+#ifdef ARCH_X86
+#define RINT(x) my_rint(x)
+#define CEIL(x) my_ceil(x)
+#define FLOOR(x) my_floor(x)
+#else
+#define RINT(x) ((s32)(x))
+#define CEIL(x) ((s32)ceil(x))
+#define FLOOR(x) ((s32)floor(x))
+#endif
+
+#ifdef ARCH_X86
+static inline long
+my_rint(const float x)
+{
+ register float arg = x;
+ long result;
+ __asm__ ("fistl %0" : "=m" (result) : "t" (arg));
+ return result;
+}
+
+static inline long
+my_ceil(const float x)
+{
+ register float arg = x;
+ volatile long value;
+ volatile short cw, cwtmp;
+
+ __asm__ volatile ("fnstcw %0" : "=m" (cw) : );
+ cwtmp = (cw & 0xf3ff) | 0x0800; /* rounding up */
+ __asm__ volatile ("fldcw %1\n"
+ "fistl %0\n"
+ "fldcw %2"
+ : "=m" (value)
+ : "m" (cwtmp), "m" (cw), "t" (arg));
+ return value;
+}
+
+static inline long
+my_floor(const float x)
+{
+ register float arg = x;
+ volatile long value;
+ volatile short cw, cwtmp;
+
+ __asm__ volatile ("fnstcw %0" : "=m" (cw) : );
+ cwtmp = (cw & 0xf3ff) | 0x0400;
+ __asm__ volatile ("fldcw %1\n"
+ "fistl %0\n"
+ "fldcw %2"
+ : "=m" (value)
+ : "m" (cwtmp), "m" (cw), "t" (arg));
+ return value;
+}
+#endif
+
+#define F2COL(x) (RINT(x) & 0x00ffffff)
+
+#define mgaF1800(x) (((s32) (x)) & 0x0003ffff)
+#define mgaF2400(x) (((s32) (x)) & 0x00ffffff)
+#define mgaF2200(x) (((s32) (x)) & 0x003fffff)
+
+#define OUTREG(r,d) do { mga_out32( mmio, d, r ); } while (0)
+
+#define MGA_S(start,xinc,yinc) \
+ do { \
+ mga_out32( mmio, start, TMR6 ); \
+ mga_out32( mmio, xinc, TMR0 ); \
+ mga_out32( mmio, yinc, TMR1 ); \
+ } while (0)
+
+#define MGA_T(start,xinc,yinc) \
+ do { \
+ mga_out32( mmio, start, TMR7 ); \
+ mga_out32( mmio, xinc, TMR2 ); \
+ mga_out32( mmio, yinc, TMR3 ); \
+ } while (0)
+
+#define MGA_Q(start,xinc,yinc) \
+ do { \
+ mga_out32( mmio, start, TMR8 ); \
+ mga_out32( mmio, xinc, TMR4 ); \
+ mga_out32( mmio, yinc, TMR5 ); \
+ } while (0)
+
+
+#define MGA_LSLOPE(dx,dy,sgn,err) \
+ do { \
+ mga_out32( mmio, mgaF1800(dy), AR0 ); \
+ if ((dx) >= 0) { \
+ mga_out32( mmio, mgaF2400(-(dx)+(err)), AR1 ); \
+ mga_out32( mmio, mgaF1800(-(dx)), AR2 ); \
+ sgn &= ~SDXL; \
+ } \
+ else { \
+ mga_out32( mmio, mgaF2400((dx)+(dy)-(err)-1), AR1 ); \
+ mga_out32( mmio, mgaF1800(dx), AR2 ); \
+ sgn |= SDXL; \
+ } \
+ } while(0)
+
+
+#define MGA_G400_LSLOPE(dx,dy,sgn,err) \
+ do { \
+ mga_out32( mmio, mgaF2200(dy), AR0 ); \
+ if ((dx) >= 0) { \
+ mga_out32( mmio, mgaF2400(-(dx)+(err)), AR1 ); \
+ mga_out32( mmio, mgaF2200(-(dx)), AR2); \
+ sgn &= ~SDXL; \
+ } \
+ else { \
+ mga_out32( mmio, mgaF2400((dx)+(dy)-(err)-1), AR1 ); \
+ mga_out32( mmio, mgaF2200(dx), AR2 ); \
+ sgn |= SDXL; \
+ } \
+ } while(0)
+
+
+#define MGA_RSLOPE(dx,dy,sgn,err) \
+ do { \
+ mga_out32( mmio, mgaF1800(dy), AR6); \
+ if ((dx) >= 0) { \
+ mga_out32( mmio, mgaF1800(-(dx)+(err)), AR4 ); \
+ mga_out32( mmio, mgaF1800(-(dx)), AR5 ); \
+ sgn &= ~SDXR; \
+ } \
+ else { \
+ mga_out32( mmio, mgaF1800((dx)+(dy)-(err)-1), AR4 ); \
+ mga_out32( mmio, mgaF1800(dx), AR5 ); \
+ sgn |= SDXR; \
+ } \
+ } while(0)
+
+
+#define MGA_G400_RSLOPE(dx,dy,sgn,err) \
+ do { \
+ mga_out32( mmio, mgaF2200(dy), AR6 ); \
+ if ((dx) >= 0) { \
+ mga_out32( mmio, mgaF2200(-(dx)+(err)), AR4 ); \
+ mga_out32( mmio, mgaF2200(-(dx)), AR5 ); \
+ sgn &= ~SDXR; \
+ } \
+ else { \
+ mga_out32( mmio, mgaF2200((dx)+(dy)-(err)-1), AR4 ); \
+ mga_out32( mmio, mgaF2200(dx), AR5); \
+ sgn |= SDXR; \
+ } \
+ } while(0)
+
+
+typedef struct {
+ DFBVertex *v0, *v1; /* Y(v0) < Y(v1) */
+ float dx; /* X(v1) - X(v0) */
+ float dy; /* Y(v1) - Y(v0) */
+ float dxOOA; /* dx * oneOverArea */
+ float dyOOA; /* dy * oneOverArea */
+
+ float adjx,adjy; /* subpixel offset after rounding to integer */
+ int err; /* error term ready for hardware */
+ int idx,idy; /* delta-x & delta-y ready for hardware */
+ int sx,sy; /* first sample point x,y coord */
+ int lines; /* number of lines to be sampled on this edge */
+} EdgeT;
+
+
+static void
+texture_triangle( MatroxDriverData *mdrv, MatroxDeviceData *mdev,
+ DFBVertex *v0, DFBVertex *v1, DFBVertex *v2 )
+{
+ EdgeT eMaj, eTop, eBot;
+ float oneOverArea;
+ DFBVertex *vMin, *vMid, *vMax; /* Y(vMin)<=Y(vMid)<=Y(vMax) */
+ int Shape; /* 1 = Top half, 2 = bottom half, 3 = top+bottom */
+// float bf = mga_bf_sign;
+
+ volatile u8 *mmio = mdrv->mmio_base;
+
+/* find the order of the 3 vertices along the Y axis */
+ {
+ float y0 = v0->y;
+ float y1 = v1->y;
+ float y2 = v2->y;
+
+ if (y0<=y1) {
+ if (y1<=y2) {
+ vMin = v0; vMid = v1; vMax = v2; /* y0<=y1<=y2 */
+ }
+ else if (y2<=y0) {
+ vMin = v2; vMid = v0; vMax = v1; /* y2<=y0<=y1 */
+ }
+ else {
+ vMin = v0; vMid = v2; vMax = v1; /*bf = -bf;*/ /* y0<=y2<=y1 */
+ }
+ }
+ else {
+ if (y0<=y2) {
+ vMin = v1; vMid = v0; vMax = v2; /*bf = -bf;*/ /* y1<=y0<=y2 */
+ }
+ else if (y2<=y1) {
+ vMin = v2; vMid = v1; vMax = v0; /*bf = -bf;*/ /* y2<=y1<=y0 */
+ }
+ else {
+ vMin = v1; vMid = v2; vMax = v0; /* y1<=y2<=y0 */
+ }
+ }
+ }
+
+/* vertex/edge relationship */
+ eMaj.v0 = vMin; eMaj.v1 = vMax;
+ eTop.v0 = vMin; eTop.v1 = vMid;
+ eBot.v0 = vMid; eBot.v1 = vMax;
+
+/* compute deltas for each edge: vertex[v1] - vertex[v0] */
+ eMaj.dx = vMax->x - vMin->x;
+ eMaj.dy = vMax->y - vMin->y;
+ eTop.dx = vMid->x - vMin->x;
+ eTop.dy = vMid->y - vMin->y;
+ eBot.dx = vMax->x - vMid->x;
+ eBot.dy = vMax->y - vMid->y;
+
+
+/* compute oneOverArea */
+ {
+ float area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
+
+ /* Do backface culling
+ */
+ //if ( area * bf < 0 || area == 0 )
+ //return;
+
+ oneOverArea = 1.0F / area;
+ }
+
+/* Edge setup. For a triangle strip these could be reused... */
+ {
+
+#define DELTASCALE 16 /* Scaling factor for idx and idy. Note that idx and
+ idy are 18 bits signed, so don't choose too big
+ value. */
+
+ int ivMax_y;
+ float temp;
+
+ ivMax_y = CEIL(vMax->y);
+ eTop.sy = eMaj.sy = CEIL(vMin->y);
+ eBot.sy = CEIL(vMid->y);
+
+ eMaj.lines = ivMax_y - eMaj.sy;
+ if (eMaj.lines > 0) {
+ float dxdy = eMaj.dx / eMaj.dy;
+ eMaj.adjy = (float) eMaj.sy - vMin->y;
+ temp = vMin->x + eMaj.adjy*dxdy;
+ eMaj.sx = CEIL(temp);
+ eMaj.adjx = (float) eMaj.sx - vMin->x;
+ if (eMaj.lines == 1) {
+ eMaj.idy = 1;
+ eMaj.idx = 0;
+ eMaj.err = 0;
+ }
+ else {
+ eMaj.idy = RINT(eMaj.dy * DELTASCALE);
+ eMaj.idx = FLOOR(eMaj.idy * dxdy);
+ eMaj.err = RINT(((float) eMaj.sx - temp) * (float)eMaj.idy);
+ }
+ }
+ else {
+ return; /* CULLED */
+ }
+
+ Shape = 3;
+
+ eBot.lines = ivMax_y - eBot.sy;
+ if (eBot.lines > 0) {
+ float dxdy = eBot.dx / eBot.dy;
+ eBot.adjy = (float) eBot.sy - vMid->y;
+ temp = vMid->x + eBot.adjy*dxdy;
+ eBot.sx = CEIL(temp);
+ eBot.adjx = (float) eBot.sx - vMid->x;
+ if (eBot.lines == 1) {
+ eBot.idy = 1;
+ eBot.idx = 0;
+ eBot.err = 0;
+ }
+ else {
+ eBot.idy = RINT(eBot.dy * DELTASCALE);
+ eBot.idx = FLOOR(eBot.idy * dxdy);
+ eBot.err = RINT(((float) eBot.sx - temp) * (float)eBot.idy);
+ }
+ }
+ else {
+ Shape = 1;
+ }
+
+ eTop.lines = eBot.sy - eTop.sy;
+ if (eTop.lines > 0) {
+ float dxdy = eTop.dx / eTop.dy;
+ eTop.adjy = eMaj.adjy;
+ temp = vMin->x + eTop.adjy*dxdy;
+ eTop.sx = CEIL(temp);
+ eTop.adjx = (float) eTop.sx - vMin->x;
+ if (eTop.lines == 1) {
+ eTop.idy = 1;
+ if (eBot.lines > 0) {
+ eTop.idx = eBot.sx - eTop.sx; /* needed for bottom half */
+ }
+ else {
+ eTop.idx = 0;
+ }
+ eTop.err = 0;
+ }
+ else {
+ eTop.idy = RINT(eTop.dy * DELTASCALE);
+ eTop.idx = FLOOR(eTop.idy * dxdy);
+ eTop.err = RINT(((float) eTop.sx - temp) * (float)eTop.idy);
+ }
+ }
+ else {
+ Shape = 2;
+ }
+ }
+
+ {
+ int ltor; /* true if scanning left-to-right */
+ EdgeT *eLeft, *eRight;
+ int lines;
+ DFBVertex *vTL; /* Top left vertex */
+ float adjx, adjy;
+
+ /*
+ * Execute user-supplied setup code
+ */
+#ifdef SETUP_CODE
+ SETUP_CODE
+#endif
+
+ ltor = (oneOverArea > 0.0F);
+
+ if (Shape == 2) {
+ /* bottom half triangle */
+ if (ltor) {
+ eLeft = &eMaj;
+ eRight = &eBot;
+ }
+ else {
+ eLeft = &eBot;
+ eRight = &eMaj;
+ }
+ lines = eBot.lines;
+ }
+ else {
+ /* top half triangle */
+ if (ltor) {
+ eLeft = &eMaj;
+ eRight = &eTop;
+ }
+ else {
+ eLeft = &eTop;
+ eRight = &eMaj;
+ }
+ lines = eTop.lines;
+ }
+
+ vTL = eLeft->v0;
+ adjx = eLeft->adjx; adjy = eLeft->adjy;
+
+
+ /* setup derivatives */
+/* compute d?/dx and d?/dy derivatives */
+ eBot.dxOOA = eBot.dx * oneOverArea;
+ eBot.dyOOA = eBot.dy * oneOverArea;
+ eMaj.dxOOA = eMaj.dx * oneOverArea;
+ eMaj.dyOOA = eMaj.dy * oneOverArea;
+
+#define DERIV( DZ, COMP) \
+ { \
+ float eMaj_DZ, eBot_DZ; \
+ eMaj_DZ = vMax->COMP - vMin->COMP; \
+ eBot_DZ = vMax->COMP - vMid->COMP; \
+ DZ ## dx = eMaj_DZ * eBot.dyOOA - eMaj.dyOOA * eBot_DZ; \
+ DZ ## dy = eMaj.dxOOA * eBot_DZ - eMaj_DZ * eBot.dxOOA; \
+ }
+
+ if (mdev->depth_buffer) {
+ float Zstart;
+ float dzdx, dzdy;
+
+ DERIV(dz, z);
+
+ if (dzdx>65535.0f*(1<<15) || dzdx<-65535.0f*(1<<15)) {
+ /* probably a sliver triangle */
+ dzdx = 0.0;
+ dzdy = 0.0;
+ }
+
+ Zstart = vTL->z + dzdx*adjx + dzdy*adjy;
+
+ /* FIXME: 16 bit assumed */
+ if (Zstart > 65535.0f*(1 << 15)) {
+ Zstart = 65535.0f*(1 << 15);
+ dzdx = 0.0F;
+ dzdy = 0.0F;
+ }
+
+ mga_waitfifo( mdrv, mdev, 3 );
+
+ mga_out32( mmio, RINT(Zstart), DR0 );
+ mga_out32( mmio, RINT(dzdx), DR2 );
+ mga_out32( mmio, RINT(dzdy), DR3 );
+ }
+
+ {
+ float dsdx, dsdy;
+ float dtdx, dtdy;
+ float dvdx, dvdy;
+
+ mga_waitfifo( mdrv, mdev, 9 );
+
+ DERIV(ds,s);
+
+ MGA_S(RINT( (vTL->s+dsdx*adjx+dsdy*adjy) ),
+ RINT( dsdx ), RINT( dsdy ));
+
+ DERIV(dt,t);
+
+ MGA_T(RINT( (vTL->t+dtdx*adjx+dtdy*adjy) ),
+ RINT( dtdx ), RINT( dtdy ));
+
+ DERIV(dv,w);
+ {
+ int sq = RINT( (vTL->w+dvdx*adjx+dvdy*adjy) );
+ MGA_Q((sq == 0) ? 1 : sq,RINT(dvdx),RINT(dvdy));
+ }
+ }
+
+ {
+ u32 sgn = 0;
+
+ mga_waitfifo( mdrv, mdev, 9 );
+
+ /* Draw part #1 */
+ if (mdrv->accelerator == FB_ACCEL_MATROX_MGAG400) {
+ MGA_G400_LSLOPE(eLeft->idx,eLeft->idy,sgn,eLeft->err);
+ MGA_G400_RSLOPE(eRight->idx,eRight->idy,sgn,eRight->err);
+ }
+ else {
+ MGA_LSLOPE(eLeft->idx,eLeft->idy,sgn,eLeft->err);
+ MGA_RSLOPE(eRight->idx,eRight->idy,sgn,eRight->err);
+ }
+
+ mga_out32( mmio, sgn, SGN );
+ mga_out32( mmio, ((u32)(eLeft->sx) & 0xFFFF) | ((u32)(eRight->sx) << 16), FXBNDRY );
+ mga_out32( mmio, lines | ((u32)(eLeft->sy) << 16), YDSTLEN | EXECUTE );
+
+ if (Shape != 3) { /* has only one half? */
+ return;
+ }
+
+ mga_waitfifo( mdrv, mdev, 6 );
+
+ /* Draw part #2 */
+ if (ltor) {
+ if (mdrv->accelerator == FB_ACCEL_MATROX_MGAG400)
+ MGA_G400_RSLOPE(eBot.idx,eBot.idy,sgn,eBot.err);
+ else
+ MGA_RSLOPE(eBot.idx,eBot.idy,sgn,eBot.err);
+
+ mga_out32( mmio, eBot.sx, FXRIGHT );
+ }
+ else {
+ sgn |= SGN_BRKLEFT;
+ mga_out32( mmio, eBot.sx, FXLEFT );
+ if (mdrv->accelerator == FB_ACCEL_MATROX_MGAG400)
+ MGA_G400_LSLOPE(eBot.idx,eBot.idy,sgn,eBot.err);
+ else
+ MGA_LSLOPE(eBot.idx,eBot.idy,sgn,eBot.err);
+
+ }
+
+ mga_out32( mmio, sgn, SGN );
+ mga_out32( mmio, eBot.lines, LEN | EXECUTE );
+ }
+ }
+}
+
+#define INVWMAX 128.0F
+
+bool
+matroxTextureTriangles( void *drv, void *dev,
+ DFBVertex *vertices, int num,
+ DFBTriangleFormation formation )
+{
+ int i;
+ MatroxDriverData *mdrv = (MatroxDriverData*) drv;
+ MatroxDeviceData *mdev = (MatroxDeviceData*) dev;
+ volatile u8 *mmio = mdrv->mmio_base;
+ u32 dwgctl;
+
+ float wScale;
+
+#if 0
+ float InvWScale = 1.0f;
+ float nearVal = 1.0f;
+
+ if (nearVal > 0) {
+ /* limit InvWScale/wMin in (0,INVWMAX] to avoid over- and underflow.
+ InvWScale is used by texture setup in mga_tritemp.h */
+ int exp2;
+
+ if (frexp(INVWMAX * nearVal,&exp2) != 0) {
+ if (exp2 >= 2) {
+ InvWScale = 1 << (exp2-1);
+ }
+ else if (exp2 <= 0) {
+ InvWScale = 1.0 / (1 << (-exp2+1));
+ }
+ }
+ }
+#else
+#define InvWScale 128.0f
+#endif
+
+ wScale = InvWScale * (float) (1 << 20);
+
+ for (i=0; i<num; i++) {
+ DFBVertex *v = &vertices[i];
+
+ v->x -= 0.5f;
+ v->y -= 0.5f;
+ v->z *= (float) (1 << 15) * 65535.0f;
+ v->w *= wScale;
+
+ v->s *= v->w * (float) mdev->w / (float) (1 << mdev->w2);
+ v->t *= v->w * (float) mdev->h / (float) (1 << mdev->h2);
+ }
+
+ if (mdev->depth_buffer)
+ dwgctl = ATYPE_ZI | ZMODE_ZLTE;
+ else
+ dwgctl = ATYPE_I | ZMODE_NOZCMP;
+
+ mga_waitfifo( mdrv, mdev, 2 );
+
+ mga_out32( mmio, dwgctl | BOP_COPY | SHFTZERO | OP_TEXTURE_TRAP, DWGCTL );
+ mga_out32( mmio, (0x10<<21) | MAG_BILIN | MIN_ANISO | FILTER_ALPHA, TEXFILTER );
+
+ switch (formation) {
+ case DTTF_LIST:
+ for (i=0; i<num; i+=3)
+ texture_triangle( mdrv, mdev, &vertices[i], &vertices[i+1], &vertices[i+2] );
+
+ break;
+
+ case DTTF_STRIP:
+ texture_triangle( mdrv, mdev, &vertices[0], &vertices[1], &vertices[2] );
+
+ for (i=3; i<num; i++)
+ texture_triangle( mdrv, mdev, &vertices[i-2], &vertices[i-1], &vertices[i] );
+
+ break;
+
+ case DTTF_FAN:
+ texture_triangle( mdrv, mdev, &vertices[0], &vertices[1], &vertices[2] );
+
+ for (i=3; i<num; i++)
+ texture_triangle( mdrv, mdev, &vertices[0], &vertices[i-1], &vertices[i] );
+
+ break;
+
+ default:
+ D_ONCE( "unknown formation" );
+ return false;
+ }
+
+ mga_waitfifo( mdrv, mdev, 5 );
+ mga_out32( mmio, 0, TMR1 );
+ mga_out32( mmio, 0, TMR2 );
+ mga_out32( mmio, 0, TMR4 );
+ mga_out32( mmio, 0, TMR5 );
+ mga_out32( mmio, 0x100000, TMR8 );
+
+ return true;
+}
+
diff --git a/Source/DirectFB/gfxdrivers/matrox/matrox_3d.h b/Source/DirectFB/gfxdrivers/matrox/matrox_3d.h
new file mode 100755
index 0000000..8a1181e
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/matrox_3d.h
@@ -0,0 +1,36 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef ___MATROX_3D_H__
+#define ___MATROX_3D_H__
+
+bool matroxTextureTriangles( void *drv, void *dev,
+ DFBVertex *vertices, int num,
+ DFBTriangleFormation formation );
+
+#endif
diff --git a/Source/DirectFB/gfxdrivers/matrox/matrox_bes.c b/Source/DirectFB/gfxdrivers/matrox/matrox_bes.c
new file mode 100755
index 0000000..df1d4ab
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/matrox_bes.c
@@ -0,0 +1,783 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <fbdev/fb.h>
+
+#include <directfb.h>
+
+#include <direct/messages.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+#include <core/layers.h>
+#include <core/screen.h>
+#include <core/surface.h>
+#include <core/system.h>
+
+#include <misc/util.h>
+
+#include "regs.h"
+#include "mmio.h"
+#include "matrox.h"
+
+typedef struct {
+ CoreLayerRegionConfig config;
+
+ /* Stored registers */
+ struct {
+ /* BES */
+ u32 besGLOBCTL;
+ u32 besA1ORG;
+ u32 besA2ORG;
+ u32 besA1CORG;
+ u32 besA2CORG;
+ u32 besA1C3ORG;
+ u32 besA2C3ORG;
+ u32 besCTL;
+
+ u32 besCTL_field;
+
+ u32 besHCOORD;
+ u32 besVCOORD;
+
+ u32 besHSRCST;
+ u32 besHSRCEND;
+ u32 besHSRCLST;
+
+ u32 besPITCH;
+
+ u32 besV1WGHT;
+ u32 besV2WGHT;
+
+ u32 besV1SRCLST;
+ u32 besV2SRCLST;
+
+ u32 besVISCAL;
+ u32 besHISCAL;
+
+ u8 xKEYOPMODE;
+ } regs;
+} MatroxBesLayerData;
+
+static bool bes_set_buffer( MatroxDriverData *mdrv, MatroxBesLayerData *mbes,
+ bool onsync );
+static void bes_set_regs( MatroxDriverData *mdrv, MatroxBesLayerData *mbes );
+static void bes_calc_regs( MatroxDriverData *mdrv, MatroxBesLayerData *mbes,
+ CoreLayerRegionConfig *config, CoreSurface *surface,
+ CoreSurfaceBufferLock *lock );
+
+#define BES_SUPPORTED_OPTIONS (DLOP_DEINTERLACING | DLOP_DST_COLORKEY)
+
+
+/**********************/
+
+static int
+besLayerDataSize( void )
+{
+ return sizeof(MatroxBesLayerData);
+}
+
+static DFBResult
+besInitLayer( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ DFBDisplayLayerDescription *description,
+ DFBDisplayLayerConfig *config,
+ DFBColorAdjustment *adjustment )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ /* set capabilities and type */
+ description->caps = DLCAPS_SCREEN_LOCATION | DLCAPS_SURFACE |
+ DLCAPS_DEINTERLACING | DLCAPS_DST_COLORKEY;
+ description->type = DLTF_GRAPHICS | DLTF_VIDEO | DLTF_STILL_PICTURE;
+
+ /* set name */
+ snprintf( description->name,
+ DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "Matrox Backend Scaler" );
+
+ /* fill out the default configuration */
+ config->flags = DLCONF_WIDTH | DLCONF_HEIGHT |
+ DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE |
+ DLCONF_OPTIONS;
+ config->width = 640;
+ config->height = 480;
+ config->pixelformat = DSPF_YUY2;
+ config->buffermode = DLBM_FRONTONLY;
+ config->options = DLOP_NONE;
+
+ adjustment->flags = DCAF_NONE;
+
+ if (mdrv->accelerator != FB_ACCEL_MATROX_MGAG200) {
+ description->caps |= DLCAPS_BRIGHTNESS | DLCAPS_CONTRAST;
+
+ /* fill out default color adjustment,
+ only fields set in flags will be accepted from applications */
+ adjustment->flags |= DCAF_BRIGHTNESS | DCAF_CONTRAST;
+ adjustment->brightness = 0x8000;
+ adjustment->contrast = 0x8000;
+
+ mga_out32( mmio, 0x80, BESLUMACTL );
+ }
+
+ /* make sure BES registers get updated (besvcnt) */
+ mga_out32( mmio, 0, BESGLOBCTL );
+ /* disable backend scaler */
+ mga_out32( mmio, 0, BESCTL );
+
+ /* set defaults */
+ mga_out_dac( mmio, XKEYOPMODE, 0x00 ); /* keying off */
+
+ mga_out_dac( mmio, XCOLMSK0RED, 0xFF ); /* full mask */
+ mga_out_dac( mmio, XCOLMSK0GREEN, 0xFF );
+ mga_out_dac( mmio, XCOLMSK0BLUE, 0xFF );
+
+ mga_out_dac( mmio, XCOLKEY0RED, 0x00 ); /* default to black */
+ mga_out_dac( mmio, XCOLKEY0GREEN, 0x00 );
+ mga_out_dac( mmio, XCOLKEY0BLUE, 0x00 );
+
+ return DFB_OK;
+}
+
+static DFBResult
+besTestRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags *failed )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxDeviceData *mdev = mdrv->device_data;
+ int max_width = mdev->g450_matrox ? 2048 : 1024;
+ int max_height = 1024;
+ CoreLayerRegionConfigFlags fail = 0;
+
+ if (config->options & ~BES_SUPPORTED_OPTIONS)
+ fail |= CLRCF_OPTIONS;
+
+ if (config->surface_caps & ~(DSCAPS_INTERLACED | DSCAPS_SEPARATED))
+ fail |= CLRCF_SURFACE_CAPS;
+
+ if (config->options & DLOP_DEINTERLACING) {
+ /* make sure BESPITCH < 4096 */
+ if (mdev->g450_matrox && !(config->surface_caps & DSCAPS_SEPARATED))
+ max_width = 2048 - 128;
+ max_height = 2048;
+ } else {
+ if (config->surface_caps & DSCAPS_SEPARATED)
+ fail |= CLRCF_SURFACE_CAPS;
+ }
+
+ switch (config->format) {
+ case DSPF_YUY2:
+ case DSPF_NV12:
+ case DSPF_NV21:
+ break;
+
+ case DSPF_ARGB:
+ case DSPF_RGB32:
+ if (!mdev->g450_matrox)
+ max_width = 512;
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_UYVY:
+ case DSPF_I420:
+ case DSPF_YV12:
+ /* these formats are not supported by G200 */
+ if (mdrv->accelerator != FB_ACCEL_MATROX_MGAG200)
+ break;
+ default:
+ fail |= CLRCF_FORMAT;
+ }
+
+ switch (config->format) {
+ case DSPF_I420:
+ case DSPF_YV12:
+ case DSPF_NV12:
+ case DSPF_NV21:
+ if (config->height & 1)
+ fail |= CLRCF_HEIGHT;
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ if (config->width & 1)
+ fail |= CLRCF_WIDTH;
+ default:
+ break;
+ }
+
+ if (config->width > max_width || config->width < 1)
+ fail |= CLRCF_WIDTH;
+
+ if (config->height > max_height || config->height < 1)
+ fail |= CLRCF_HEIGHT;
+
+ if (failed)
+ *failed = fail;
+
+ if (fail)
+ return DFB_UNSUPPORTED;
+
+ return DFB_OK;
+}
+
+static DFBResult
+besSetRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags updated,
+ CoreSurface *surface,
+ CorePalette *palette,
+ CoreSurfaceBufferLock *lock )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxBesLayerData *mbes = (MatroxBesLayerData*) layer_data;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ /* remember configuration */
+ mbes->config = *config;
+
+ /* set main configuration */
+ if (updated & (CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_FORMAT |
+ CLRCF_OPTIONS | CLRCF_DEST | CLRCF_OPACITY | CLRCF_SOURCE))
+ {
+ bes_calc_regs( mdrv, mbes, config, surface, lock );
+ bes_set_regs( mdrv, mbes );
+ }
+
+ /* set color key */
+ if (updated & CLRCF_DSTKEY) {
+ DFBColorKey key = config->dst_key;
+
+ switch (dfb_primary_layer_pixelformat()) {
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ key.r >>= 3;
+ key.g >>= 3;
+ key.b >>= 3;
+ break;
+
+ case DSPF_RGB16:
+ key.r >>= 3;
+ key.g >>= 2;
+ key.b >>= 3;
+ break;
+
+ default:
+ ;
+ }
+
+ mga_out_dac( mmio, XCOLKEY0RED, key.r );
+ mga_out_dac( mmio, XCOLKEY0GREEN, key.g );
+ mga_out_dac( mmio, XCOLKEY0BLUE, key.b );
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+besRemoveRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ /* make sure BES registers get updated (besvcnt) */
+ mga_out32( mmio, 0, BESGLOBCTL );
+ /* disable backend scaler */
+ mga_out32( mmio, 0, BESCTL );
+
+ return DFB_OK;
+}
+
+static DFBResult
+besFlipRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreSurface *surface,
+ DFBSurfaceFlipFlags flags,
+ CoreSurfaceBufferLock *lock )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxBesLayerData *mbes = (MatroxBesLayerData*) layer_data;
+ bool swap;
+
+ bes_calc_regs( mdrv, mbes, &mbes->config, surface, lock );
+ swap = bes_set_buffer( mdrv, mbes, flags & DSFLIP_ONSYNC );
+
+ dfb_surface_flip( surface, swap );
+
+ if (flags & DSFLIP_WAIT)
+ dfb_screen_wait_vsync( mdrv->primary );
+
+ return DFB_OK;
+}
+
+static DFBResult
+besSetColorAdjustment( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ DFBColorAdjustment *adj )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ if (mdrv->accelerator == FB_ACCEL_MATROX_MGAG200)
+ return DFB_UNSUPPORTED;
+
+ mga_out32( mmio, (adj->contrast >> 8) |
+ ((u8)(((int)adj->brightness >> 8) - 128)) << 16,
+ BESLUMACTL );
+
+ return DFB_OK;
+}
+
+static DFBResult
+besSetInputField( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ int field )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxBesLayerData *mbes = (MatroxBesLayerData*) layer_data;
+
+ mbes->regs.besCTL_field = field ? 0x2000000 : 0;
+
+ mga_out32( mdrv->mmio_base,
+ mbes->regs.besCTL | mbes->regs.besCTL_field, BESCTL );
+
+ return DFB_OK;
+}
+
+DisplayLayerFuncs matroxBesFuncs = {
+ .LayerDataSize = besLayerDataSize,
+ .InitLayer = besInitLayer,
+
+ .TestRegion = besTestRegion,
+ .SetRegion = besSetRegion,
+ .RemoveRegion = besRemoveRegion,
+ .FlipRegion = besFlipRegion,
+
+ .SetColorAdjustment = besSetColorAdjustment,
+ .SetInputField = besSetInputField,
+};
+
+
+/* internal */
+
+static void bes_set_regs( MatroxDriverData *mdrv, MatroxBesLayerData *mbes )
+{
+ int line = 0;
+ volatile u8 *mmio = mdrv->mmio_base;
+ VideoMode *mode = dfb_system_current_mode();
+
+ if (!mode) {
+ mode = dfb_system_modes();
+ if (!mode)
+ return;
+ }
+
+ /* prevent updates */
+ line = 0xfff;
+ mga_out32( mmio, mbes->regs.besGLOBCTL | (line << 16), BESGLOBCTL);
+
+ if (!(mbes->regs.besCTL & 0x4000000)) {
+ mga_out32( mmio, mbes->regs.besA1ORG, BESA1ORG );
+ mga_out32( mmio, mbes->regs.besA2ORG, BESA2ORG );
+ mga_out32( mmio, mbes->regs.besA1CORG, BESA1CORG );
+ mga_out32( mmio, mbes->regs.besA2CORG, BESA2CORG );
+
+ if (mdrv->accelerator != FB_ACCEL_MATROX_MGAG200) {
+ mga_out32( mmio, mbes->regs.besA1C3ORG, BESA1C3ORG );
+ mga_out32( mmio, mbes->regs.besA2C3ORG, BESA2C3ORG );
+ }
+ } else {
+ mga_out32( mmio, mbes->regs.besA1ORG, BESB1ORG );
+ mga_out32( mmio, mbes->regs.besA2ORG, BESB2ORG );
+ mga_out32( mmio, mbes->regs.besA1CORG, BESB1CORG );
+ mga_out32( mmio, mbes->regs.besA2CORG, BESB2CORG );
+
+ if (mdrv->accelerator != FB_ACCEL_MATROX_MGAG200) {
+ mga_out32( mmio, mbes->regs.besA1C3ORG, BESB1C3ORG );
+ mga_out32( mmio, mbes->regs.besA2C3ORG, BESB2C3ORG );
+ }
+ }
+
+ mga_out32( mmio, mbes->regs.besCTL | mbes->regs.besCTL_field, BESCTL );
+
+ mga_out32( mmio, mbes->regs.besHCOORD, BESHCOORD );
+ mga_out32( mmio, mbes->regs.besVCOORD, BESVCOORD );
+
+ mga_out32( mmio, mbes->regs.besHSRCST, BESHSRCST );
+ mga_out32( mmio, mbes->regs.besHSRCEND, BESHSRCEND );
+ mga_out32( mmio, mbes->regs.besHSRCLST, BESHSRCLST );
+
+ mga_out32( mmio, mbes->regs.besPITCH, BESPITCH );
+
+ mga_out32( mmio, mbes->regs.besV1WGHT, BESV1WGHT );
+ mga_out32( mmio, mbes->regs.besV2WGHT, BESV2WGHT );
+
+ mga_out32( mmio, mbes->regs.besV1SRCLST, BESV1SRCLST );
+ mga_out32( mmio, mbes->regs.besV2SRCLST, BESV2SRCLST );
+
+ mga_out32( mmio, mbes->regs.besVISCAL, BESVISCAL );
+ mga_out32( mmio, mbes->regs.besHISCAL, BESHISCAL );
+
+ /* allow updates again */
+ line = mode->yres;
+ mga_out32( mmio, mbes->regs.besGLOBCTL | (line << 16), BESGLOBCTL);
+
+ mga_out_dac( mmio, XKEYOPMODE, mbes->regs.xKEYOPMODE );
+}
+
+static bool bes_set_buffer( MatroxDriverData *mdrv, MatroxBesLayerData *mbes, bool onsync )
+{
+ bool ret;
+ u32 status;
+ int line;
+ volatile u8 *mmio = mdrv->mmio_base;
+ VideoMode *mode = dfb_system_current_mode();
+
+ if (!mode) {
+ mode = dfb_system_modes();
+ if (!mode)
+ return false;
+ }
+
+ /* prevent updates */
+ line = 0xfff;
+ mga_out32( mmio, mbes->regs.besGLOBCTL | (line << 16), BESGLOBCTL);
+
+ status = mga_in32( mmio, BESSTATUS );
+
+ /* Had the previous flip actually occured? */
+ ret = !(status & 0x2) != !(mbes->regs.besCTL & 0x4000000);
+
+ /*
+ * Pick the next buffer based on what's being displayed right now
+ * so that it's possible to detect if the flip actually occured
+ * regardless of how many times the buffers are flipped during one
+ * displayed frame.
+ */
+ if (status & 0x2) {
+ mga_out32( mmio, mbes->regs.besA1ORG, BESA1ORG );
+ mga_out32( mmio, mbes->regs.besA2ORG, BESA2ORG );
+ mga_out32( mmio, mbes->regs.besA1CORG, BESA1CORG );
+ mga_out32( mmio, mbes->regs.besA2CORG, BESA2CORG );
+
+ if (mdrv->accelerator != FB_ACCEL_MATROX_MGAG200) {
+ mga_out32( mmio, mbes->regs.besA1C3ORG, BESA1C3ORG );
+ mga_out32( mmio, mbes->regs.besA2C3ORG, BESA2C3ORG );
+ }
+
+ mbes->regs.besCTL &= ~0x4000000;
+ } else {
+ mga_out32( mmio, mbes->regs.besA1ORG, BESB1ORG );
+ mga_out32( mmio, mbes->regs.besA2ORG, BESB2ORG );
+ mga_out32( mmio, mbes->regs.besA1CORG, BESB1CORG );
+ mga_out32( mmio, mbes->regs.besA2CORG, BESB2CORG );
+
+ if (mdrv->accelerator != FB_ACCEL_MATROX_MGAG200) {
+ mga_out32( mmio, mbes->regs.besA1C3ORG, BESB1C3ORG );
+ mga_out32( mmio, mbes->regs.besA2C3ORG, BESB2C3ORG );
+ }
+
+ mbes->regs.besCTL |= 0x4000000;
+ }
+
+ mga_out32( mmio, mbes->regs.besCTL | mbes->regs.besCTL_field, BESCTL );
+
+ /* allow updates again */
+ if (onsync)
+ line = mode->yres;
+ else
+ line = mga_in32( mmio, MGAREG_VCOUNT ) + 48;
+ mga_out32( mmio, mbes->regs.besGLOBCTL | (line << 16), BESGLOBCTL);
+
+ return ret;
+}
+
+static void bes_calc_regs( MatroxDriverData *mdrv,
+ MatroxBesLayerData *mbes,
+ CoreLayerRegionConfig *config,
+ CoreSurface *surface,
+ CoreSurfaceBufferLock *lock )
+{
+ MatroxDeviceData *mdev = mdrv->device_data;
+ int cropleft, cropright, croptop, cropbot, croptop_uv;
+ int pitch, tmp, hzoom, intrep, field_height, field_offset;
+ DFBRectangle source, dest;
+ DFBRegion dst;
+ bool visible;
+ VideoMode *mode = dfb_system_current_mode();
+
+ if (!mode) {
+ mode = dfb_system_modes();
+ if (!mode) {
+ D_BUG( "No current and no default mode" );
+ return;
+ }
+ }
+
+ source = config->source;
+ dest = config->dest;
+
+ if (!mdev->g450_matrox && (surface->config.format == DSPF_RGB32 || surface->config.format == DSPF_ARGB))
+ dest.w = source.w;
+
+ pitch = lock->pitch;
+
+ field_height = surface->config.size.h;
+
+ if (config->options & DLOP_DEINTERLACING) {
+ field_height /= 2;
+ source.y /= 2;
+ source.h /= 2;
+ if (!(surface->config.caps & DSCAPS_SEPARATED))
+ pitch *= 2;
+ } else
+ mbes->regs.besCTL_field = 0;
+
+ /* destination region */
+ dst.x1 = dest.x;
+ dst.y1 = dest.y;
+ dst.x2 = dest.x + dest.w - 1;
+ dst.y2 = dest.y + dest.h - 1;
+
+ visible = dfb_region_intersect( &dst, 0, 0, mode->xres - 1, mode->yres - 1 );
+
+ /* calculate destination cropping */
+ cropleft = -dest.x;
+ croptop = -dest.y;
+ cropright = dest.x + dest.w - mode->xres;
+ cropbot = dest.y + dest.h - mode->yres;
+
+ cropleft = cropleft > 0 ? cropleft : 0;
+ croptop = croptop > 0 ? croptop : 0;
+ cropright = cropright > 0 ? cropright : 0;
+ cropbot = cropbot > 0 ? cropbot : 0;
+ croptop_uv = croptop;
+
+ /* scale crop values to source dimensions */
+ if (cropleft)
+ cropleft = ((u64) (source.w << 16) * cropleft / dest.w) & ~0x3;
+ if (croptop)
+ croptop = ((u64) (source.h << 16) * croptop / dest.h) & ~0x3;
+ if (cropright)
+ cropright = ((u64) (source.w << 16) * cropright / dest.w) & ~0x3;
+ if (cropbot)
+ cropbot = ((u64) (source.h << 16) * cropbot / dest.h) & ~0x3;
+ if (croptop_uv)
+ croptop_uv = ((u64) ((source.h/2) << 16) * croptop_uv / dest.h) & ~0x3;
+
+ /* should horizontal zoom be used? */
+ if (mdev->g450_matrox)
+ hzoom = (1000000/mode->pixclock >= 234) ? 1 : 0;
+ else
+ hzoom = (1000000/mode->pixclock >= 135) ? 1 : 0;
+
+ /* initialize */
+ mbes->regs.besGLOBCTL = 0;
+
+ /* preserve buffer */
+ mbes->regs.besCTL &= 0x4000000;
+
+ /* enable/disable depending on opacity */
+ if (config->opacity && visible)
+ mbes->regs.besCTL |= BESEN;
+
+ /* pixel format settings */
+ switch (surface->config.format) {
+ case DSPF_YV12:
+ mbes->regs.besGLOBCTL |= BESCORDER;
+ /* fall through */
+
+ case DSPF_I420:
+ mbes->regs.besGLOBCTL |= BESPROCAMP | BES3PLANE;
+ mbes->regs.besCTL |= BESHFEN | BESVFEN | BESCUPS | BES420PL;
+ break;
+
+ case DSPF_NV21:
+ mbes->regs.besGLOBCTL |= BESCORDER;
+ /* fall through */
+
+ case DSPF_NV12:
+ mbes->regs.besGLOBCTL |= BESPROCAMP;
+ mbes->regs.besCTL |= BESHFEN | BESVFEN | BESCUPS | BES420PL;
+ break;
+
+ case DSPF_UYVY:
+ mbes->regs.besGLOBCTL |= BESUYVYFMT;
+ /* fall through */
+
+ case DSPF_YUY2:
+ mbes->regs.besGLOBCTL |= BESPROCAMP;
+ mbes->regs.besCTL |= BESHFEN | BESVFEN | BESCUPS;
+ break;
+
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ mbes->regs.besGLOBCTL |= BESRGB15;
+ break;
+
+ case DSPF_RGB16:
+ mbes->regs.besGLOBCTL |= BESRGB16;
+ break;
+
+ case DSPF_ARGB:
+ case DSPF_RGB32:
+ mbes->regs.besGLOBCTL |= BESRGB32;
+ break;
+
+ default:
+ D_BUG( "unexpected pixelformat" );
+ return;
+ }
+
+ if (surface->config.size.w > 1024)
+ mbes->regs.besCTL &= ~BESVFEN;
+
+ mbes->regs.besGLOBCTL |= 3*hzoom;
+
+ mbes->regs.besPITCH = pitch / DFB_BYTES_PER_PIXEL(surface->config.format);
+
+ /* buffer offsets */
+
+ field_offset = lock->pitch;
+ if (surface->config.caps & DSCAPS_SEPARATED)
+ field_offset *= surface->config.size.h / 2;
+
+ mbes->regs.besA1ORG = lock->offset +
+ pitch * (source.y + (croptop >> 16));
+ mbes->regs.besA2ORG = mbes->regs.besA1ORG +
+ field_offset;
+
+ switch (surface->config.format) {
+ case DSPF_NV12:
+ case DSPF_NV21:
+ field_offset = lock->pitch;
+ if (surface->config.caps & DSCAPS_SEPARATED)
+ field_offset *= surface->config.size.h / 4;
+
+ mbes->regs.besA1CORG = lock->offset +
+ surface->config.size.h * lock->pitch +
+ pitch * (source.y/2 + (croptop_uv >> 16));
+ mbes->regs.besA2CORG = mbes->regs.besA1CORG +
+ field_offset;
+ break;
+
+ case DSPF_I420:
+ case DSPF_YV12:
+ field_offset = lock->pitch / 2;
+ if (surface->config.caps & DSCAPS_SEPARATED)
+ field_offset *= surface->config.size.h / 4;
+
+ mbes->regs.besA1CORG = lock->offset +
+ surface->config.size.h * lock->pitch +
+ pitch/2 * (source.y/2 + (croptop_uv >> 16));
+ mbes->regs.besA2CORG = mbes->regs.besA1CORG +
+ field_offset;
+
+ mbes->regs.besA1C3ORG = mbes->regs.besA1CORG +
+ surface->config.size.h/2 * lock->pitch/2;
+ mbes->regs.besA2C3ORG = mbes->regs.besA1C3ORG +
+ field_offset;
+ break;
+
+ default:
+ ;
+ }
+
+ mbes->regs.besHCOORD = (dst.x1 << 16) | dst.x2;
+ mbes->regs.besVCOORD = (dst.y1 << 16) | dst.y2;
+
+ mbes->regs.besHSRCST = (source.x << 16) + cropleft;
+ mbes->regs.besHSRCEND = ((source.x + source.w - 1) << 16) - cropright;
+ mbes->regs.besHSRCLST = (surface->config.size.w - 1) << 16;
+
+ /* vertical starting weights */
+ tmp = croptop & 0xfffc;
+ mbes->regs.besV1WGHT = tmp;
+ if (tmp >= 0x8000) {
+ tmp = tmp - 0x8000;
+ /* fields start on the same line */
+ if ((source.y + (croptop >> 16)) & 1)
+ mbes->regs.besCTL |= BESV1SRCSTP | BESV2SRCSTP;
+ } else {
+ tmp = 0x10000 | (0x8000 - tmp);
+ /* fields start on alternate lines */
+ if ((source.y + (croptop >> 16)) & 1)
+ mbes->regs.besCTL |= BESV1SRCSTP;
+ else
+ mbes->regs.besCTL |= BESV2SRCSTP;
+ }
+ mbes->regs.besV2WGHT = tmp;
+
+ mbes->regs.besV1SRCLST = mbes->regs.besV2SRCLST =
+ field_height - 1 - source.y - (croptop >> 16);
+
+ /* horizontal scaling */
+ if (!mdev->g450_matrox && (surface->config.format == DSPF_RGB32 || surface->config.format == DSPF_ARGB)) {
+ mbes->regs.besHISCAL = 0x20000 << hzoom;
+ mbes->regs.besHSRCST *= 2;
+ mbes->regs.besHSRCEND *= 2;
+ mbes->regs.besHSRCLST *= 2;
+ mbes->regs.besPITCH *= 2;
+ } else {
+ intrep = ((mbes->regs.besCTL & BESHFEN) || (source.w > dest.w)) ? 1 : 0;
+ if ((dest.w == source.w) || (dest.w < 2))
+ intrep = 0;
+ tmp = (((source.w - intrep) << 16) / (dest.w - intrep)) << hzoom;
+ if (tmp >= (32 << 16))
+ tmp = (32 << 16) - 1;
+ mbes->regs.besHISCAL = tmp & 0x001ffffc;
+ }
+
+ /* vertical scaling */
+ intrep = ((mbes->regs.besCTL & BESVFEN) || (source.h > dest.h)) ? 1 : 0;
+ if ((dest.h == source.h) || (dest.h < 2))
+ intrep = 0;
+ tmp = ((source.h - intrep) << 16) / (dest.h - intrep);
+ if(tmp >= (32 << 16))
+ tmp = (32 << 16) - 1;
+ mbes->regs.besVISCAL = tmp & 0x001ffffc;
+
+ /* enable color keying? */
+ mbes->regs.xKEYOPMODE = (config->options & DLOP_DST_COLORKEY) ? 1 : 0;
+}
diff --git a/Source/DirectFB/gfxdrivers/matrox/matrox_crtc2.c b/Source/DirectFB/gfxdrivers/matrox/matrox_crtc2.c
new file mode 100755
index 0000000..36c83a3
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/matrox_crtc2.c
@@ -0,0 +1,751 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <directfb.h>
+
+#include <direct/messages.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+#include <core/layers.h>
+#include <core/screen.h>
+#include <core/surface.h>
+
+#include <misc/conf.h>
+
+#include "regs.h"
+#include "mmio.h"
+#include "matrox.h"
+#include "matrox_maven.h"
+
+typedef struct {
+ CoreLayerRegionConfig config;
+ DFBColorAdjustment adj;
+ int field;
+
+ /* Stored registers */
+ struct {
+ /* CRTC2 */
+ u32 c2CTL;
+ u32 c2DATACTL;
+ u32 c2MISC;
+ u32 c2OFFSET;
+
+ u32 c2HPARAM;
+ u32 c2VPARAM;
+
+ u32 c2STARTADD0;
+ u32 c2STARTADD1;
+ u32 c2PL2STARTADD0;
+ u32 c2PL2STARTADD1;
+ u32 c2PL3STARTADD0;
+ u32 c2PL3STARTADD1;
+ } regs;
+
+ MatroxMavenData mav;
+} MatroxCrtc2LayerData;
+
+static void crtc2_set_regs ( MatroxDriverData *mdrv,
+ MatroxCrtc2LayerData *mcrtc2 );
+
+static void crtc2_calc_regs ( MatroxDriverData *mdrv,
+ MatroxCrtc2LayerData *mcrtc2,
+ CoreLayerRegionConfig *config,
+ CoreSurface *surface,
+ CoreSurfaceBufferLock *lock );
+
+static void crtc2_calc_buffer ( MatroxDriverData *mdrv,
+ MatroxCrtc2LayerData *mcrtc2,
+ CoreSurface *surface,
+ CoreSurfaceBufferLock *lock );
+
+static void crtc2_set_buffer ( MatroxDriverData *mdrv,
+ MatroxCrtc2LayerData *mcrtc2 );
+
+static DFBResult crtc2_disable_output( MatroxDriverData *mdrv,
+ MatroxCrtc2LayerData *mcrtc2 );
+
+static DFBResult crtc2_enable_output ( MatroxDriverData *mdrv,
+ MatroxCrtc2LayerData *mcrtc2 );
+
+#define CRTC2_SUPPORTED_OPTIONS (DLOP_FIELD_PARITY)
+
+/**********************/
+
+static int
+crtc2LayerDataSize( void )
+{
+ return sizeof(MatroxCrtc2LayerData);
+}
+
+static const DFBColorAdjustment adjustments[2][2] = {
+ /* G400 */
+ {
+ /* PAL / PAL-60 */
+ {
+ .flags = DCAF_BRIGHTNESS | DCAF_CONTRAST | DCAF_HUE | DCAF_SATURATION,
+ .brightness = 0xA800,
+ .saturation = 0x9500,
+ .contrast = 0xFF00,
+ .hue = 0x0000,
+ },
+ /* NTSC */
+ {
+ .flags = DCAF_BRIGHTNESS | DCAF_CONTRAST | DCAF_HUE | DCAF_SATURATION,
+ .brightness = 0xB500,
+ .saturation = 0x8E00,
+ .contrast = 0xEA00,
+ .hue = 0x0000,
+ }
+ },
+ /* G450 / G550 */
+ {
+ /* PAL / PAL-60 */
+ {
+ .flags = DCAF_BRIGHTNESS | DCAF_CONTRAST | DCAF_HUE | DCAF_SATURATION,
+ .brightness = 0x9E00,
+ .saturation = 0xBB00,
+ .contrast = 0xFF00,
+ .hue = 0x0000,
+ },
+ /* NTSC */
+ {
+ .flags = DCAF_BRIGHTNESS | DCAF_CONTRAST | DCAF_HUE | DCAF_SATURATION,
+ .brightness = 0xAA00,
+ .saturation = 0xAE00,
+ .contrast = 0xEA00,
+ .hue = 0x0000,
+ }
+ }
+};
+
+static DFBResult
+crtc2InitLayer( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ DFBDisplayLayerDescription *description,
+ DFBDisplayLayerConfig *config,
+ DFBColorAdjustment *adjustment )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data;
+ MatroxDeviceData *mdev = mdrv->device_data;
+ MatroxMavenData *mav = &mcrtc2->mav;
+ DFBResult res;
+
+ if ((res = maven_init( mav, mdrv )) != DFB_OK)
+ return res;
+
+ /* set capabilities and type */
+ description->caps = DLCAPS_SURFACE | DLCAPS_FIELD_PARITY |
+ DLCAPS_BRIGHTNESS | DLCAPS_CONTRAST |
+ DLCAPS_HUE | DLCAPS_SATURATION | DLCAPS_ALPHA_RAMP;
+ description->type = DLTF_GRAPHICS | DLTF_VIDEO | DLTF_STILL_PICTURE;
+
+ /* set name */
+ snprintf( description->name,
+ DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "Matrox CRTC2 Layer" );
+
+ /* fill out the default configuration */
+ config->flags = DLCONF_WIDTH | DLCONF_HEIGHT |
+ DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE |
+ DLCONF_OPTIONS | DLCONF_SURFACE_CAPS;
+ config->width = 720;
+ config->height = (dfb_config->matrox_tv_std != DSETV_PAL) ? 480 : 576;
+ config->pixelformat = DSPF_YUY2;
+ config->buffermode = DLBM_FRONTONLY;
+ config->options = DLOP_NONE;
+ config->surface_caps = DSCAPS_INTERLACED;
+
+ /* fill out default color adjustment,
+ only fields set in flags will be accepted from applications */
+ *adjustment = adjustments[mdev->g450_matrox][dfb_config->matrox_tv_std == DSETV_NTSC];
+
+ /* remember color adjustment */
+ mcrtc2->adj = *adjustment;
+
+ return DFB_OK;
+}
+
+static DFBResult
+crtc2TestRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags *failed )
+{
+ CoreLayerRegionConfigFlags fail = 0;
+
+ if (config->options & ~CRTC2_SUPPORTED_OPTIONS)
+ fail |= CLRCF_OPTIONS;
+
+ if (config->surface_caps & ~(DSCAPS_INTERLACED | DSCAPS_SEPARATED))
+ fail |= CLRCF_SURFACE_CAPS;
+
+ switch (config->format) {
+ case DSPF_ARGB:
+ case DSPF_RGB32:
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ case DSPF_I420:
+ case DSPF_YV12:
+ break;
+ default:
+ fail |= CLRCF_FORMAT;
+ }
+
+ if (config->width != 720)
+ fail |= CLRCF_WIDTH;
+
+ if (config->height != ((dfb_config->matrox_tv_std != DSETV_PAL) ? 480 : 576))
+ fail |= CLRCF_HEIGHT;
+
+ if (failed)
+ *failed = fail;
+
+ if (fail)
+ return DFB_UNSUPPORTED;
+
+ return DFB_OK;
+}
+
+static DFBResult
+crtc2AddRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config )
+{
+ return DFB_OK;
+}
+
+static DFBResult
+crtc2SetRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags updated,
+ CoreSurface *surface,
+ CorePalette *palette,
+ CoreSurfaceBufferLock *lock )
+{
+ DFBResult ret;
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data;
+ MatroxDeviceData *mdev = mdrv->device_data;
+
+ /* remember configuration */
+ mcrtc2->config = *config;
+
+ if (updated & CLRCF_PARITY)
+ mcrtc2->field = !config->parity;
+
+ if (updated & (CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_FORMAT |
+ CLRCF_SURFACE_CAPS | CLRCF_ALPHA_RAMP | CLRCF_SURFACE)) {
+ crtc2_calc_regs( mdrv, mcrtc2, config, surface, lock );
+ crtc2_calc_buffer( mdrv, mcrtc2, surface, lock );
+
+ ret = crtc2_enable_output( mdrv, mcrtc2 );
+ if (ret)
+ return ret;
+
+ mdev->crtc2_separated = !!(surface->config.caps & DSCAPS_SEPARATED);
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+crtc2RemoveRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data;
+
+ crtc2_disable_output( mdrv, mcrtc2 );
+
+ return DFB_OK;
+}
+
+static DFBResult
+crtc2FlipRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreSurface *surface,
+ DFBSurfaceFlipFlags flags,
+ CoreSurfaceBufferLock *lock )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ crtc2_calc_buffer( mdrv, mcrtc2, surface, lock );
+
+ if (mcrtc2->config.options & DLOP_FIELD_PARITY) {
+ int field = (mga_in32( mmio, C2VCOUNT ) & C2FIELD) ? 1 : 0;
+
+ while (field == mcrtc2->field) {
+ dfb_screen_wait_vsync( mdrv->secondary );
+
+ field = (mga_in32( mmio, C2VCOUNT ) & C2FIELD) ? 1 : 0;
+ }
+ }
+ crtc2_set_buffer( mdrv, mcrtc2 );
+
+ dfb_surface_flip( surface, false );
+
+ if (flags & DSFLIP_WAIT)
+ dfb_screen_wait_vsync( mdrv->secondary );
+
+ return DFB_OK;
+}
+
+static DFBResult
+crtc2SetColorAdjustment( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ DFBColorAdjustment *adj )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data;
+ MatroxMavenData *mav = &mcrtc2->mav;
+ DFBResult res;
+
+ if ((res = maven_open( mav, mdrv )) != DFB_OK)
+ return res;
+
+ if (adj->flags & DCAF_HUE)
+ maven_set_hue( mav, mdrv,
+ adj->hue >> 8 );
+ if (adj->flags & DCAF_SATURATION)
+ maven_set_saturation( mav, mdrv,
+ adj->saturation >> 8 );
+ if (adj->flags & DCAF_BRIGHTNESS ||
+ adj->flags & DCAF_CONTRAST)
+ maven_set_bwlevel( mav, mdrv,
+ adj->brightness >> 8,
+ adj->contrast >> 8 );
+
+ maven_close( mav, mdrv );
+
+ /* remember color adjustment */
+ mcrtc2->adj = *adj;
+
+ return DFB_OK;
+}
+
+static DFBResult
+crtc2GetCurrentOutputField( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ int *field )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+
+ if (!field)
+ return DFB_INVARG;
+
+ *field = (mga_in32( mdrv->mmio_base, C2VCOUNT ) & C2FIELD) ? 1 : 0;
+
+ return DFB_OK;
+}
+
+DisplayLayerFuncs matroxCrtc2Funcs = {
+ .LayerDataSize = crtc2LayerDataSize,
+ .InitLayer = crtc2InitLayer,
+
+ .TestRegion = crtc2TestRegion,
+ .AddRegion = crtc2AddRegion,
+ .SetRegion = crtc2SetRegion,
+ .RemoveRegion = crtc2RemoveRegion,
+ .FlipRegion = crtc2FlipRegion,
+
+ .SetColorAdjustment = crtc2SetColorAdjustment,
+ .GetCurrentOutputField = crtc2GetCurrentOutputField,
+};
+
+/* internal */
+
+static void crtc2_set_regs( MatroxDriverData *mdrv,
+ MatroxCrtc2LayerData *mcrtc2 )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mga_out32( mmio, mcrtc2->regs.c2CTL, C2CTL );
+ mga_out32( mmio, mcrtc2->regs.c2DATACTL, C2DATACTL );
+ mga_out32( mmio, mcrtc2->regs.c2HPARAM, C2HPARAM );
+ mga_out32( mmio, 0, C2HSYNC );
+ mga_out32( mmio, mcrtc2->regs.c2VPARAM, C2VPARAM );
+ mga_out32( mmio, 0, C2VSYNC );
+ mga_out32( mmio, mcrtc2->regs.c2OFFSET, C2OFFSET );
+ mga_out32( mmio, mcrtc2->regs.c2MISC, C2MISC );
+ mga_out32( mmio, 0, C2PRELOAD );
+}
+
+static void crtc2_calc_regs( MatroxDriverData *mdrv,
+ MatroxCrtc2LayerData *mcrtc2,
+ CoreLayerRegionConfig *config,
+ CoreSurface *surface,
+ CoreSurfaceBufferLock *lock )
+{
+ MatroxDeviceData *mdev = mdrv->device_data;
+
+ mcrtc2->regs.c2CTL = 0;
+
+ /* Don't touch sub-picture bits. */
+ mcrtc2->regs.c2DATACTL = mga_in32( mdrv->mmio_base, C2DATACTL );
+ mcrtc2->regs.c2DATACTL &= C2STATICKEY | C2OFFSETDIVEN | C2STATICKEYEN | C2SUBPICEN;
+
+ if (mdev->g450_matrox)
+ mcrtc2->regs.c2CTL |= C2PIXCLKSEL_CRISTAL;
+ else
+ mcrtc2->regs.c2CTL |= C2PIXCLKSEL_VDOCLK;
+
+ /*
+ * High priority request level.
+ * According to G400 specs these values should
+ * be fixed when CRTC2 is in YUV mode.
+ */
+ /* c2hiprilvl */
+ mcrtc2->regs.c2CTL |= 2 << 4;
+ /* c2maxhipri */
+ mcrtc2->regs.c2CTL |= 1 << 8;
+
+ switch (surface->config.format) {
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ mcrtc2->regs.c2DATACTL |= C2DITHEN | C2YFILTEN | C2CBCRFILTEN;
+ break;
+ default:
+ break;
+ }
+
+ if (dfb_config->matrox_tv_std != DSETV_PAL)
+ mcrtc2->regs.c2DATACTL |= C2NTSCEN;
+
+ /* pixel format settings */
+ switch (surface->config.format) {
+ case DSPF_I420:
+ case DSPF_YV12:
+ mcrtc2->regs.c2CTL |= C2DEPTH_YCBCR420;
+ break;
+
+ case DSPF_UYVY:
+ mcrtc2->regs.c2DATACTL |= C2UYVYFMT;
+ /* fall through */
+
+ case DSPF_YUY2:
+ mcrtc2->regs.c2CTL |= C2DEPTH_YCBCR422;
+ break;
+
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ mcrtc2->regs.c2CTL |= C2DEPTH_15BPP;
+ break;
+
+ case DSPF_RGB16:
+ mcrtc2->regs.c2CTL |= C2DEPTH_16BPP;
+ break;
+
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ mcrtc2->regs.c2CTL |= C2DEPTH_32BPP;
+ break;
+
+ default:
+ D_BUG( "unexpected pixelformat" );
+ return;
+ }
+
+ if (!(surface->config.caps & DSCAPS_INTERLACED))
+ mcrtc2->regs.c2CTL |= C2VCBCRSINGLE;
+
+ mcrtc2->regs.c2OFFSET = lock->pitch;
+ if (!(surface->config.caps & DSCAPS_SEPARATED))
+ mcrtc2->regs.c2OFFSET *= 2;
+
+ {
+ int hdisplay, htotal, vdisplay, vtotal;
+
+ if (dfb_config->matrox_tv_std != DSETV_PAL) {
+ hdisplay = 720;
+ htotal = 858;
+ vdisplay = 480 / 2;
+ vtotal = 525 / 2;
+ } else {
+ hdisplay = 720;
+ htotal = 864;
+ vdisplay = 576 / 2;
+ vtotal = 625 / 2;
+ }
+
+ mcrtc2->regs.c2HPARAM = ((hdisplay - 8) << 16) | (htotal - 8);
+ mcrtc2->regs.c2VPARAM = ((vdisplay - 1) << 16) | (vtotal - 1);
+
+ mcrtc2->regs.c2MISC = 0;
+ /* c2vlinecomp */
+ mcrtc2->regs.c2MISC |= (vdisplay + 1) << 16;
+ }
+
+ /* c2bpp15halpha */
+ mcrtc2->regs.c2DATACTL |= config->alpha_ramp[3] << 8;
+
+ /* c2bpp15lalpha */
+ mcrtc2->regs.c2DATACTL |= config->alpha_ramp[0] << 16;
+}
+
+static void crtc2_calc_buffer( MatroxDriverData *mdrv,
+ MatroxCrtc2LayerData *mcrtc2,
+ CoreSurface *surface,
+ CoreSurfaceBufferLock *lock )
+{
+ unsigned int field_offset = lock->pitch;
+
+ if (surface->config.caps & DSCAPS_SEPARATED)
+ field_offset *= surface->config.size.h / 2;
+
+ mcrtc2->regs.c2STARTADD1 = lock->offset;
+ mcrtc2->regs.c2STARTADD0 = mcrtc2->regs.c2STARTADD1 + field_offset;
+
+ if (surface->config.caps & DSCAPS_INTERLACED)
+ field_offset = lock->pitch / 2;
+ else
+ field_offset = 0;
+
+ if (surface->config.caps & DSCAPS_SEPARATED)
+ field_offset *= surface->config.size.h / 4;
+
+ switch (surface->config.format) {
+ case DSPF_I420:
+ mcrtc2->regs.c2PL2STARTADD1 = mcrtc2->regs.c2STARTADD1 + surface->config.size.h * lock->pitch;
+ mcrtc2->regs.c2PL2STARTADD0 = mcrtc2->regs.c2PL2STARTADD1 + field_offset;
+
+ mcrtc2->regs.c2PL3STARTADD1 = mcrtc2->regs.c2PL2STARTADD1 + surface->config.size.h/2 * lock->pitch/2;
+ mcrtc2->regs.c2PL3STARTADD0 = mcrtc2->regs.c2PL3STARTADD1 + field_offset;
+ break;
+ case DSPF_YV12:
+ mcrtc2->regs.c2PL3STARTADD1 = mcrtc2->regs.c2STARTADD1 + surface->config.size.h * lock->pitch;
+ mcrtc2->regs.c2PL3STARTADD0 = mcrtc2->regs.c2PL3STARTADD1 + field_offset;
+
+ mcrtc2->regs.c2PL2STARTADD1 = mcrtc2->regs.c2PL3STARTADD1 + surface->config.size.h/2 * lock->pitch/2;
+ mcrtc2->regs.c2PL2STARTADD0 = mcrtc2->regs.c2PL2STARTADD1 + field_offset;
+ break;
+ default:
+ break;
+ }
+}
+
+static void crtc2_set_buffer( MatroxDriverData *mdrv,
+ MatroxCrtc2LayerData *mcrtc2 )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mga_out32( mmio, mcrtc2->regs.c2STARTADD0, C2STARTADD0 );
+ mga_out32( mmio, mcrtc2->regs.c2STARTADD1, C2STARTADD1 );
+ mga_out32( mmio, mcrtc2->regs.c2PL2STARTADD0, C2PL2STARTADD0 );
+ mga_out32( mmio, mcrtc2->regs.c2PL2STARTADD1, C2PL2STARTADD1 );
+ mga_out32( mmio, mcrtc2->regs.c2PL3STARTADD0, C2PL3STARTADD0 );
+ mga_out32( mmio, mcrtc2->regs.c2PL3STARTADD1, C2PL3STARTADD1 );
+}
+
+static void
+crtc2OnOff( MatroxDriverData *mdrv,
+ MatroxCrtc2LayerData *mcrtc2,
+ int on )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ if (on)
+ mcrtc2->regs.c2CTL |= C2EN;
+ else
+ mcrtc2->regs.c2CTL &= ~C2EN;
+ mga_out32( mmio, mcrtc2->regs.c2CTL, C2CTL );
+
+ if (on)
+ mcrtc2->regs.c2CTL &= ~C2PIXCLKDIS;
+ else
+ mcrtc2->regs.c2CTL |= C2PIXCLKDIS;
+ mga_out32( mmio, mcrtc2->regs.c2CTL, C2CTL );
+
+ if (!on) {
+ mcrtc2->regs.c2CTL &= ~C2INTERLACE;
+ mga_out32( mmio, mcrtc2->regs.c2CTL, C2CTL );
+ }
+}
+
+static void crtc2_set_mafc( MatroxDriverData *mdrv,
+ int on )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ u8 val;
+
+ val = mga_in_dac( mmio, XMISCCTRL );
+ if (on) {
+ val &= ~(MFCSEL_MASK | VDOUTSEL_MASK);
+ val |= MFCSEL_MAFC | VDOUTSEL_CRTC2656;
+ } else {
+ val &= ~MFCSEL_MASK;
+ val |= MFCSEL_DIS;
+ }
+ mga_out_dac( mmio, XMISCCTRL, val );
+}
+
+static DFBResult
+crtc2_disable_output( MatroxDriverData *mdrv,
+ MatroxCrtc2LayerData *mcrtc2 )
+{
+ MatroxDeviceData *mdev = mdrv->device_data;
+ MatroxMavenData *mav = &mcrtc2->mav;
+ DFBResult res;
+
+ if ((res = maven_open( mav, mdrv )) != DFB_OK)
+ return res;
+
+ maven_disable( mav, mdrv );
+ if (!mdev->g450_matrox)
+ crtc2_set_mafc( mdrv, 0 );
+ crtc2OnOff( mdrv, mcrtc2, 0 );
+
+ maven_close( mav, mdrv );
+
+ if (mdev->g450_matrox) {
+ volatile u8 *mmio = mdrv->mmio_base;
+ u8 val;
+
+ /* Set Rset to 0.7 V */
+ val = mga_in_dac( mmio, XGENIOCTRL );
+ val &= ~0x40;
+ mga_out_dac( mmio, XGENIOCTRL, val );
+ val = mga_in_dac( mmio, XGENIODATA );
+ val &= ~0x40;
+ mga_out_dac( mmio, XGENIODATA, val );
+
+ val = mga_in_dac( mmio, XPWRCTRL );
+ val &= ~(DAC2PDN | CFIFOPDN);
+ mga_out_dac( mmio, XPWRCTRL, val );
+
+ val = mga_in_dac( mmio, XDISPCTRL );
+ val &= ~DAC2OUTSEL_MASK;
+ val |= DAC2OUTSEL_DIS;
+ mga_out_dac( mmio, XDISPCTRL, val );
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+crtc2_enable_output( MatroxDriverData *mdrv,
+ MatroxCrtc2LayerData *mcrtc2 )
+{
+ MatroxDeviceData *mdev = mdrv->device_data;
+ MatroxMavenData *mav = &mcrtc2->mav;
+ volatile u8 *mmio = mdrv->mmio_base;
+ DFBResult res;
+
+ if ((res = maven_open( mav, mdrv )) != DFB_OK)
+ return res;
+
+ if (mdev->g450_matrox) {
+ volatile u8 *mmio = mdrv->mmio_base;
+ u8 val;
+
+ /* Set Rset to 1.0 V */
+ val = mga_in_dac( mmio, XGENIOCTRL );
+ val |= 0x40;
+ mga_out_dac( mmio, XGENIOCTRL, val );
+ val = mga_in_dac( mmio, XGENIODATA );
+ val &= ~0x40;
+ mga_out_dac( mmio, XGENIODATA, val );
+
+ val = mga_in_dac( mmio, XPWRCTRL );
+ val |= DAC2PDN | CFIFOPDN;
+ mga_out_dac( mmio, XPWRCTRL, val );
+
+ val = mga_in_dac( mmio, XDISPCTRL );
+ val &= ~DAC2OUTSEL_MASK;
+ val |= DAC2OUTSEL_TVE;
+ mga_out_dac( mmio, XDISPCTRL, val );
+
+ if (dfb_config->matrox_cable == 1) {
+ val = mga_in_dac( mmio, XSYNCCTRL );
+ val &= ~(DAC2HSOFF | DAC2VSOFF | DAC2HSPOL | DAC2VSPOL);
+ mga_out_dac( mmio, XSYNCCTRL, val );
+ }
+ }
+
+ maven_disable( mav, mdrv );
+ if (!mdev->g450_matrox)
+ crtc2_set_mafc( mdrv, 0 );
+ crtc2OnOff( mdrv, mcrtc2, 0 );
+
+ crtc2_set_regs( mdrv, mcrtc2 );
+ crtc2_set_buffer( mdrv, mcrtc2 );
+
+ if (!mdev->g450_matrox)
+ crtc2_set_mafc( mdrv, 1 );
+ crtc2OnOff( mdrv, mcrtc2, 1 );
+
+ maven_set_regs( mav, mdrv, &mcrtc2->config, &mcrtc2->adj );
+
+ mcrtc2->regs.c2CTL |= C2INTERLACE;
+ if (mdev->g450_matrox)
+ mcrtc2->regs.c2CTL |= 0x1000; /* Undocumented bit */
+ while ((mga_in32( mmio, C2VCOUNT ) & 0x00000FFF) != 1)
+ ;
+ while ((mga_in32( mmio, C2VCOUNT ) & 0x00000FFF) != 0)
+ ;
+ mga_out32( mmio, mcrtc2->regs.c2CTL, C2CTL );
+
+ maven_enable( mav, mdrv );
+
+ if (!mdev->g450_matrox) {
+ while ((mga_in32( mmio, C2VCOUNT ) & 0x00000FFF) != 1)
+ ;
+ while ((mga_in32( mmio, C2VCOUNT ) & 0x00000FFF) != 0)
+ ;
+ maven_sync( mav, mdrv );
+ }
+
+ maven_close( mav, mdrv );
+
+ return DFB_OK;
+}
diff --git a/Source/DirectFB/gfxdrivers/matrox/matrox_maven.c b/Source/DirectFB/gfxdrivers/matrox/matrox_maven.c
new file mode 100755
index 0000000..e263864
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/matrox_maven.c
@@ -0,0 +1,785 @@
+/*
+ (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
+
+ This code originally comes from matroxfb.
+ Relicensed under the LGPL with the authors permission.
+ Adapted for CRTC2 ITU-R 656 mode by Ville Syrjala <syrjala@sci.fi>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <dirent.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+
+#include <directfb.h>
+
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <misc/conf.h>
+
+#include "matrox.h"
+#include "regs.h"
+#include "mmio.h"
+#include "matrox_maven.h"
+
+#define SYS_CLASS_I2C_DEV "/sys/class/i2c-dev"
+
+static void
+maven_write_byte( MatroxMavenData *mav,
+ MatroxDriverData *mdrv,
+ u8 reg,
+ u8 val )
+{
+ MatroxDeviceData *mdev = mdrv->device_data;
+
+ if (mdev->g450_matrox) {
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mga_out_dac( mmio, 0x87, reg );
+ mga_out_dac( mmio, 0x88, val );
+ } else {
+ union i2c_smbus_data data;
+ struct i2c_smbus_ioctl_data args;
+
+ data.byte = val;
+
+ args.read_write = I2C_SMBUS_WRITE;
+ args.command = reg;
+ args.size = I2C_SMBUS_BYTE_DATA;
+ args.data = &data;
+
+ ioctl( mdrv->maven_fd, I2C_SMBUS, &args );
+ }
+}
+
+static void
+maven_write_word( MatroxMavenData *mav,
+ MatroxDriverData *mdrv,
+ u8 reg,
+ u16 val )
+{
+ MatroxDeviceData *mdev = mdrv->device_data;
+
+ if (mdev->g450_matrox) {
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mga_out_dac( mmio, 0x87, reg );
+ mga_out_dac( mmio, 0x88, val );
+ mga_out_dac( mmio, 0x87, reg + 1 );
+ mga_out_dac( mmio, 0x88, val >> 8 );
+ } else {
+ union i2c_smbus_data data;
+ struct i2c_smbus_ioctl_data args;
+
+ data.word = val;
+
+ args.read_write = I2C_SMBUS_WRITE;
+ args.command = reg;
+ args.size = I2C_SMBUS_WORD_DATA;
+ args.data = &data;
+
+ ioctl( mdrv->maven_fd, I2C_SMBUS, &args );
+ }
+}
+
+#if 0
+/* i2c_smbus_read_byte_data() doesn't work with maven. */
+static int
+i2c_read_byte( int fd, u8 addr, u8 reg )
+{
+ int ret;
+ u8 val;
+ struct i2c_msg msgs[] = {
+ { addr, I2C_M_REV_DIR_ADDR, sizeof(reg), &reg },
+ { addr, I2C_M_RD | I2C_M_NOSTART, sizeof(val), &val }
+ };
+ struct i2c_rdwr_ioctl_data data = {
+ msgs, 2
+ };
+
+ ret = ioctl( fd, I2C_RDWR, &data );
+ if (ret < 0)
+ return ret;
+
+ return val;
+}
+#endif
+
+void
+maven_disable( MatroxMavenData *mav,
+ MatroxDriverData *mdrv )
+{
+ MatroxDeviceData *mdev = mdrv->device_data;
+
+ maven_write_byte( mav, mdrv, 0x3E, 0x01 );
+
+ if (mdev->g450_matrox) {
+ maven_write_byte( mav, mdrv, 0x80, 0x00 );
+ return;
+ }
+
+ maven_write_byte( mav, mdrv, 0x82, 0x80 );
+ maven_write_byte( mav, mdrv, 0x8C, 0x00 );
+ maven_write_byte( mav, mdrv, 0x94, 0xA2 );
+ maven_write_word( mav, mdrv, 0x8E, 0x1EFF );
+ maven_write_byte( mav, mdrv, 0xC6, 0x01 );
+}
+
+void
+maven_enable( MatroxMavenData *mav,
+ MatroxDriverData *mdrv )
+{
+ MatroxDeviceData *mdev = mdrv->device_data;
+ bool ntsc = dfb_config->matrox_tv_std != DSETV_PAL;
+
+ if (mdev->g450_matrox) {
+ if (dfb_config->matrox_cable == 1)
+ /* SCART RGB */
+ maven_write_byte( mav, mdrv, 0x80, ntsc ? 0x43 : 0x41 );
+ else
+ /* Composite / S-Video */
+ maven_write_byte( mav, mdrv, 0x80, ntsc ? 0x03 : 0x01 );
+ }
+ else
+ maven_write_byte( mav, mdrv, 0x82, 0x20 );
+
+ maven_write_byte( mav, mdrv, 0x3E, 0x00 );
+}
+
+void
+maven_sync( MatroxMavenData *mav,
+ MatroxDriverData *mdrv )
+{
+ MatroxDeviceData *mdev = mdrv->device_data;
+
+ if (mdev->g450_matrox)
+ return;
+
+ maven_write_byte( mav, mdrv, 0xD4, 0x01 );
+ maven_write_byte( mav, mdrv, 0xD4, 0x00 );
+}
+
+#define LR(x) maven_write_byte( mav, mdrv, (x), mav->regs[(x)] )
+#define LRP(x) maven_write_word( mav, mdrv, (x), mav->regs[(x)] | (mav->regs[(x)+1] << 8) )
+
+void
+maven_set_regs( MatroxMavenData *mav,
+ MatroxDriverData *mdrv,
+ CoreLayerRegionConfig *config,
+ DFBColorAdjustment *adj )
+{
+ MatroxDeviceData *mdev = mdrv->device_data;
+ bool ntsc = dfb_config->matrox_tv_std != DSETV_PAL;
+
+ LR(0x00);
+ LR(0x01);
+ LR(0x02);
+ LR(0x03);
+ LR(0x04);
+ LR(0x2C);
+ LR(0x08);
+ LR(0x0A);
+ LR(0x09);
+ LR(0x29);
+ LRP(0x31);
+ LRP(0x17);
+ LR(0x0B);
+ LR(0x0C);
+ LR(0x35);
+ LRP(0x10);
+ LRP(0x0E);
+ LRP(0x1E);
+ LR(0x20);
+ LR(0x22);
+ LR(0x25);
+ LR(0x34);
+
+ LR(0x33);
+ LR(0x19);
+ LR(0x12);
+ LR(0x3B);
+ LR(0x13);
+ LR(0x39);
+ LR(0x1D);
+ LR(0x3A);
+ LR(0x24);
+ LR(0x14);
+ LR(0x15);
+ LR(0x16);
+ LRP(0x2D);
+ LRP(0x2F);
+ LR(0x1A);
+ LR(0x1B);
+ LR(0x1C);
+ LR(0x23);
+ LR(0x26);
+ LR(0x28);
+ LR(0x27);
+ LR(0x21);
+ LRP(0x2A);
+ LR(0x35);
+ LRP(0x3C);
+ LR(0x37);
+ LR(0x38);
+
+ if (mdev->g450_matrox) {
+ maven_write_word( mav, mdrv, 0x82, ntsc ? 0x0014 : 0x0017 );
+ maven_write_word( mav, mdrv, 0x84, 0x0001 );
+ } else {
+ maven_write_byte( mav, mdrv, 0xB3, 0x01 );
+ maven_write_byte( mav, mdrv, 0x82, 0xA0 );
+ maven_write_byte( mav, mdrv, 0xD3, 0x01 );
+ maven_write_byte( mav, mdrv, 0x8C, 0x10 );
+ maven_write_byte( mav, mdrv, 0x94, 0xA2 );
+ maven_write_byte( mav, mdrv, 0x8D, 0x03 );
+ maven_write_byte( mav, mdrv, 0xB9, 0x78 );
+ maven_write_byte( mav, mdrv, 0xBF, 0x02 );
+
+ /*
+ * Deflicker: 0x00, 0xB1, 0xA2
+ * Doesn't work due to:
+ * - ITU-R BT.656 mode?
+ * - scaler is not used?
+ * - something else?
+ */
+ maven_write_byte( mav, mdrv, 0x93, 0x00 );
+ }
+
+ maven_set_saturation( mav, mdrv, adj->saturation >> 8 );
+ maven_set_hue( mav, mdrv, adj->hue >> 8 );
+ maven_set_bwlevel( mav, mdrv, adj->brightness >> 8,
+ adj->contrast >> 8 );
+
+ if (!mdev->g450_matrox) {
+ LR(0x83);
+ LR(0x84);
+ LR(0x85);
+ LR(0x86);
+ LR(0x87);
+ LR(0x88);
+ LR(0x89);
+ LR(0x8A);
+ LR(0x8B);
+
+ switch (dfb_config->matrox_cable) {
+ case 1:
+ /* SCART RGB */
+ maven_write_byte( mav, mdrv, 0xB0, 0x85 );
+ break;
+ case 2:
+ /* SCART Composite */
+ maven_write_byte( mav, mdrv, 0xB0, 0x81 );
+ break;
+ default:
+ /* Composite / S-Video */
+ maven_write_byte( mav, mdrv, 0xB0, 0x80 );
+ break;
+ }
+ }
+}
+
+void
+maven_set_hue( MatroxMavenData *mav,
+ MatroxDriverData *mdrv,
+ u8 hue )
+{
+ maven_write_byte( mav, mdrv, 0x25, hue );
+}
+
+void
+maven_set_saturation( MatroxMavenData *mav,
+ MatroxDriverData *mdrv,
+ u8 saturation )
+{
+ maven_write_byte( mav, mdrv, 0x20, saturation );
+ maven_write_byte( mav, mdrv, 0x22, saturation );
+}
+
+void
+maven_set_bwlevel( MatroxMavenData *mav,
+ MatroxDriverData *mdrv,
+ u8 brightness,
+ u8 contrast )
+{
+ MatroxDeviceData *mdev = mdrv->device_data;
+ int b, c, bl, wl, wlmax, blmin, range;
+ bool ntsc = dfb_config->matrox_tv_std == DSETV_NTSC;
+
+ if (mdev->g450_matrox) {
+ wlmax = ntsc ? 936 : 938;
+ blmin = ntsc ? 267 : 281;
+ } else {
+ wlmax = 786;
+ blmin = ntsc ? 242 : 255;
+ }
+ range = wlmax - blmin - 128;
+
+ b = brightness * range / 255 + blmin;
+ c = contrast * range / 2 / 255 + 64;
+
+ bl = MAX( b - c, blmin );
+ wl = MIN( b + c, wlmax );
+
+ blmin = ((blmin << 8) & 0x0300) | ((blmin >> 2) & 0x00FF);
+ bl = ((bl << 8) & 0x0300) | ((bl >> 2) & 0x00FF);
+ wl = ((wl << 8) & 0x0300) | ((wl >> 2) & 0x00FF);
+
+ maven_write_word( mav, mdrv, 0x10, blmin );
+ maven_write_word( mav, mdrv, 0x0E, bl );
+ maven_write_word( mav, mdrv, 0x1E, wl );
+}
+
+DFBResult
+maven_open( MatroxMavenData *mav,
+ MatroxDriverData *mdrv )
+{
+ MatroxDeviceData *mdev = mdrv->device_data;
+
+ if (mdev->g450_matrox)
+ return DFB_OK;
+
+ if (mdrv->maven_fd != -1)
+ D_BUG( "DirectFB/Matrox/Maven: Device already open!\n" );
+
+ if ((mdrv->maven_fd = open( mav->dev, O_RDWR )) < 0) {
+ D_PERROR( "DirectFB/Matrox/Maven: Error opening `%s'!\n",
+ mav->dev );
+ mdrv->maven_fd = -1;
+ return errno2result( errno );
+ }
+
+ if (ioctl( mdrv->maven_fd, I2C_SLAVE, mav->address ) < 0) {
+ D_PERROR( "DirectFB/Matrox/Maven: Error controlling `%s'!\n",
+ mav->dev );
+ close( mdrv->maven_fd );
+ mdrv->maven_fd = -1;
+ return errno2result( errno );
+ }
+
+ return DFB_OK;
+}
+
+void
+maven_close( MatroxMavenData *mav,
+ MatroxDriverData *mdrv )
+{
+ MatroxDeviceData *mdev = mdrv->device_data;
+
+ if (mdev->g450_matrox)
+ return;
+
+ if (mdrv->maven_fd == -1)
+ D_BUG( "DirectFB/Matrox/Maven: Device not open!\n" );
+
+ close( mdrv->maven_fd );
+ mdrv->maven_fd = -1;
+}
+
+DFBResult maven_init( MatroxMavenData *mav,
+ MatroxDriverData *mdrv )
+{
+ MatroxDeviceData *mdev = mdrv->device_data;
+ char line[512];
+ int fd;
+ FILE *file;
+ bool found = false;
+ DIR *dir;
+
+ /* Locate G400 maven /dev/i2c file */
+
+ /* Try sysfs */
+ if (!mdev->g450_matrox && (dir = opendir( SYS_CLASS_I2C_DEV )) != NULL) {
+ char path[PATH_MAX];
+ struct dirent *ent;
+
+ while ((ent = readdir( dir )) != NULL) {
+ FILE *fp;
+
+ if (!strcmp( ent->d_name, "." ))
+ continue;
+ if (!strcmp( ent->d_name, ".." ))
+ continue;
+
+ snprintf( path, sizeof(path), "%s/%s/name", SYS_CLASS_I2C_DEV, ent->d_name );
+
+ fp = fopen( path, "r" );
+ if (!fp) {
+ D_PERROR( "DirectFB/Matrox/Maven: Error opening `%s'!\n", path );
+ continue;
+ }
+
+ memset( line, 0, 6 );
+
+ fread( line, 1, 5, fp );
+ if (ferror( fp )) {
+ D_PERROR( "DirectFB/Matrox/Maven: Error reading `%s'!\n", path );
+ fclose( fp );
+ continue;
+ }
+
+ fclose( fp );
+
+ if (strcmp( line, "MAVEN" ))
+ continue;
+
+ snprintf( mav->dev, sizeof(mav->dev), "/dev/%s", ent->d_name );
+ found = true;
+ break;
+ }
+ if (!ent && errno)
+ D_PERROR( "DirectFB/Matrox/Maven: Error reading `%s'!\n", SYS_CLASS_I2C_DEV );
+
+ closedir( dir );
+ }
+
+ /* Try /proc/bus/i2c */
+ if (!mdev->g450_matrox && !found) {
+ file = fopen( "/proc/bus/i2c", "r" );
+ if (!file) {
+ D_PERROR( "DirectFB/Matrox/Maven: "
+ "Error opening `/proc/bus/i2c'!\n" );
+ return errno2result( errno );
+ }
+ while (fgets( line, 512, file )) {
+ if (strstr( line, "MAVEN" )) {
+ char *p = line;
+ while (!isspace( *p ))
+ p++;
+ *p = '\0';
+ direct_snputs( mav->dev, "/dev/", 6 );
+ strncat( mav->dev, line, 250 );
+ found = true;
+ break;
+ }
+ }
+ fclose( file );
+ }
+
+ if (!mdev->g450_matrox) {
+ if (!found) {
+ D_ERROR( "DirectFB/Matrox/Maven: "
+ "Can't find MAVEN i2c device file!\n" );
+ return DFB_UNSUPPORTED;
+ }
+
+ /* Try to use it */
+ if ((fd = open( mav->dev, O_RDWR )) < 0) {
+ D_PERROR( "DirectFB/Matrox/Maven: Error opening `%s'!\n",
+ mav->dev );
+ return errno2result( errno );
+ }
+
+#if 0
+ /* FIXME: This fails for some people */
+ /* Check if maven is at address 0x1B (DH board) or 0x1A (DH add-on) */
+ if (i2c_read_byte( fd, 0x1B, 0xB2 ) < 0) {
+ if (i2c_read_byte( fd, 0x1A, 0xB2 ) < 0) {
+ D_ERROR( "DirectFB/Matrox/Maven: Error reading from maven chip!\n" );
+ close( fd );
+ return errno2result( errno );
+ } else
+ mav->address = 0x1A;
+ } else
+ mav->address = 0x1B;
+#else
+ mav->address = 0x1B;
+#endif
+
+ close( fd );
+ }
+
+ /* Maven registers */
+ {
+ static const u8 ntscregs[2][0x40] = {
+ /* G400 */
+ {
+ 0x21, 0xF0, 0x7C, 0x1F, /* 00-03 */
+ 0x00, /* 04 */
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x7E, /* 08 */
+ 0x43, /* 09 */
+ 0x7E, /* 0A */
+ 0x3D, /* 0B */
+ 0x00, /* 0C */
+ 0x00,
+ 0x46, 0x03, /* 0E-0F */
+ 0x3C, 0x02, /* 10-11 */
+ 0x17, /* 12 */
+ 0x21, /* 13 */
+ 0x1B, /* 14 */
+ 0x1B, /* 15 */
+ 0x24, /* 16 */
+ 0x83, 0x01, /* 17-18 */
+ 0x00, /* 19 */
+ 0x0F, /* 1A */
+ 0x0F, /* 1B */
+ 0x60, /* 1C */
+ 0x05, /* 1D */
+ 0xC4, 0x02, /* 1E-1F */
+ 0x8E, /* 20 */
+ 0x04, /* 21 */
+ 0x8E, /* 22 */
+ 0x01, /* 23 */
+ 0x02, /* 24 */
+ 0x00, /* 25 */
+ 0x0A, /* 26 */
+ 0x05, /* 27 */
+ 0x00, /* 28 */
+ 0x10, /* 29 */
+ 0xFF, 0x03, /* 2A-2B */
+ 0x18, /* 2C */
+ 0x0F, 0x78, /* 2D-2E */
+ 0x00, 0x00, /* 2F-30 */
+ 0xB4, 0x00, /* 31-32 */
+ 0x14, /* 33 */
+ 0x02, /* 34 */
+ 0x1C, /* 35 */
+ 0x00,
+ 0xA3, /* 37 */
+ 0xC8, /* 38 */
+ 0x15, /* 39 */
+ 0x05, /* 3A */
+ 0x15, /* 3B */
+ 0x3C, 0x00, /* 3C-3D */
+ 0x00, /* 3E */
+ 0x00
+ },
+ /* G450 / G550 */
+ {
+ 0x21, 0xF0, 0x7C, 0x1F, /* 00-03 */
+ 0x00, /* 04 */
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x7E, /* 08 */
+ 0x44, /* 09 */
+ 0x76, /* 0A */
+ 0x49, /* 0B */
+ 0x00, /* 0C */
+ 0x00,
+ 0x4E, 0x03, /* 0E-0F */
+ 0x42, 0x03, /* 10-11 */
+ 0x17, /* 12 */
+ 0x21, /* 13 */
+ 0x1B, /* 14 */
+ 0x1B, /* 15 */
+ 0x24, /* 16 */
+ 0x83, 0x01, /* 17-18 */
+ 0x00, /* 19 */
+ 0x0F, /* 1A */
+ 0x0F, /* 1B */
+ 0x60, /* 1C */
+ 0x05, /* 1D */
+ 0xEA, 0x00, /* 1E-1F */
+ 0xAE, /* 20 */
+ 0x04, /* 21 */
+ 0xAE, /* 22 */
+ 0x01, /* 23 */
+ 0x02, /* 24 */
+ 0x00, /* 25 */
+ 0x0A, /* 26 */
+ 0x05, /* 27 */
+ 0x00, /* 28 */
+ 0x11, /* 29 */
+ 0xFF, 0x03, /* 2A-2B */
+ 0x20, /* 2C */
+ 0x0F, 0x78, /* 2D-2E */
+ 0x00, 0x00, /* 2F-30 */
+ 0xB4, 0x00, /* 31-32 */
+ 0x14, /* 33 */
+ 0x02, /* 34 */
+ 0x00, /* 35 */
+ 0x00,
+ 0xBD, /* 37 */
+ 0xDA, /* 38 */
+ 0x15, /* 39 */
+ 0x05, /* 3A */
+ 0x15, /* 3B */
+ 0x42, 0x03, /* 3C-3D */
+ 0x00, /* 3E */
+ 0x00
+ }
+ };
+ static const u8 palregs[2][0x40] = {
+ /* G400 */
+ {
+ 0x2A, 0x09, 0x8A, 0xCB, /* 00-03 */
+ 0x00, /* 04 */
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x7E, /* 08 */
+ 0x3C, /* 09 */
+ 0x82, /* 0A */
+ 0x2E, /* 0B */
+ 0x21, /* 0C */
+ 0x00,
+ 0x3F, 0x03, /* 0E-0F */
+ 0x3F, 0x03, /* 10-11 */
+ 0x1A, /* 12 */
+ 0x2A, /* 13 */
+ 0x1C, /* 14 */
+ 0x3D, /* 15 */
+ 0x14, /* 16 */
+ 0x9C, 0x01, /* 17-18 */
+ 0x00, /* 19 */
+ 0xFE, /* 1A */
+ 0x7E, /* 1B */
+ 0x60, /* 1C */
+ 0x05, /* 1D */
+ 0xC4, 0x01, /* 1E-1F */
+ 0x95, /* 20 */
+ 0x07, /* 21 */
+ 0x95, /* 22 */
+ 0x00, /* 23 */
+ 0x00, /* 24 */
+ 0x00, /* 25 */
+ 0x08, /* 26 */
+ 0x04, /* 27 */
+ 0x00, /* 28 */
+ 0x1A, /* 29 */
+ 0x55, 0x01, /* 2A-2B */
+ 0x20, /* 2C */
+ 0x07, 0x7E, /* 2D-2E */
+ 0x02, 0x54, /* 2F-30 */
+ 0xB4, 0x00, /* 31-32 */
+ 0x14, /* 33 */
+ 0x49, /* 34 */
+ 0x1D, /* 35 */
+ 0x00,
+ 0xA3, /* 37 */
+ 0xC8, /* 38 */
+ 0x22, /* 39 */
+ 0x02, /* 3A */
+ 0x22, /* 3B */
+ 0x3F, 0x03, /* 3C-3D */
+ 0x00, /* 3E */
+ 0x00,
+ },
+ /* G450 / G550 */
+ {
+ 0x2A, 0x09, 0x8A, 0xCB, /* 00-03 */
+ 0x00, /* 04 */
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x7E, /* 08 */
+ 0x3A, /* 09 */
+ 0x8A, /* 0A */
+ 0x38, /* 0B */
+ 0x28, /* 0C */
+ 0x00,
+ 0x46, 0x01, /* 0E-0F */
+ 0x46, 0x01, /* 10-11 */
+ 0x1A, /* 12 */
+ 0x2A, /* 13 */
+ 0x1C, /* 14 */
+ 0x3D, /* 15 */
+ 0x14, /* 16 */
+ 0x9C, 0x01, /* 17-18 */
+ 0x00, /* 19 */
+ 0xFE, /* 1A */
+ 0x7E, /* 1B */
+ 0x60, /* 1C */
+ 0x05, /* 1D */
+ 0xEA, 0x00, /* 1E-1F */
+ 0xBB, /* 20 */
+ 0x07, /* 21 */
+ 0xBB, /* 22 */
+ 0x00, /* 23 */
+ 0x00, /* 24 */
+ 0x00, /* 25 */
+ 0x08, /* 26 */
+ 0x04, /* 27 */
+ 0x00, /* 28 */
+ 0x1A, /* 29 */
+ 0x55, 0x01, /* 2A-2B */
+ 0x18, /* 2C */
+ 0x07, 0x7E, /* 2D-2E */
+ 0x02, 0x54, /* 2F-30 */
+ 0xB4, 0x00, /* 31-32 */
+ 0x16, /* 33 */
+ 0x49, /* 34 */
+ 0x00, /* 35 */
+ 0x00,
+ 0xB9, /* 37 */
+ 0xDD, /* 38 */
+ 0x22, /* 39 */
+ 0x02, /* 3A */
+ 0x22, /* 3B */
+ 0x46, 0x00, /* 3C-3D */
+ 0x00, /* 3E */
+ 0x00,
+ }
+ };
+
+ if (dfb_config->matrox_tv_std != DSETV_PAL)
+ direct_memcpy( mav->regs, ntscregs[mdev->g450_matrox], 64 );
+ else
+ direct_memcpy( mav->regs, palregs[mdev->g450_matrox], 64 );
+
+ if (dfb_config->matrox_tv_std == DSETV_PAL_60) {
+ mav->regs[0x00] = palregs[mdev->g450_matrox][0x00];
+ mav->regs[0x01] = palregs[mdev->g450_matrox][0x01];
+ mav->regs[0x02] = palregs[mdev->g450_matrox][0x02];
+ mav->regs[0x03] = palregs[mdev->g450_matrox][0x03];
+ mav->regs[0x0B] = palregs[mdev->g450_matrox][0x0B];
+ mav->regs[0x0C] = palregs[mdev->g450_matrox][0x0C];
+ mav->regs[0x0E] = palregs[mdev->g450_matrox][0x0E];
+ mav->regs[0x0F] = palregs[mdev->g450_matrox][0x0F];
+ mav->regs[0x10] = palregs[mdev->g450_matrox][0x10];
+ mav->regs[0x11] = palregs[mdev->g450_matrox][0x11];
+ mav->regs[0x1E] = palregs[mdev->g450_matrox][0x1E];
+ mav->regs[0x1F] = palregs[mdev->g450_matrox][0x1F];
+ mav->regs[0x20] = palregs[mdev->g450_matrox][0x20];
+ mav->regs[0x22] = palregs[mdev->g450_matrox][0x22];
+ mav->regs[0x25] = palregs[mdev->g450_matrox][0x25];
+ mav->regs[0x34] = palregs[mdev->g450_matrox][0x34];
+ }
+
+ if (!mdev->g450_matrox) {
+ /* gamma */
+ mav->regs[0x83] = 0x00;
+ mav->regs[0x84] = 0x00;
+ mav->regs[0x85] = 0x00;
+ mav->regs[0x86] = 0x1F;
+ mav->regs[0x87] = 0x10;
+ mav->regs[0x88] = 0x10;
+ mav->regs[0x89] = 0x10;
+ mav->regs[0x8A] = 0x64;
+ mav->regs[0x8B] = 0xC8;
+ }
+ }
+
+ return DFB_OK;
+}
diff --git a/Source/DirectFB/gfxdrivers/matrox/matrox_maven.h b/Source/DirectFB/gfxdrivers/matrox/matrox_maven.h
new file mode 100755
index 0000000..eeeb32d
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/matrox_maven.h
@@ -0,0 +1,64 @@
+/*
+ (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
+
+ This code originally comes from matroxfb.
+ Relicensed under the LGPL with the authors permission.
+ Adapted for CRTC2 ITU-R 656 mode by Ville Syrjala <syrjala@sci.fi>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __MATROX_MAVEN_H__
+#define __MATROX_MAVEN_H__
+
+typedef struct {
+ char dev[256];
+ u8 regs[256];
+ u8 address;
+} MatroxMavenData;
+
+DFBResult maven_init( MatroxMavenData *mav,
+ MatroxDriverData *mdrv );
+
+DFBResult maven_open( MatroxMavenData *mav,
+ MatroxDriverData *mdrv );
+void maven_close( MatroxMavenData *mav,
+ MatroxDriverData *mdrv );
+
+void maven_enable( MatroxMavenData *mav,
+ MatroxDriverData *mdrv );
+void maven_disable( MatroxMavenData *mav,
+ MatroxDriverData *mdrv );
+void maven_sync( MatroxMavenData *mav,
+ MatroxDriverData *mdrv );
+
+void maven_set_regs( MatroxMavenData *mav,
+ MatroxDriverData *mdrv,
+ CoreLayerRegionConfig *config,
+ DFBColorAdjustment *adj );
+
+void maven_set_hue( MatroxMavenData *mav,
+ MatroxDriverData *mdrv,
+ u8 hue );
+void maven_set_saturation( MatroxMavenData *mav,
+ MatroxDriverData *mdrv,
+ u8 saturation );
+void maven_set_bwlevel( MatroxMavenData *mav,
+ MatroxDriverData *mdrv,
+ u8 brightness,
+ u8 contrast );
+
+#endif
diff --git a/Source/DirectFB/gfxdrivers/matrox/matrox_screen_crtc2.c b/Source/DirectFB/gfxdrivers/matrox/matrox_screen_crtc2.c
new file mode 100755
index 0000000..f08a58f
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/matrox_screen_crtc2.c
@@ -0,0 +1,279 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <sys/ioctl.h>
+
+#include <fbdev/fbdev.h> /* FIXME: Needs to be included before dfb_types.h to work around a type clash with asm/types.h */
+
+#include <directfb.h>
+
+#include <direct/messages.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+#include <core/screens.h>
+#include <core/system.h>
+
+#include <fbdev/fbdev.h>
+
+#include <misc/conf.h>
+
+#include "regs.h"
+#include "mmio.h"
+#include "matrox.h"
+
+
+typedef struct {
+ DFBScreenPowerMode power_mode;
+} MatroxCrtc2ScreenData;
+
+static void crtc2_wait_vsync( MatroxDriverData *mdrv );
+
+/**************************************************************************************************/
+
+static int
+crtc2ScreenDataSize( void )
+{
+ return sizeof(MatroxCrtc2ScreenData);
+}
+
+static DFBResult
+crtc2InitScreen( CoreScreen *screen,
+ CoreGraphicsDevice *device,
+ void *driver_data,
+ void *screen_data,
+ DFBScreenDescription *description )
+{
+ /* Set the screen capabilities. */
+ description->caps = DSCCAPS_VSYNC | DSCCAPS_ENCODERS | DSCCAPS_OUTPUTS;
+
+ /* Set the screen name. */
+ snprintf( description->name,
+ DFB_SCREEN_DESC_NAME_LENGTH, "Matrox CRTC2 Screen" );
+
+ /* Set number of encoders and outputs. */
+ description->encoders = 1;
+ description->outputs = 1;
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+crtc2InitEncoder( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int encoder,
+ DFBScreenEncoderDescription *description,
+ DFBScreenEncoderConfig *config )
+{
+ /* Set the encoder capabilities & type. */
+ description->caps = DSECAPS_TV_STANDARDS;
+ description->type = DSET_TV;
+
+ /* Set supported TV standards. */
+ description->tv_standards = DSETV_PAL | DSETV_NTSC | DSETV_PAL_60;
+
+ /* Set default configuration. */
+ config->flags = DSECONF_TV_STANDARD;
+ config->tv_standard = dfb_config->matrox_tv_std;
+
+ return DFB_OK;
+}
+
+static DFBResult
+crtc2InitOutput( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int output,
+ DFBScreenOutputDescription *description,
+ DFBScreenOutputConfig *config )
+{
+ /* Set the output capabilities. */
+ description->caps = DSOCAPS_CONNECTORS |
+ DSOCAPS_SIGNAL_SEL | DSOCAPS_CONNECTOR_SEL;
+
+ /* Set supported output connectors and signals. */
+ description->all_connectors = DSOC_CVBS | DSOC_YC | DSOC_SCART;
+ description->all_signals = DSOS_CVBS | DSOS_YC | DSOS_RGB;
+
+ /* Set default configuration. */
+ config->flags = DSOCONF_SIGNALS | DSOCONF_CONNECTORS;
+
+ switch (dfb_config->matrox_cable) {
+ case 1:
+ /* SCART RGB */
+ config->out_signals = DSOS_RGB;
+ config->out_connectors = DSOC_SCART;
+ break;
+ case 2:
+ /* SCART Composite */
+ config->out_signals = DSOS_CVBS;
+ config->out_connectors = DSOC_SCART;
+ break;
+ default:
+ /* Composite / S-Video */
+ config->out_signals = DSOS_CVBS | DSOS_YC;
+ config->out_connectors = DSOC_CVBS | DSOC_YC;
+ break;
+ }
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+crtc2SetPowerMode( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ DFBScreenPowerMode mode )
+{
+ MatroxCrtc2ScreenData *msc2 = (MatroxCrtc2ScreenData*) screen_data;
+
+ msc2->power_mode = mode;
+
+ return DFB_OK;
+}
+
+static DFBResult
+crtc2WaitVSync( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxCrtc2ScreenData *msc2 = (MatroxCrtc2ScreenData*) screen_data;
+
+ if (msc2->power_mode == DSPM_ON)
+ crtc2_wait_vsync( mdrv );
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+crtc2TestEncoderConfig( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int encoder,
+ const DFBScreenEncoderConfig *config,
+ DFBScreenEncoderConfigFlags *failed )
+{
+ D_UNIMPLEMENTED();
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+crtc2SetEncoderConfig( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int encoder,
+ const DFBScreenEncoderConfig *config )
+{
+// D_UNIMPLEMENTED();
+
+ return DFB_UNIMPLEMENTED;
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+crtc2TestOutputConfig( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int output,
+ const DFBScreenOutputConfig *config,
+ DFBScreenOutputConfigFlags *failed )
+{
+ D_UNIMPLEMENTED();
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+crtc2SetOutputConfig( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int output,
+ const DFBScreenOutputConfig *config )
+{
+// D_UNIMPLEMENTED();
+
+ return DFB_UNIMPLEMENTED;
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+crtc2GetScreenSize( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int *ret_width,
+ int *ret_height )
+{
+ *ret_width = 720;
+ *ret_height = (dfb_config->matrox_tv_std != DSETV_PAL) ? 480 : 576;
+
+ return DFB_OK;
+}
+
+ScreenFuncs matroxCrtc2ScreenFuncs = {
+ .ScreenDataSize = crtc2ScreenDataSize,
+ .InitScreen = crtc2InitScreen,
+ .InitEncoder = crtc2InitEncoder,
+ .InitOutput = crtc2InitOutput,
+ .SetPowerMode = crtc2SetPowerMode,
+ .WaitVSync = crtc2WaitVSync,
+ .TestEncoderConfig = crtc2TestEncoderConfig,
+ .SetEncoderConfig = crtc2SetEncoderConfig,
+ .TestOutputConfig = crtc2TestOutputConfig,
+ .SetOutputConfig = crtc2SetOutputConfig,
+ .GetScreenSize = crtc2GetScreenSize,
+};
+
+/**************************************************************************************************/
+
+static void crtc2_wait_vsync( MatroxDriverData *mdrv )
+{
+ int vdisplay = ((dfb_config->matrox_tv_std != DSETV_PAL) ? 480/2 : 576/2) + 1;
+
+#ifdef FBIO_WAITFORVSYNC
+ static const int one = 1;
+ FBDev *dfb_fbdev = dfb_system_data();
+ if (ioctl( dfb_fbdev->fd, FBIO_WAITFORVSYNC, &one ))
+#endif
+ while ((int)(mga_in32( mdrv->mmio_base, C2VCOUNT ) & 0x00000FFF) != vdisplay)
+ ;
+}
+
diff --git a/Source/DirectFB/gfxdrivers/matrox/matrox_spic.c b/Source/DirectFB/gfxdrivers/matrox/matrox_spic.c
new file mode 100755
index 0000000..cca8392
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/matrox_spic.c
@@ -0,0 +1,314 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <directfb.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+#include <core/layers.h>
+#include <core/palette.h>
+#include <core/surface.h>
+
+#include <gfx/convert.h>
+
+#include <misc/conf.h>
+
+#include "regs.h"
+#include "mmio.h"
+#include "matrox.h"
+
+typedef struct {
+ CoreLayerRegionConfig config;
+
+ /* Stored registers */
+ struct {
+ /* CRTC2 sub picture */
+ u32 c2DATACTL;
+
+ u32 c2SPICSTARTADD0;
+ u32 c2SPICSTARTADD1;
+ u32 c2SUBPICLUT;
+ } regs;
+} MatroxSpicLayerData;
+
+static void spic_calc_buffer( MatroxDriverData *mdrv,
+ MatroxSpicLayerData *mspic,
+ CoreSurface *surface,
+ CoreSurfaceBufferLock *lock );
+
+static void spic_set_buffer( MatroxDriverData *mdrv,
+ MatroxSpicLayerData *mspic );
+
+#define SPIC_SUPPORTED_OPTIONS (DLOP_ALPHACHANNEL | DLOP_OPACITY)
+
+/**********************/
+
+static int
+spicLayerDataSize( void )
+{
+ return sizeof(MatroxSpicLayerData);
+}
+
+static DFBResult
+spicInitLayer( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ DFBDisplayLayerDescription *description,
+ DFBDisplayLayerConfig *config,
+ DFBColorAdjustment *adjustment )
+{
+ /* set capabilities and type */
+ description->caps = DLCAPS_SURFACE | DLCAPS_ALPHACHANNEL | DLCAPS_OPACITY;
+ description->type = DLTF_GRAPHICS | DLTF_VIDEO | DLTF_STILL_PICTURE;
+
+ /* set name */
+ snprintf( description->name,
+ DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "Matrox CRTC2 Sub-Picture" );
+
+ /* fill out the default configuration */
+ config->flags = DLCONF_WIDTH | DLCONF_HEIGHT |
+ DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE |
+ DLCONF_OPTIONS | DLCONF_SURFACE_CAPS;
+
+ config->width = 720;
+ config->height = (dfb_config->matrox_tv_std != DSETV_PAL) ? 480 : 576;
+ config->pixelformat = DSPF_ALUT44;
+ config->buffermode = DLBM_FRONTONLY;
+ config->options = DLOP_NONE;
+ config->surface_caps = DSCAPS_INTERLACED;
+
+ return DFB_OK;
+}
+
+static DFBResult
+spicTestRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags *failed )
+{
+ CoreLayerRegionConfigFlags fail = 0;
+
+ if (config->options & ~SPIC_SUPPORTED_OPTIONS)
+ fail |= CLRCF_OPTIONS;
+
+ /* Can't have both at the same time */
+ if (config->options & DLOP_ALPHACHANNEL && config->options & DLOP_OPACITY)
+ fail |= CLRCF_OPTIONS;
+
+ switch (config->opacity) {
+ case 0x00:
+ case 0xFF:
+ break;
+ default:
+ if (!(config->options & DLOP_OPACITY))
+ fail |= CLRCF_OPACITY;
+ }
+
+ if (config->surface_caps & ~(DSCAPS_INTERLACED | DSCAPS_SEPARATED))
+ fail |= CLRCF_SURFACE_CAPS;
+
+ if (config->format != DSPF_ALUT44)
+ fail |= CLRCF_FORMAT;
+
+ if (config->width != 720)
+ fail |= CLRCF_WIDTH;
+
+ if (config->surface_caps & DSCAPS_INTERLACED) {
+ if (config->height != ((dfb_config->matrox_tv_std != DSETV_PAL) ? 480 : 576))
+ fail |= CLRCF_HEIGHT;
+ } else {
+ if (config->height != ((dfb_config->matrox_tv_std != DSETV_PAL) ? 240 : 288))
+ fail |= CLRCF_HEIGHT;
+ }
+
+ if (failed)
+ *failed = fail;
+
+ if (fail)
+ return DFB_UNSUPPORTED;
+
+ return DFB_OK;
+}
+
+static DFBResult
+spicAddRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config )
+{
+ return DFB_OK;
+}
+
+static DFBResult
+spicSetRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags updated,
+ CoreSurface *surface,
+ CorePalette *palette,
+ CoreSurfaceBufferLock *lock )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxSpicLayerData *mspic = (MatroxSpicLayerData*) layer_data;
+ MatroxDeviceData *mdev = mdrv->device_data;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ /* remember configuration */
+ mspic->config = *config;
+
+ if (updated & CLRCF_PALETTE) {
+ u8 y, cb, cr;
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ RGB_TO_YCBCR( palette->entries[i].r,
+ palette->entries[i].g,
+ palette->entries[i].b,
+ y, cb, cr );
+
+ mspic->regs.c2SUBPICLUT = (cr << 24) | (cb << 16) | (y << 8) | i;
+ mga_out32( mmio, mspic->regs.c2SUBPICLUT, C2SUBPICLUT );
+ }
+ }
+
+ if (updated & (CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_FORMAT | CLRCF_SURFACE_CAPS |
+ CLRCF_OPTIONS | CLRCF_OPACITY | CLRCF_SURFACE)) {
+ spic_calc_buffer( mdrv, mspic, surface, lock );
+ spic_set_buffer( mdrv, mspic );
+
+ mspic->regs.c2DATACTL = mga_in32( mmio, C2DATACTL );
+
+ if (surface->config.caps & DSCAPS_INTERLACED || mdev->crtc2_separated)
+ mspic->regs.c2DATACTL &= ~C2OFFSETDIVEN;
+ else
+ mspic->regs.c2DATACTL |= C2OFFSETDIVEN;
+
+ if (config->opacity)
+ mspic->regs.c2DATACTL |= C2SUBPICEN;
+ else
+ mspic->regs.c2DATACTL &= ~C2SUBPICEN;
+
+ if (config->options & DLOP_ALPHACHANNEL)
+ mspic->regs.c2DATACTL &= ~C2STATICKEYEN;
+ else
+ mspic->regs.c2DATACTL |= C2STATICKEYEN;
+
+ mspic->regs.c2DATACTL &= ~C2STATICKEY;
+ mspic->regs.c2DATACTL |= ((config->opacity + 1) << 20) & C2STATICKEY;
+
+ mga_out32( mmio, mspic->regs.c2DATACTL, C2DATACTL);
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+spicRemoveRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxSpicLayerData *mspic = (MatroxSpicLayerData*) layer_data;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mspic->regs.c2DATACTL = mga_in32( mmio, C2DATACTL );
+
+ mspic->regs.c2DATACTL &= ~C2SUBPICEN;
+
+ mga_out32( mmio, mspic->regs.c2DATACTL, C2DATACTL );
+
+ return DFB_OK;
+}
+
+static DFBResult
+spicFlipRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreSurface *surface,
+ DFBSurfaceFlipFlags flags,
+ CoreSurfaceBufferLock *lock )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxSpicLayerData *mspic = (MatroxSpicLayerData*) layer_data;
+
+ spic_calc_buffer( mdrv, mspic, surface, lock );
+ spic_set_buffer( mdrv, mspic );
+
+ dfb_surface_flip( surface, false );
+
+ return DFB_OK;
+}
+
+DisplayLayerFuncs matroxSpicFuncs = {
+ .LayerDataSize = spicLayerDataSize,
+ .InitLayer = spicInitLayer,
+
+ .TestRegion = spicTestRegion,
+ .AddRegion = spicAddRegion,
+ .SetRegion = spicSetRegion,
+ .RemoveRegion = spicRemoveRegion,
+ .FlipRegion = spicFlipRegion,
+};
+
+/* internal */
+
+static void spic_calc_buffer( MatroxDriverData *mdrv,
+ MatroxSpicLayerData *mspic,
+ CoreSurface *surface,
+ CoreSurfaceBufferLock *lock )
+{
+ unsigned int field_offset = lock->pitch;
+
+ mspic->regs.c2SPICSTARTADD1 = lock->offset;
+ mspic->regs.c2SPICSTARTADD0 = lock->offset;
+
+ if (surface->config.caps & DSCAPS_SEPARATED)
+ field_offset *= surface->config.size.h / 2;
+
+ if (surface->config.caps & DSCAPS_INTERLACED)
+ mspic->regs.c2SPICSTARTADD0 += field_offset;
+}
+
+static void spic_set_buffer( MatroxDriverData *mdrv,
+ MatroxSpicLayerData *mspic )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mga_out32( mmio, mspic->regs.c2SPICSTARTADD0, C2SPICSTARTADD0 );
+ mga_out32( mmio, mspic->regs.c2SPICSTARTADD1, C2SPICSTARTADD1 );
+}
diff --git a/Source/DirectFB/gfxdrivers/matrox/matrox_state.c b/Source/DirectFB/gfxdrivers/matrox/matrox_state.c
new file mode 100755
index 0000000..ceeffa5
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/matrox_state.c
@@ -0,0 +1,810 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/messages.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/state.h>
+#include <core/gfxcard.h>
+#include <core/surface.h>
+#include <core/palette.h>
+
+#include <gfx/convert.h>
+
+#include "regs.h"
+#include "mmio.h"
+#include "matrox.h"
+
+#include "matrox_state.h"
+
+#define MGA_KEYMASK(format) ((1 << DFB_COLOR_BITS_PER_PIXEL(format)) - 1)
+
+static void matrox_calc_offsets( MatroxDeviceData *mdev,
+ CoreSurface *surface,
+ CoreSurfaceBufferLock *lock,
+ bool unit_pixel,
+ int offset[2][3] )
+{
+ int bytes_per_pixel = DFB_BYTES_PER_PIXEL( surface->config.format );
+ int pitch;
+
+ if (unit_pixel) {
+ offset[0][0] = lock->offset / bytes_per_pixel;
+ pitch = lock->pitch / bytes_per_pixel;
+ } else {
+ offset[0][0] = mdev->fb.offset + lock->offset;
+ pitch = lock->pitch;
+ }
+
+ switch (surface->config.format) {
+ case DSPF_NV12:
+ case DSPF_NV21:
+ offset[0][1] = offset[0][0] + surface->config.size.h * pitch;
+ offset[0][2] = 0;
+ break;
+ case DSPF_I420:
+ offset[0][1] = offset[0][0] + surface->config.size.h * pitch;
+ offset[0][2] = offset[0][1] + surface->config.size.h/2 * pitch/2;
+ break;
+ case DSPF_YV12:
+ offset[0][2] = offset[0][0] + surface->config.size.h * pitch;
+ offset[0][1] = offset[0][2] + surface->config.size.h/2 * pitch/2;
+ break;
+ default:
+ offset[0][1] = 0;
+ offset[0][2] = 0;
+ }
+
+ D_ASSERT( offset[0][0] % 64 == 0 );
+ D_ASSERT( offset[0][1] % 64 == 0 );
+ D_ASSERT( offset[0][2] % 64 == 0 );
+
+ if (mdev->blit_fields || mdev->blit_deinterlace) {
+ if (surface->config.caps & DSCAPS_SEPARATED) {
+ offset[1][0] = offset[0][0] + surface->config.size.h/2 * pitch;
+ switch (surface->config.format) {
+ case DSPF_NV12:
+ case DSPF_NV21:
+ offset[1][1] = offset[0][1] + surface->config.size.h/4 * pitch;
+ offset[1][2] = 0;
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ offset[1][1] = offset[0][1] + surface->config.size.h/4 * pitch/2;
+ offset[1][2] = offset[0][2] + surface->config.size.h/4 * pitch/2;
+ break;
+ default:
+ offset[1][1] = 0;
+ offset[1][2] = 0;
+ }
+ } else {
+ offset[1][0] = offset[0][0] + pitch;
+ switch (surface->config.format) {
+ case DSPF_NV12:
+ case DSPF_NV21:
+ offset[1][1] = offset[0][1] + pitch;
+ offset[1][2] = 0;
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ offset[1][1] = offset[0][1] + pitch/2;
+ offset[1][2] = offset[0][2] + pitch/2;
+ break;
+ default:
+ offset[1][1] = 0;
+ offset[1][2] = 0;
+ }
+ }
+
+ D_ASSERT( offset[1][0] % 64 == 0 );
+ D_ASSERT( offset[1][1] % 64 == 0 );
+ D_ASSERT( offset[1][2] % 64 == 0 );
+ }
+}
+
+void matrox_validate_destination( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ CoreSurface *destination = state->destination;
+ CoreSurfaceBuffer *depth_buffer = NULL;//destination->depth_buffer;
+ int bytes_per_pixel = DFB_BYTES_PER_PIXEL( destination->config.format );
+
+ if (MGA_IS_VALID( m_destination ))
+ return;
+
+ mdev->dst_pitch = state->dst.pitch / bytes_per_pixel;
+
+ mdev->depth_buffer = depth_buffer != NULL;
+
+ if (destination->config.format == DSPF_YUY2 || destination->config.format == DSPF_UYVY)
+ mdev->dst_pitch /= 2;
+
+ if (mdev->blit_fields && !(destination->config.caps & DSCAPS_SEPARATED))
+ mdev->dst_pitch *= 2;
+
+ D_ASSERT( mdev->dst_pitch % 32 == 0 );
+
+ matrox_calc_offsets( mdev, destination, &state->dst, mdev->old_matrox, mdev->dst_offset );
+
+ mga_waitfifo( mdrv, mdev, depth_buffer ? 4 : 3 );
+
+ mga_out32( mmio, mdev->dst_offset[0][0], mdev->old_matrox ? YDSTORG : DSTORG );
+ mga_out32( mmio, mdev->dst_pitch, PITCH );
+
+#if 0
+ if (depth_buffer)
+ mga_out32( mmio, depth_buffer->video.offset, ZORG );
+#endif
+
+ switch (destination->config.format) {
+ case DSPF_A8:
+ case DSPF_ALUT44:
+ case DSPF_LUT8:
+ case DSPF_RGB332:
+ mga_out32( mmio, PW8, MACCESS );
+ break;
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ mga_out32( mmio, PW16 | DIT555, MACCESS );
+ break;
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ case DSPF_RGB16:
+ mga_out32( mmio, PW16, MACCESS );
+ break;
+ case DSPF_RGB24:
+ mga_out32( mmio, PW24, MACCESS );
+ break;
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ mga_out32( mmio, PW32, MACCESS );
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ case DSPF_NV12:
+ case DSPF_NV21:
+ mga_out32( mmio, PW8 | BYPASS332 | NODITHER, MACCESS );
+ break;
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ mga_out32( mmio, PW32 | NODITHER, MACCESS );
+ break;
+ default:
+ D_BUG( "unexpected pixelformat!" );
+ break;
+ }
+
+ MGA_VALIDATE( m_destination );
+}
+
+void matrox_set_clip( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ DFBRegion *clip )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mga_waitfifo( mdrv, mdev, 3 );
+
+ if (mdev->old_matrox) {
+ mga_out32( mmio, (mdev->dst_offset[0][0] +
+ mdev->dst_pitch * clip->y1) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_offset[0][0] +
+ mdev->dst_pitch * clip->y2) & 0xFFFFFF, YBOT );
+ }
+ else {
+ mga_out32( mmio, (mdev->dst_pitch * clip->y1) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_pitch * clip->y2) & 0xFFFFFF, YBOT );
+ }
+
+ mga_out32( mmio, ((clip->x2 & 0x0FFF) << 16) | (clip->x1 & 0x0FFF), CXBNDRY );
+}
+
+void matrox_validate_drawColor( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ DFBColor color = state->color;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ if (MGA_IS_VALID( m_drawColor ))
+ return;
+
+ if (state->drawingflags & DSDRAW_SRC_PREMULTIPLY) {
+ color.r = (color.r * (color.a + 1)) >> 8;
+ color.g = (color.g * (color.a + 1)) >> 8;
+ color.b = (color.b * (color.a + 1)) >> 8;
+ }
+
+ mga_waitfifo( mdrv, mdev, 4 );
+
+ mga_out32( mmio, U8_TO_F0915(color.a), ALPHASTART );
+ mga_out32( mmio, U8_TO_F0915(color.r), DR4 );
+ mga_out32( mmio, U8_TO_F0915(color.g), DR8 );
+ mga_out32( mmio, U8_TO_F0915(color.b), DR12 );
+
+ MGA_VALIDATE( m_drawColor );
+ MGA_INVALIDATE( m_blitColor );
+ MGA_INVALIDATE( m_blitBlend );
+}
+
+void matrox_validate_blitColor( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ DFBColor color = state->color;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ if (MGA_IS_VALID( m_blitColor ))
+ return;
+
+ if (state->blittingflags & DSBLIT_COLORIZE) {
+ if (state->blittingflags & DSBLIT_SRC_PREMULTCOLOR) {
+ color.r = (color.r * (color.a + 1)) >> 8;
+ color.g = (color.g * (color.a + 1)) >> 8;
+ color.b = (color.b * (color.a + 1)) >> 8;
+ }
+ }
+ else {
+ if (state->blittingflags & DSBLIT_SRC_PREMULTCOLOR)
+ color.r = color.g = color.b = color.a;
+ else
+ color.r = color.g = color.b = 0xff;
+ }
+
+ mga_waitfifo( mdrv, mdev, 4 );
+
+ mga_out32( mmio, U8_TO_F0915(color.a), ALPHASTART );
+ mga_out32( mmio, U8_TO_F0915(color.r), DR4 );
+ mga_out32( mmio, U8_TO_F0915(color.g), DR8 );
+ mga_out32( mmio, U8_TO_F0915(color.b), DR12 );
+
+ MGA_VALIDATE( m_blitColor );
+ MGA_INVALIDATE( m_drawColor );
+ MGA_INVALIDATE( m_blitBlend );
+}
+
+void matrox_validate_color( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ DFBColor color = state->color;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ u32 fcol;
+ u8 cb, cr;
+
+ if (MGA_IS_VALID( m_color ))
+ return;
+
+ if (state->drawingflags & DSDRAW_SRC_PREMULTIPLY) {
+ color.r = (color.r * (color.a + 1)) >> 8;
+ color.g = (color.g * (color.a + 1)) >> 8;
+ color.b = (color.b * (color.a + 1)) >> 8;
+ }
+
+ switch (state->destination->config.format) {
+ case DSPF_ALUT44:
+ fcol = (color.a & 0xF0) | state->color_index;
+ fcol |= fcol << 8;
+ fcol |= fcol << 16;
+ break;
+ case DSPF_LUT8:
+ fcol = state->color_index;
+ fcol |= fcol << 8;
+ fcol |= fcol << 16;
+ break;
+ case DSPF_RGB332:
+ fcol = PIXEL_RGB332( color.r,
+ color.g,
+ color.b );
+ fcol |= fcol << 8;
+ fcol |= fcol << 16;
+ break;
+ case DSPF_RGB444:
+ fcol = PIXEL_RGB444( color.r,
+ color.g,
+ color.b );
+ fcol |= fcol << 16;
+ break;
+ case DSPF_ARGB4444:
+ fcol = PIXEL_ARGB4444( color.a,
+ color.r,
+ color.g,
+ color.b );
+ fcol |= fcol << 16;
+ break;
+ case DSPF_RGB555:
+ fcol = PIXEL_RGB555( color.r,
+ color.g,
+ color.b );
+ fcol |= fcol << 16;
+ break;
+ case DSPF_ARGB1555:
+ fcol = PIXEL_ARGB1555( color.a,
+ color.r,
+ color.g,
+ color.b );
+ fcol |= fcol << 16;
+ break;
+ case DSPF_RGB16:
+ fcol = PIXEL_RGB16( color.r,
+ color.g,
+ color.b );
+ fcol |= fcol << 16;
+ break;
+ case DSPF_RGB24:
+ fcol = PIXEL_RGB32( color.r,
+ color.g,
+ color.b );
+ fcol |= fcol << 24;
+ break;
+ case DSPF_RGB32:
+ fcol = PIXEL_RGB32( color.r,
+ color.g,
+ color.b );
+ break;
+ case DSPF_ARGB:
+ fcol = PIXEL_ARGB( color.a,
+ color.r,
+ color.g,
+ color.b );
+ break;
+ case DSPF_A8:
+ fcol = color.a;
+ fcol |= fcol << 8;
+ fcol |= fcol << 16;
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ RGB_TO_YCBCR( color.r,
+ color.g,
+ color.b,
+ fcol, cb, cr );
+ fcol |= fcol << 8;
+ fcol |= fcol << 16;
+ mdev->color[0] = fcol;
+ mdev->color[1] = (cb << 24) | (cb << 16) | (cb << 8) | cb;
+ mdev->color[2] = (cr << 24) | (cr << 16) | (cr << 8) | cr;
+ break;
+ case DSPF_NV12:
+ RGB_TO_YCBCR( color.r,
+ color.g,
+ color.b,
+ fcol, cb, cr );
+ fcol |= fcol << 8;
+ fcol |= fcol << 16;
+ mdev->color[0] = fcol;
+ mdev->color[1] = (cr << 24) | (cb << 16) | (cr << 8) | cb;
+ break;
+ case DSPF_NV21:
+ RGB_TO_YCBCR( color.r,
+ color.g,
+ color.b,
+ fcol, cb, cr );
+ fcol |= fcol << 8;
+ fcol |= fcol << 16;
+ mdev->color[0] = fcol;
+ mdev->color[1] = (cb << 24) | (cr << 16) | (cb << 8) | cr;
+ break;
+ case DSPF_YUY2:
+ RGB_TO_YCBCR( color.r,
+ color.g,
+ color.b,
+ fcol, cb, cr );
+ fcol = PIXEL_YUY2( fcol, cb, cr );
+ break;
+ case DSPF_UYVY:
+ RGB_TO_YCBCR( color.r,
+ color.g,
+ color.b,
+ fcol, cb, cr );
+ fcol = PIXEL_UYVY( fcol, cb, cr );
+ break;
+ default:
+ D_BUG( "unexpected pixelformat!" );
+ return;
+ }
+
+ mga_waitfifo( mdrv, mdev, 1 );
+ mga_out32( mmio, fcol, FCOL );
+
+ MGA_VALIDATE( m_color );
+ MGA_INVALIDATE( m_srckey );
+}
+
+static u32 matroxSourceBlend[] = {
+ SRC_ZERO, /* DSBF_ZERO */
+ SRC_ONE, /* DSBF_ONE */
+ 0, /* DSBF_SRCCOLOR */
+ 0, /* DSBF_INVSRCCOLOR */
+ SRC_ALPHA, /* DSBF_SRCALPHA */
+ SRC_ONE_MINUS_SRC_ALPHA, /* DSBF_INVSRCALPHA */
+ SRC_DST_ALPHA, /* DSBF_DESTALPHA */
+ SRC_ONE_MINUS_DST_ALPHA, /* DSBF_INVDESTALPHA */
+ SRC_DST_COLOR, /* DSBF_DESTCOLOR */
+ SRC_ONE_MINUS_DST_COLOR, /* DSBF_INVDESTCOLOR */
+ SRC_SRC_ALPHA_SATURATE /* DSBF_SRCALPHASAT */
+};
+
+static u32 matroxDestBlend[] = {
+ DST_ZERO, /* DSBF_ZERO */
+ DST_ONE, /* DSBF_ONE */
+ DST_SRC_COLOR, /* DSBF_SRCCOLOR */
+ DST_ONE_MINUS_SRC_COLOR, /* DSBF_INVSRCCOLOR */
+ DST_SRC_ALPHA, /* DSBF_SRCALPHA */
+ DST_ONE_MINUS_SRC_ALPHA, /* DSBF_INVSRCALPHA */
+ DST_DST_ALPHA, /* DSBF_DESTALPHA */
+ DST_ONE_MINUS_DST_ALPHA, /* DSBF_INVDESTALPHA */
+ 0, /* DSBF_DESTCOLOR */
+ 0, /* DSBF_INVDESTCOLOR */
+ 0 /* DSBF_SRCALPHASAT */
+};
+
+void matrox_validate_drawBlend( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ u32 alphactrl;
+
+ if (MGA_IS_VALID( m_drawBlend ))
+ return;
+
+ alphactrl = matroxSourceBlend[state->src_blend - 1] |
+ matroxDestBlend [state->dst_blend - 1] |
+ ALPHACHANNEL | DIFFUSEDALPHA;
+
+ mga_waitfifo( mdrv, mdev, 1 );
+ mga_out32( mmio, alphactrl, ALPHACTRL );
+
+ MGA_VALIDATE( m_drawBlend );
+ MGA_INVALIDATE( m_blitBlend );
+}
+
+static u32 matroxAlphaSelect[] = {
+ 0,
+ 0,
+ DIFFUSEDALPHA,
+ MODULATEDALPHA
+};
+
+void matrox_validate_blitBlend( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ u32 alphactrl;
+
+ if (MGA_IS_VALID( m_blitBlend ))
+ return;
+
+ if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL |
+ DSBLIT_BLEND_COLORALPHA))
+ {
+ if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY)
+ /* src_blend == ONE and dst_blend == INVSRCALPHA/INVSRCCOLOR */
+ alphactrl = matroxSourceBlend[DSBF_SRCALPHA - 1] |
+ matroxDestBlend [state->dst_blend - 1] |
+ VIDEOALPHA;
+ else
+ alphactrl = matroxSourceBlend[state->src_blend - 1] |
+ matroxDestBlend [state->dst_blend - 1] |
+ ALPHACHANNEL;
+
+ if (state->source->config.format == DSPF_RGB32) {
+ alphactrl |= DIFFUSEDALPHA;
+
+ if (! (state->blittingflags & DSBLIT_BLEND_COLORALPHA)) {
+ mga_out32( mmio, U8_TO_F0915(0xff), ALPHASTART );
+ MGA_INVALIDATE( m_drawColor | m_blitColor );
+ }
+ }
+ else
+ alphactrl |= matroxAlphaSelect [state->blittingflags & 3];
+ }
+ else {
+ alphactrl = SRC_ONE | DST_ZERO | ALPHACHANNEL;
+
+ if (state->source->config.format == DSPF_RGB32) {
+ alphactrl |= DIFFUSEDALPHA;
+
+ mga_out32( mmio, U8_TO_F0915(0xff), ALPHASTART );
+ MGA_INVALIDATE( m_drawColor | m_blitColor );
+ }
+ }
+
+ mga_waitfifo( mdrv, mdev, 1 );
+ mga_out32( mmio, alphactrl, ALPHACTRL );
+
+ MGA_VALIDATE( m_blitBlend );
+ MGA_INVALIDATE( m_drawBlend );
+}
+
+static void matrox_tlutload( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CorePalette *palette )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ volatile u16 *dst = dfb_gfxcard_memory_virtual( NULL, mdev->tlut_offset );
+ unsigned int i;
+
+ for (i = 0; i < palette->num_entries; i++)
+ *dst++ = PIXEL_RGB16( palette->entries[i].r,
+ palette->entries[i].g,
+ palette->entries[i].b );
+
+ mga_waitfifo( mdrv, mdev, mdev->old_matrox ? 8 : 9 );
+ mga_out32( mmio, BLTMOD_BU32RGB | BOP_COPY | SHFTZERO |
+ SGNZERO | LINEAR | ATYPE_RSTR | OP_BITBLT, DWGCTL );
+ mga_out32( mmio, 1024, PITCH );
+ if (mdev->old_matrox) {
+ mga_out32( mmio, mdev->tlut_offset / 2, AR3 );
+ mga_out32( mmio, palette->num_entries, AR0 );
+ mga_out32( mmio, 0, YDSTORG );
+ }
+ else {
+ mga_out32( mmio, 0, AR3 );
+ mga_out32( mmio, palette->num_entries, AR0 );
+ mga_out32( mmio, mdev->fb.offset + mdev->tlut_offset, SRCORG );
+ mga_out32( mmio, 0, DSTORG );
+
+ MGA_INVALIDATE( m_source );
+ }
+ mga_out32( mmio, 0, FXBNDRY );
+ mga_out32( mmio, PW16 | TLUTLOAD, MACCESS );
+ mga_out32( mmio, palette->num_entries, YDSTLEN | EXECUTE );
+
+ MGA_INVALIDATE( m_destination );
+}
+
+void matrox_validate_Source( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ CoreSurface *surface = state->source;
+ int bytes_per_pixel = DFB_BYTES_PER_PIXEL(surface->config.format);
+ u32 texctl = 0, texctl2 = 0;
+
+ if (MGA_IS_VALID( m_Source ))
+ return;
+
+ mdev->src_pitch = state->src.pitch / bytes_per_pixel;
+ mdev->field = surface->field;
+ mdev->w = surface->config.size.w;
+ mdev->h = surface->config.size.h;
+
+ if (state->destination->config.format == DSPF_YUY2 || state->destination->config.format == DSPF_UYVY) {
+ mdev->w /= 2;
+ mdev->src_pitch /= 2;
+ }
+
+ if (mdev->blit_deinterlace || mdev->blit_fields) {
+ mdev->h /= 2;
+ if (!(surface->config.caps & DSCAPS_SEPARATED))
+ mdev->src_pitch *= 2;
+ }
+
+ D_ASSERT( mdev->src_pitch % 32 == 0 );
+
+ matrox_calc_offsets( mdev, surface, &state->src, false, mdev->src_offset );
+
+ if (mdev->blit_deinterlace && mdev->field) {
+ mdev->src_offset[0][0] = mdev->src_offset[1][0];
+ mdev->src_offset[0][1] = mdev->src_offset[1][1];
+ mdev->src_offset[0][2] = mdev->src_offset[1][2];
+ }
+
+ mdev->w2 = mga_log2( mdev->w );
+ mdev->h2 = mga_log2( mdev->h );
+
+ if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL)
+ texctl = TAMASK;
+ else
+ texctl = TAKEY;
+
+ switch (surface->config.format) {
+ case DSPF_YUY2:
+ texctl |= (state->destination->config.format == DSPF_YUY2) ? TW32 : TW422;
+ break;
+ case DSPF_UYVY:
+ texctl |= (state->destination->config.format == DSPF_UYVY) ? TW32 : TW422UYVY;
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ case DSPF_NV12:
+ case DSPF_NV21:
+ case DSPF_A8:
+ texctl |= TW8A;
+ break;
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ texctl |= TW12;
+ break;
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ texctl |= TW15;
+ break;
+ case DSPF_RGB16:
+ texctl |= TW16;
+ break;
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ texctl |= TW32;
+ break;
+ case DSPF_LUT8:
+ matrox_tlutload( mdrv, mdev, surface->palette );
+ texctl |= TW8;
+ break;
+ case DSPF_RGB332:
+ matrox_tlutload( mdrv, mdev, mdev->rgb332_palette );
+ texctl |= TW8;
+ break;
+ default:
+ D_BUG( "unexpected pixelformat!" );
+ break;
+ }
+
+ texctl |= ((mdev->src_pitch << 9) & TPITCHEXT) | TPITCHLIN;
+
+ if (1 << mdev->w2 != mdev->w || 1 << mdev->h2 != mdev->h)
+ texctl |= CLAMPUV;
+
+ if (state->blittingflags & (DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR))
+ texctl |= TMODULATE;
+ else
+ texctl2 |= DECALDIS;
+
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY)
+ texctl |= DECALCKEY | STRANS;
+ else
+ texctl2 |= CKSTRANSDIS;
+
+ if (surface->config.format == DSPF_A8)
+ texctl2 |= IDECAL | DECALDIS;
+
+ mdev->texctl = texctl;
+
+ mga_waitfifo( mdrv, mdev, 5 );
+ mga_out32( mmio, texctl, TEXCTL );
+ mga_out32( mmio, texctl2, TEXCTL2 );
+
+ mga_out32( mmio, ( (((u32)(mdev->w - 1) & 0x7ff) << 18) |
+ (((u32)(4 - mdev->w2) & 0x3f) << 9) |
+ (((u32)(mdev->w2 + 4) & 0x3f) ) ), TEXWIDTH );
+
+ mga_out32( mmio, ( (((u32)(mdev->h - 1) & 0x7ff) << 18) |
+ (((u32)(4 - mdev->h2) & 0x3f) << 9) |
+ (((u32)(mdev->h2 + 4) & 0x3f) ) ), TEXHEIGHT );
+
+ mga_out32( mmio, mdev->src_offset[0][0], TEXORG );
+
+ MGA_VALIDATE( m_Source );
+}
+
+void matrox_validate_source( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ CoreSurface *surface = state->source;
+ int bytes_per_pixel = DFB_BYTES_PER_PIXEL(surface->config.format);
+
+ if (MGA_IS_VALID( m_source ))
+ return;
+
+ mdev->src_pitch = state->src.pitch / bytes_per_pixel;
+
+ if (state->destination->config.format == DSPF_YUY2 || state->destination->config.format == DSPF_UYVY)
+ mdev->src_pitch /= 2;
+
+ if (mdev->blit_fields && !(surface->config.caps & DSCAPS_SEPARATED))
+ mdev->src_pitch *= 2;
+
+ D_ASSERT( mdev->src_pitch % 32 == 0 );
+
+ matrox_calc_offsets( mdev, surface, &state->src, mdev->old_matrox, mdev->src_offset );
+
+ if (!mdev->old_matrox) {
+ mga_waitfifo( mdrv, mdev, 1 );
+ mga_out32( mmio, mdev->src_offset[0][0], SRCORG );
+ }
+
+ MGA_VALIDATE( m_source );
+}
+
+void matrox_validate_SrcKey( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ CoreSurface *surface = state->source;
+ u32 key;
+ u32 mask;
+
+ if (MGA_IS_VALID( m_SrcKey ))
+ return;
+
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY) {
+ mask = MGA_KEYMASK(surface->config.format);
+ key = state->src_colorkey & mask;
+ } else {
+ mask = 0;
+ key = 0xFFFF;
+ }
+
+ mga_waitfifo( mdrv, mdev, 2);
+
+ mga_out32( mmio, ((mask & 0xFFFF) << 16) | (key & 0xFFFF), TEXTRANS );
+ mga_out32( mmio, (mask & 0xFFFF0000) | (key >> 16), TEXTRANSHIGH );
+
+ MGA_VALIDATE( m_SrcKey );
+}
+
+void matrox_validate_srckey( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ CoreSurface *surface = state->source;
+ u32 key;
+ u32 mask;
+
+ if (MGA_IS_VALID( m_srckey ))
+ return;
+
+ mask = MGA_KEYMASK(surface->config.format);
+ key = state->src_colorkey & mask;
+
+ switch (DFB_BYTES_PER_PIXEL(state->source->config.format)) {
+ case 1:
+ mask |= mask << 8;
+ key |= key << 8;
+ case 2:
+ mask |= mask << 16;
+ key |= key << 16;
+ }
+
+ mga_waitfifo( mdrv, mdev, 2);
+ mga_out32( mmio, mask, BCOL );
+ mga_out32( mmio, key, FCOL );
+
+ MGA_VALIDATE( m_srckey );
+ MGA_INVALIDATE( m_color );
+}
+
diff --git a/Source/DirectFB/gfxdrivers/matrox/matrox_state.h b/Source/DirectFB/gfxdrivers/matrox/matrox_state.h
new file mode 100755
index 0000000..160efe0
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/matrox_state.h
@@ -0,0 +1,70 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef ___MATROX_STATE_H__
+#define ___MATROX_STATE_H__
+
+void matrox_validate_destination( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state );
+void matrox_set_clip( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ DFBRegion *clip );
+
+void matrox_validate_drawColor( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state );
+void matrox_validate_blitColor( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state );
+void matrox_validate_color( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state );
+
+void matrox_validate_drawBlend( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state );
+void matrox_validate_blitBlend( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state );
+
+void matrox_validate_Source( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state );
+void matrox_validate_source( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state );
+
+void matrox_validate_SrcKey( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state );
+void matrox_validate_srckey( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state );
+
+#endif
diff --git a/Source/DirectFB/gfxdrivers/matrox/mmio.h b/Source/DirectFB/gfxdrivers/matrox/mmio.h
new file mode 100755
index 0000000..d897db6
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/mmio.h
@@ -0,0 +1,118 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __MATROX_MMIO_H__
+#define __MATROX_MMIO_H__
+
+#include <dfb_types.h>
+
+#include "matrox.h"
+
+static inline void
+mga_out8(volatile u8 *mmioaddr, u8 value, u32 reg)
+{
+ *((volatile u8*)(mmioaddr+reg)) = value;
+}
+
+static inline void
+mga_out32(volatile u8 *mmioaddr, u32 value, u32 reg)
+{
+#ifdef __powerpc__
+ asm volatile("stwbrx %0,%1,%2;eieio" : : "r"(value), "b"(reg), "r"(mmioaddr) : "memory");
+#else
+ *((volatile u32*)(mmioaddr+reg)) = value;
+#endif
+}
+
+static inline u8
+mga_in8(volatile u8 *mmioaddr, u32 reg)
+{
+ return *((volatile u8*)(mmioaddr+reg));
+}
+
+static inline u32
+mga_in32(volatile u8 *mmioaddr, u32 reg)
+{
+#ifdef __powerpc__
+ u32 value;
+
+ asm volatile("lwbrx %0,%1,%2;eieio" : "=r"(value) : "b"(reg), "r"(mmioaddr));
+
+ return value;
+#else
+ return *((volatile u32*)(mmioaddr+reg));
+#endif
+}
+
+/* Wait for idle accelerator and DMA */
+static inline void
+mga_waitidle(MatroxDriverData *mdrv, MatroxDeviceData *mdev)
+{
+ while ((mga_in32(mdrv->mmio_base, STATUS) & (DWGENGSTS | ENDPRDMASTS)) != mdev->idle_status) {
+ mdev->idle_waitcycles++;
+ }
+}
+
+/* Wait for fifo space */
+static inline void
+mga_waitfifo(MatroxDriverData *mdrv, MatroxDeviceData *mdev, unsigned int space)
+{
+ mdev->waitfifo_sum += space;
+ mdev->waitfifo_calls++;
+
+ if (mdev->fifo_space < space) {
+ do { /* not needed on a G400,
+ hardware does retries on writing if FIFO is full,
+ but results in DMA problems */
+ mdev->fifo_space = mga_in32(mdrv->mmio_base, FIFOSTATUS) & 0xff;
+ mdev->fifo_waitcycles++;
+ } while (mdev->fifo_space < space);
+ }
+ else {
+ mdev->fifo_cache_hits++;
+ }
+
+ mdev->fifo_space -= space;
+}
+
+static inline void
+mga_out_dac( volatile u8 *mmioaddr, u8 reg, u8 val )
+{
+ mga_out8( mmioaddr, reg, DAC_INDEX );
+ mga_out8( mmioaddr, val, DAC_DATA );
+}
+
+static inline u8
+mga_in_dac( volatile u8 *mmioaddr, u8 reg )
+{
+ mga_out8( mmioaddr, reg, DAC_INDEX );
+ return mga_in8( mmioaddr, DAC_DATA );
+}
+
+#endif
+
diff --git a/Source/DirectFB/gfxdrivers/matrox/regs.h b/Source/DirectFB/gfxdrivers/matrox/regs.h
new file mode 100755
index 0000000..a419b83
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/regs.h
@@ -0,0 +1,454 @@
+#ifndef __MATROX__REGS_H__
+#define __MATROX__REGS_H__
+
+#define U8_TO_F0915(x) (((u32) ((x+1) << 15)) & 0x00FFFFFF)
+
+#define RS16(val) ( (u16)((s16)(val)))
+#define RS18(val) (((u32)((s32)(val)))&0x003ffff)
+#define RS24(val) (((u32)((s32)(val)))&0x0ffffff)
+#define RS27(val) (((u32)((s32)(val)))&0x7ffffff)
+
+#define DWGSYNC 0x2C4C
+#define SYNC_DMA_BUSY 0x8325340 /* just a random number */
+
+#define RST 0x1E40
+#define OPMODE 0x1E54
+
+#define CACHEFLUSH 0x1FFF
+
+/* CRTC2 registers */
+#define C2CTL 0x3C10
+# define C2EN 0x00000001
+# define C2PIXCLKSEL_PCICLK 0x00000000
+# define C2PIXCLKSEL_VDOCLK 0x00000002
+# define C2PIXCLKSEL_PIXPLL 0x00000004
+# define C2PIXCLKSEL_VIDPLL 0x00000006 /* SYSPLL on G400 */
+# define C2PIXCLKSEL_VDCLK 0x00004000 /* G450/G550 only */
+# define C2PIXCLKSEL_CRISTAL 0x00004002 /* G450/G550 only */
+# define C2PIXCLKSEL_SYSPLL 0x00004004 /* G450/G550 only */
+# define C2PIXCLKDIS 0x00000008
+# define CRTCDACSEL 0x00100000
+# define C2DEPTH_15BPP 0x00200000
+# define C2DEPTH_16BPP 0x00400000
+# define C2DEPTH_32BPP 0x00800000
+# define C2DEPTH_YCBCR422 0x00A00000
+# define C2DEPTH_YCBCR420 0x00E00000
+# define C2VCBCRSINGLE 0x01000000
+# define C2INTERLACE 0x02000000
+# define C2FIELDLENGTH 0x04000000
+# define C2FIELDPOL 0x08000000
+# define C2VIDRSTMOD_FALLING 0x00000000
+# define C2VIDRSTMOD_RISING 0x10000000
+# define C2VIDRSTMOD_BOTH 0x20000000
+# define C2HPLOADEN 0x40000000
+# define C2VPLOADEN 0x80000000
+#define C2HPARAM 0x3C14
+#define C2HSYNC 0x3C18
+#define C2VPARAM 0x3C1C
+#define C2VSYNC 0x3C20
+#define C2PRELOAD 0x3C24
+#define C2STARTADD0 0x3C28
+#define C2STARTADD1 0x3C2C
+#define C2PL2STARTADD0 0x3C30
+#define C2PL2STARTADD1 0x3C34
+#define C2PL3STARTADD0 0x3C38
+#define C2PL3STARTADD1 0x3C3C
+#define C2OFFSET 0x3C40
+#define C2MISC 0x3C44
+# define C2HSYNCPOL 0x00000100
+# define C2VSYNCPOL 0x00000200
+#define C2VCOUNT 0x3C48
+# define C2FIELD 0x01000000
+#define C2DATACTL 0x3C4C
+# define C2DITHEN 0x00000001
+# define C2YFILTEN 0x00000002
+# define C2CBCRFILTEN 0x00000004
+# define C2SUBPICEN 0x00000008
+# define C2NTSCEN 0x00000010
+# define C2STATICKEYEN 0x00000020
+# define C2OFFSETDIVEN 0x00000040
+# define C2UYVYFMT 0x00000080
+# define C2STATICKEY 0x1F000000
+#define C2SUBPICLUT 0x3C50
+#define C2SPICSTARTADD0 0x3C54
+#define C2SPICSTARTADD1 0x3C58
+
+/* Backend scaler registers */
+#define BESA1ORG 0x3D00
+#define BESA2ORG 0x3D04
+#define BESB1ORG 0x3D08
+#define BESB2ORG 0x3D0C
+#define BESA1CORG 0x3D10
+#define BESA2CORG 0x3D14
+#define BESB1CORG 0x3D18
+#define BESB2CORG 0x3D1C
+#define BESA1C3ORG 0x3D60
+#define BESA2C3ORG 0x3D64
+#define BESB1C3ORG 0x3D68
+#define BESB2C3ORG 0x3D6C
+
+#define BESCTL 0x3D20
+# define BESEN 0x00000001
+# define BESV1SRCSTP 0x00000040
+# define BESV2SRCSTP 0x00000080
+# define BESHFEN 0x00000400
+# define BESVFEN 0x00000800
+# define BESCUPS 0x00010000
+# define BES420PL 0x00020000
+
+#define BESGLOBCTL 0x3DC0
+# define BESCORDER 0x00000008
+# define BES3PLANE 0x00000020
+# define BESUYVYFMT 0x00000040
+# define BESPROCAMP 0x00000080
+# define BESRGB15 0x00000100
+# define BESRGB16 0x00000200
+# define BESRGB32 0x00000300
+
+#define BESHCOORD 0x3D28
+#define BESHISCAL 0x3D30
+#define BESHSRCEND 0x3D3C
+#define BESHSRCLST 0x3D50
+#define BESHSRCST 0x3D38
+#define BESLUMACTL 0x3D40
+#define BESPITCH 0x3D24
+#define BESSTATUS 0x3DC4
+#define BESV1SRCLST 0x3D54
+#define BESV2SRCLST 0x3D58
+#define BESV1WGHT 0x3D48
+#define BESV2WGHT 0x3D4C
+#define BESVCOORD 0x3D2C
+#define BESVISCAL 0x3D34
+
+/* DAC Registers */
+#define DAC_INDEX 0x3C00
+#define DAC_DATA 0x3C0A
+
+#define MGAREG_VCOUNT 0x1e20
+
+/* Alpha registers */
+
+#define ALPHASTART 0x2C70
+#define ALPHAXINC 0x2C74
+#define ALPHAYINC 0x2C78
+
+#define ALPHACTRL 0x2C7C
+#define SRC_ZERO 0x00000000
+#define SRC_ONE 0x00000001
+#define SRC_DST_COLOR 0x00000002
+#define SRC_ONE_MINUS_DST_COLOR 0x00000003
+#define SRC_ALPHA 0x00000004
+#define SRC_ONE_MINUS_SRC_ALPHA 0x00000005
+#define SRC_DST_ALPHA 0x00000006
+#define SRC_ONE_MINUS_DST_ALPHA 0x00000007
+#define SRC_SRC_ALPHA_SATURATE 0x00000008
+
+#define DST_ZERO 0x00000000
+#define DST_ONE 0x00000010
+#define DST_SRC_COLOR 0x00000020
+#define DST_ONE_MINUS_SRC_COLOR 0x00000030
+#define DST_SRC_ALPHA 0x00000040
+#define DST_ONE_MINUS_SRC_ALPHA 0x00000050
+#define DST_DST_ALPHA 0x00000060
+#define DST_ONE_MINUS_DST_ALPHA 0x00000070
+
+#define ALPHACHANNEL 0x00000100
+#define VIDEOALPHA 0x00000200
+
+#define DIFFUSEDALPHA 0x01000000
+#define MODULATEDALPHA 0x02000000
+
+/* Texture registers */
+
+#define TEXCTL 0x2C30
+#define TEXCTL2 0x2C3C
+#define TEXFILTER 0x2C58
+#define TEXWIDTH 0x2C28
+#define TEXHEIGHT 0x2C2C
+#define TEXORG 0x2C24
+#define TEXORG1 0x2CA4
+#define TEXORG2 0x2CA8
+#define TEXORG3 0x2CAC
+#define TEXORG4 0x2CB0
+#define TEXTRANS 0x2C34
+#define TEXTRANSHIGH 0x2C38
+#define TDUALSTAGE0 0x2CF8
+#define TDUALSTAGE1 0x2CFC
+
+#define TMR0 0x2C00
+#define TMR1 0x2C04
+#define TMR2 0x2C08
+#define TMR3 0x2C0C
+#define TMR4 0x2C10
+#define TMR5 0x2C14
+#define TMR6 0x2C18
+#define TMR7 0x2C1C
+#define TMR8 0x2C20
+
+#define CUR_XWINDOWS 0x03
+
+/* TEXCTL */
+#define TW4 0x00000000
+#define TW8 0x00000001
+#define TW15 0x00000002
+#define TW16 0x00000003
+#define TW12 0x00000004
+
+#define TW32 0x00000006
+#define TW8A 0x00000007
+#define TW8AL 0x00000008
+#define TW422 0x0000000A
+#define TW422UYVY 0x0000000B
+
+#define TFORMAT 0x0000000F
+#define TPITCHLIN 0x00000100
+#define TPITCHEXT 0x000FFE00
+
+#define NOPERSPECTIVE 0x00200000
+#define TAKEY 0x02000000
+#define TAMASK 0x04000000
+#define CLAMPUV 0x18000000
+
+#define DECALCKEY 0x01000000
+#define TMODULATE 0x20000000
+#define STRANS 0x40000000
+
+
+/* TEXTCTL2 */
+#define IDECAL 0x00000002
+#define DECALDIS 0x00000004
+#define CKSTRANSDIS 0x00000010
+
+
+/* TEXFILTER */
+#define MIN_NRST 0x00000000
+#define MIN_BILIN 0x00000002
+#define MIN_ANISO 0x0000000D
+#define MAG_NRST 0x00000000
+#define MAG_BILIN 0x00000020
+#define FILTER_ALPHA 0x00100000
+
+/* SGN */
+#define SGN_BRKLEFT 0x00000100
+
+#define DSTORG 0x2cb8
+#define SRCORG 0x2cb4
+
+#define MACCESS 0x1C04
+# define PW8 0x00000000
+# define PW16 0x00000001
+# define PW32 0x00000002
+# define PW24 0x00000003
+# define ZW16 0x00000000
+# define ZW32 0x00000008
+# define ZW15 0x00000010
+# define ZW24 0x00000018
+# define BYPASS332 0x10000000
+# define TLUTLOAD 0x20000000
+# define NODITHER 0x40000000
+# define DIT555 0x80000000
+
+
+#define EXECUTE 0x100 /* or with register to execute a programmed
+ accel command */
+
+#define DWGCTL 0x1C00 /* Drawing control */
+ /* opcod - Operation code */
+# define OP_LINE_OPEN 0x00
+# define OP_AUTOLINE_OPEN 0x01
+# define OP_LINE_CLOSE 0x02
+# define OP_AUTOLINE_CLOSE 0x03
+# define OP_TRAP 0x04
+# define OP_TRAP_ILOAD 0x05
+# define OP_TEXTURE_TRAP 0x06
+# define OP_ILOAD_HIQH 0x07
+# define OP_BITBLT 0x08
+# define OP_ILOAD 0x09
+# define OP_IDUMP 0x0A
+# define OP_FBITBLT 0x0C
+# define OP_ILOAD_SCALE 0x0D
+# define OP_ILOAD_HIQHV 0x0E
+# define OP_ILOAD_FILTER 0x0F
+
+ /* atype - Access type */
+# define ATYPE_RPL 0x00
+# define ATYPE_RSTR 0x10
+# define ATYPE_ZI 0x30
+# define ATYPE_BLK 0x40
+# define ATYPE_I 0x70
+
+ /* Flag */
+# define LINEAR 0x80
+# define NOCLIP (1<<31)
+# define TRANSC (1<<30)
+
+ /* zmode - Z drawing mode */
+# define ZMODE_NOZCMP 0x000
+# define ZMODE_ZE 0x200
+# define ZMODE_ZNE 0x300
+# define ZMODE_ZLT 0x400
+# define ZMODE_ZLTE 0x500
+# define ZMODE_ZGT 0x600
+# define ZMODE_ZGTE 0x700
+
+ /* Flags */
+# define SOLID 0x0800
+# define ARZERO 0x1000
+# define SGNZERO 0x2000
+# define SHFTZERO 0x4000
+
+ /* bop - Boolean operation */
+# define BOP_CLEAR 0x00000
+# define BOP_NOR 0x10000
+# define BOP_COPYINV 0x30000
+# define BOP_INVERT 0x50000
+# define BOP_XOR 0x60000
+# define BOP_NAND 0x70000
+# define BOP_AND 0x80000
+# define BOP_EQUIV 0x90000
+# define BOP_NOOP 0xA0000
+# define BOP_IMP 0xB0000
+# define BOP_COPY 0xC0000
+# define BOP_OR 0xE0000
+# define BOP_SET 0xF0000
+
+ /* bltmod - Blit mode selection */
+# define BLTMOD_BMONOLEF 0x00000000
+# define BLTMOD_BMONOWF 0x08000000
+# define BLTMOD_BPLAN 0x02000000
+# define BLTMOD_BFCOL 0x04000000
+# define BLTMOD_BUYUV 0x1C000000
+# define BLTMOD_BU32BGR 0x06000000
+# define BLTMOD_BU32RGB 0x0E000000
+# define BLTMOD_BU24BGR 0x16000000
+# define BLTMOD_BU24RGB 0x1E000000
+
+#define ZORG 0x1C0C
+#define PAT0 0x1C10
+#define PAT1 0x1C14
+#define PLNWT 0x1C1C
+#define BCOL 0x1C20
+#define FCOL 0x1C24
+#define SRC0 0x1C30
+#define SRC1 0x1C34
+#define SRC2 0x1C38
+#define SRC3 0x1C3C
+#define XYSTRT 0x1C40
+#define XYEND 0x1C44
+#define SHIFT 0x1C50
+#define DMAPAD 0x1C54
+#define SGN 0x1C58
+#define LEN 0x1C5C
+#define AR0 0x1C60
+#define AR1 0x1C64
+#define AR2 0x1C68
+#define AR3 0x1C6C
+#define AR4 0x1C70
+#define AR5 0x1C74
+#define AR6 0x1C78
+#define CXBNDRY 0x1C80
+#define FXBNDRY 0x1C84
+#define YDSTLEN 0x1C88
+#define PITCH 0x1C8C
+#define YDST 0x1C90
+#define YDSTORG 0x1C94
+#define YTOP 0x1C98
+#define YBOT 0x1C9C
+#define CXLEFT 0x1CA0
+#define CXRIGHT 0x1CA4
+#define FXLEFT 0x1CA8
+#define FXRIGHT 0x1CAC
+#define XDST 0x1CB0
+#define DR0 0x1CC0
+#define DR2 0x1CC8
+#define DR3 0x1CCC
+#define DR4 0x1CD0
+#define DR6 0x1CD8
+#define DR7 0x1CDC
+#define DR8 0x1CE0
+#define WO 0x1CE4
+#define DR10 0x1CE8
+#define DR11 0x1CEC
+#define DR12 0x1CF0
+#define DR14 0x1CF8
+#define DR15 0x1CFC
+
+#define FIFOSTATUS 0x1E10
+
+#define STATUS 0x1E14
+# define DWGENGSTS 0x10000
+# define ENDPRDMASTS 0x20000
+
+#define IEN 0x1E1C
+
+#define BLIT_LEFT 1
+#define BLIT_UP 4
+
+
+#define SDXL 0x0002
+#define SDXR 0x0020
+
+
+/* DAC registers */
+
+#define XMISCCTRL 0x1E
+# define DACPDN 0x01
+# define MFCSEL_MAFC 0x02
+# define MFCSEL_PANELLINK 0x04
+# define MFCSEL_DIS 0x06
+# define MFCSEL_MASK 0x06
+# define VGA8DAC 0x08
+# define RAMCS 0x10
+# define VDOUTSEL_MAFC12 0x00
+# define VDOUTSEL_BYPASS656 0x40
+# define VDOUTSEL_CRTC2RGB 0x80
+# define VDOUTSEL_CRTC2656 0xC0
+# define VDOUTSEL_MASK 0xE0
+
+#define XGENIOCTRL 0x2A
+#define XGENIODATA 0x2B
+
+#define XKEYOPMODE 0x51
+
+#define XCOLMSK0RED 0x52
+#define XCOLMSK0GREEN 0x53
+#define XCOLMSK0BLUE 0x54
+
+#define XCOLKEY0RED 0x55
+#define XCOLKEY0GREEN 0x56
+#define XCOLKEY0BLUE 0x57
+
+#define XDISPCTRL 0x8A
+# define DAC1OUTSEL_DIS 0x00
+# define DAC1OUTSEL_EN 0x01
+# define DAC1OUTSEL_MASK 0x01
+# define DAC2OUTSEL_DIS 0x00
+# define DAC2OUTSEL_CRTC1 0x04
+# define DAC2OUTSEL_CRTC2 0x08
+# define DAC2OUTSEL_TVE 0x0C
+# define DAC2OUTSEL_MASK 0x0C
+# define PANOUTSEL_DIS 0x00
+# define PANOUTSEL_CRTC1 0x20
+# define PANOUTSEL_CRTC2RGB 0x40
+# define PANOUTSEL_CRTC2656 0x60
+# define PANOUTSEL_MASK 0x60
+
+#define XSYNCCTRL 0x8B
+# define DAC1HSOFF 0x01
+# define DAC1VSOFF 0x02
+# define DAC1HSPOL 0x04
+# define DAC1VSPOL 0x08
+# define DAC2HSOFF 0x10
+# define DAC2VSOFF 0x20
+# define DAC2HSPOL 0x40
+# define DAC2VSPOL 0x80
+
+#define XPWRCTRL 0xA0
+# define DAC2PDN 0x01
+# define VIDPLLPDN 0x02
+# define PANPDN 0x04
+# define RFIFOPDN 0x08
+# define CFIFOPDN 0x10
+
+#endif
+