diff options
Diffstat (limited to 'Source/DirectFB/gfxdrivers/matrox')
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/Makefile.am | 47 | ||||
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/Makefile.in | 618 | ||||
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/matrox.c | 2930 | ||||
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/matrox.h | 157 | ||||
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/matrox_3d.c | 627 | ||||
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/matrox_3d.h | 36 | ||||
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/matrox_bes.c | 783 | ||||
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/matrox_crtc2.c | 751 | ||||
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/matrox_maven.c | 785 | ||||
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/matrox_maven.h | 64 | ||||
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/matrox_screen_crtc2.c | 279 | ||||
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/matrox_spic.c | 314 | ||||
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/matrox_state.c | 810 | ||||
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/matrox_state.h | 70 | ||||
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/mmio.h | 118 | ||||
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/regs.h | 454 |
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), ® }, + { 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 + |