summaryrefslogtreecommitdiff
path: root/Source/DirectFB/gfxdrivers/sh772x
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/gfxdrivers/sh772x')
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/Makefile.am80
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/Makefile.in726
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/Makefile.kernel61
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/README.sh7722172
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/directfbrc.sh772210
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/directfbrc.sh772310
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/kernel-module/Makefile3
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/kernel-module/sh7722.c1192
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/kernel-module/sh7722.h21
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/kernel-module/sh7723.c566
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/kernel-module/sh7723.h21
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/kernel-module/sh772x_driver.c82
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/kernel-module/sh772x_gfx.h105
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722.c490
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722.h131
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_blt.c2013
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_blt.h214
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_jpeg.c395
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_jpeglib.c1654
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_jpeglib.h47
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_jpegtool.c142
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_layer.c529
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_layer.h11
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_lcd.c172
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_lcd.h17
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_multi.c412
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_multi.h11
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_regs.h624
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_screen.c85
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_screen.h9
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_types.h136
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7723_blt.c890
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7723_blt.h239
33 files changed, 11270 insertions, 0 deletions
diff --git a/Source/DirectFB/gfxdrivers/sh772x/Makefile.am b/Source/DirectFB/gfxdrivers/sh772x/Makefile.am
new file mode 100755
index 0000000..462aa03
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/Makefile.am
@@ -0,0 +1,80 @@
+## Makefile.am for DirectFB/src/core/gfxcards/sh7722
+
+EXTRA_DIST = \
+ directfbrc.sh7722 \
+ directfbrc.sh7723 \
+ Makefile.kernel \
+ README.sh7722 \
+ kernel-module/sh772x_driver.c \
+ kernel-module/sh772x_gfx.h \
+ kernel-module/sh7722.c \
+ kernel-module/sh7722.h \
+ kernel-module/sh7723.c \
+ kernel-module/sh7723.h \
+ kernel-module/Makefile
+
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/systems \
+ -I$(srcdir)/kernel-module
+
+
+lib_LTLIBRARIES = libsh7722_jpeg.la
+
+libsh7722_jpeg_la_SOURCES = \
+ sh7722_jpeglib.c \
+ sh7722_jpeglib.h
+
+
+bin_PROGRAMS = sh7722_jpegtool
+
+sh7722_jpegtool_SOURCES = \
+ sh7722_jpegtool.c
+
+sh7722_jpegtool_LDADD = \
+ $(top_builddir)/src/libdirectfb.la \
+ libsh7722_jpeg.la
+
+
+sh7722_LTLIBRARIES = libdirectfb_sh7722.la
+
+if BUILD_STATIC
+sh7722_DATA = $(sh7722_LTLIBRARIES:.la=.o)
+endif
+
+sh7722dir = $(MODULEDIR)/gfxdrivers
+
+libdirectfb_sh7722_la_SOURCES = \
+ sh7722.c \
+ sh7722.h \
+ sh7722_blt.c \
+ sh7722_blt.h \
+ sh7723_blt.c \
+ sh7723_blt.h \
+ sh7722_jpeg.c \
+ sh7722_layer.c \
+ sh7722_layer.h \
+ sh7722_lcd.c \
+ sh7722_lcd.h \
+ sh7722_multi.c \
+ sh7722_multi.h \
+ sh7722_regs.h \
+ sh7722_screen.c \
+ sh7722_screen.h \
+ sh7722_types.h
+
+libdirectfb_sh7722_la_LDFLAGS = \
+ -module \
+ -avoid-version \
+ $(DFB_LDFLAGS)
+
+libdirectfb_sh7722_la_LIBADD = \
+ $(top_builddir)/src/libdirectfb.la \
+ libsh7722_jpeg.la
+
+
+include $(top_srcdir)/rules/libobject.make
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/Makefile.in b/Source/DirectFB/gfxdrivers/sh772x/Makefile.in
new file mode 100755
index 0000000..a2fcc20
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/Makefile.in
@@ -0,0 +1,726 @@
+# 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@
+bin_PROGRAMS = sh7722_jpegtool$(EXEEXT)
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/rules/libobject.make
+subdir = gfxdrivers/sh772x
+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)$(libdir)" "$(DESTDIR)$(sh7722dir)" \
+ "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sh7722dir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+sh7722LTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES) $(sh7722_LTLIBRARIES)
+libdirectfb_sh7722_la_DEPENDENCIES = \
+ $(top_builddir)/src/libdirectfb.la libsh7722_jpeg.la
+am_libdirectfb_sh7722_la_OBJECTS = sh7722.lo sh7722_blt.lo \
+ sh7723_blt.lo sh7722_jpeg.lo sh7722_layer.lo sh7722_lcd.lo \
+ sh7722_multi.lo sh7722_screen.lo
+libdirectfb_sh7722_la_OBJECTS = $(am_libdirectfb_sh7722_la_OBJECTS)
+libdirectfb_sh7722_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libdirectfb_sh7722_la_LDFLAGS) $(LDFLAGS) -o $@
+libsh7722_jpeg_la_LIBADD =
+am_libsh7722_jpeg_la_OBJECTS = sh7722_jpeglib.lo
+libsh7722_jpeg_la_OBJECTS = $(am_libsh7722_jpeg_la_OBJECTS)
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_sh7722_jpegtool_OBJECTS = sh7722_jpegtool.$(OBJEXT)
+sh7722_jpegtool_OBJECTS = $(am_sh7722_jpegtool_OBJECTS)
+sh7722_jpegtool_DEPENDENCIES = $(top_builddir)/src/libdirectfb.la \
+ libsh7722_jpeg.la
+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_sh7722_la_SOURCES) \
+ $(libsh7722_jpeg_la_SOURCES) $(sh7722_jpegtool_SOURCES)
+DIST_SOURCES = $(libdirectfb_sh7722_la_SOURCES) \
+ $(libsh7722_jpeg_la_SOURCES) $(sh7722_jpegtool_SOURCES)
+sh7722DATA_INSTALL = $(INSTALL_DATA)
+DATA = $(sh7722_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@
+EXTRA_DIST = \
+ directfbrc.sh7722 \
+ directfbrc.sh7723 \
+ Makefile.kernel \
+ README.sh7722 \
+ kernel-module/sh772x_driver.c \
+ kernel-module/sh772x_gfx.h \
+ kernel-module/sh7722.c \
+ kernel-module/sh7722.h \
+ kernel-module/sh7723.c \
+ kernel-module/sh7723.h \
+ kernel-module/Makefile
+
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/systems \
+ -I$(srcdir)/kernel-module
+
+lib_LTLIBRARIES = libsh7722_jpeg.la
+libsh7722_jpeg_la_SOURCES = \
+ sh7722_jpeglib.c \
+ sh7722_jpeglib.h
+
+sh7722_jpegtool_SOURCES = \
+ sh7722_jpegtool.c
+
+sh7722_jpegtool_LDADD = \
+ $(top_builddir)/src/libdirectfb.la \
+ libsh7722_jpeg.la
+
+sh7722_LTLIBRARIES = libdirectfb_sh7722.la
+@BUILD_STATIC_TRUE@sh7722_DATA = $(sh7722_LTLIBRARIES:.la=.o)
+sh7722dir = $(MODULEDIR)/gfxdrivers
+libdirectfb_sh7722_la_SOURCES = \
+ sh7722.c \
+ sh7722.h \
+ sh7722_blt.c \
+ sh7722_blt.h \
+ sh7723_blt.c \
+ sh7723_blt.h \
+ sh7722_jpeg.c \
+ sh7722_layer.c \
+ sh7722_layer.h \
+ sh7722_lcd.c \
+ sh7722_lcd.h \
+ sh7722_multi.c \
+ sh7722_multi.h \
+ sh7722_regs.h \
+ sh7722_screen.c \
+ sh7722_screen.h \
+ sh7722_types.h
+
+libdirectfb_sh7722_la_LDFLAGS = \
+ -module \
+ -avoid-version \
+ $(DFB_LDFLAGS)
+
+libdirectfb_sh7722_la_LIBADD = \
+ $(top_builddir)/src/libdirectfb.la \
+ libsh7722_jpeg.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/sh772x/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu gfxdrivers/sh772x/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-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_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
+install-sh7722LTLIBRARIES: $(sh7722_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(sh7722dir)" || $(MKDIR_P) "$(DESTDIR)$(sh7722dir)"
+ @list='$(sh7722_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sh7722LTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(sh7722dir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sh7722LTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(sh7722dir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-sh7722LTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sh7722_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(sh7722dir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(sh7722dir)/$$p"; \
+ done
+
+clean-sh7722LTLIBRARIES:
+ -test -z "$(sh7722_LTLIBRARIES)" || rm -f $(sh7722_LTLIBRARIES)
+ @list='$(sh7722_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_sh7722.la: $(libdirectfb_sh7722_la_OBJECTS) $(libdirectfb_sh7722_la_DEPENDENCIES)
+ $(libdirectfb_sh7722_la_LINK) -rpath $(sh7722dir) $(libdirectfb_sh7722_la_OBJECTS) $(libdirectfb_sh7722_la_LIBADD) $(LIBS)
+libsh7722_jpeg.la: $(libsh7722_jpeg_la_OBJECTS) $(libsh7722_jpeg_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libsh7722_jpeg_la_OBJECTS) $(libsh7722_jpeg_la_LIBADD) $(LIBS)
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+sh7722_jpegtool$(EXEEXT): $(sh7722_jpegtool_OBJECTS) $(sh7722_jpegtool_DEPENDENCIES)
+ @rm -f sh7722_jpegtool$(EXEEXT)
+ $(LINK) $(sh7722_jpegtool_OBJECTS) $(sh7722_jpegtool_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh7722.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh7722_blt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh7722_jpeg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh7722_jpeglib.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh7722_jpegtool.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh7722_layer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh7722_lcd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh7722_multi.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh7722_screen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh7723_blt.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-sh7722DATA: $(sh7722_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(sh7722dir)" || $(MKDIR_P) "$(DESTDIR)$(sh7722dir)"
+ @list='$(sh7722_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(sh7722DATA_INSTALL) '$$d$$p' '$(DESTDIR)$(sh7722dir)/$$f'"; \
+ $(sh7722DATA_INSTALL) "$$d$$p" "$(DESTDIR)$(sh7722dir)/$$f"; \
+ done
+
+uninstall-sh7722DATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sh7722_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(sh7722dir)/$$f'"; \
+ rm -f "$(DESTDIR)$(sh7722dir)/$$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) $(PROGRAMS) $(DATA)
+install-binPROGRAMS: install-libLTLIBRARIES
+
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(sh7722dir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sh7722dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
+ clean-libtool clean-sh7722LTLIBRARIES 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-sh7722DATA install-sh7722LTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-binPROGRAMS install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
+ uninstall-sh7722DATA uninstall-sh7722LTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libLTLIBRARIES clean-libtool \
+ clean-sh7722LTLIBRARIES ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binPROGRAMS install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am \
+ install-libLTLIBRARIES install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-sh7722DATA \
+ install-sh7722LTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-libLTLIBRARIES uninstall-sh7722DATA \
+ uninstall-sh7722LTLIBRARIES
+
+%.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/sh772x/Makefile.kernel b/Source/DirectFB/gfxdrivers/sh772x/Makefile.kernel
new file mode 100755
index 0000000..8b6be07
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/Makefile.kernel
@@ -0,0 +1,61 @@
+KERNEL_VERSION ?= $(shell uname -r)
+KERNEL_MODLIB ?= /lib/modules/$(KERNEL_VERSION)
+KERNEL_BUILD ?= $(SYSROOT)$(KERNEL_MODLIB)/build
+KERNEL_SOURCE ?= $(SYSROOT)$(KERNEL_MODLIB)/source
+
+ifeq ($(shell test -L $(KERNEL_BUILD) && echo yes),yes)
+ KERNEL_BUILD := $(SYSROOT)$(shell readlink $(KERNEL_BUILD))
+endif
+
+ifeq ($(shell test -L $(KERNEL_SOURCE) && echo yes),yes)
+ KERNEL_SOURCE := $(SYSROOT)$(shell readlink $(KERNEL_SOURCE))
+endif
+
+K_VERSION := $(shell echo $(KERNEL_VERSION) | cut -d . -f 1)
+K_PATCHLEVEL := $(shell echo $(KERNEL_VERSION) | cut -d . -f 2)
+K_SUBLEVEL := $(shell echo $(KERNEL_VERSION) | cut -d . -f 3 | cut -d '-' -f 1)
+
+
+DESTDIR ?= $(SYSROOT)
+
+
+ifeq ($(DEBUG_2DG),yes)
+ CPPFLAGS += -DSH7722GFX_DEBUG_2DG
+endif
+
+ifeq ($(DEBUG_JPU),yes)
+ CPPFLAGS += -DSH7722GFX_DEBUG_JPU
+endif
+
+ifeq ($(shell test -e $(KERNEL_BUILD)/include/linux/autoconf.h && echo yes),yes)
+ AUTOCONF_H = -include $(KERNEL_BUILD)/include/linux/autoconf.h
+endif
+
+ifeq ($(shell test -e $(KERNEL_BUILD)/include/linux/config.h && echo yes),yes)
+ CPPFLAGS += -DHAVE_LINUX_CONFIG_H
+endif
+
+check-version = $(shell expr \( $(K_VERSION) \* 65536 + $(K_PATCHLEVEL) \* 256 + $(K_SUBLEVEL) \) \>= \( $(1) \* 65536 + $(2) \* 256 + $(3) \))
+
+.PHONY: all install clean
+
+all:
+ifeq ($(call check-version,2,6,24),1)
+ $(MAKE) -C $(KERNEL_BUILD) \
+ KCPPFLAGS="$(CPPFLAGS) -I`pwd`/kernel-module" \
+ SUBDIRS="`pwd`/kernel-module" modules
+else
+ $(MAKE) -C $(KERNEL_BUILD) \
+ CPPFLAGS="$(CPPFLAGS) -D__KERNEL__ -I`pwd`/kernel-module -I$(KERNEL_BUILD)/include -I$(KERNEL_SOURCE)/include $(AUTOCONF_H)" \
+ SUBDIRS="`pwd`/kernel-module" modules
+endif
+
+clean:
+ rm -rf kernel-module/*.*o kernel-module/.*.*o* kernel-module/*.mod.c kernel-module/.tmp_versions
+
+install: all
+ install -v -m 0755 -d $(DESTDIR)/lib/modules/$(KERNEL_VERSION)/renesas
+ install -v -m 0644 kernel-module/sh772x_gfx.ko $(DESTDIR)/lib/modules/$(KERNEL_VERSION)/renesas/
+
+
+.PHONY: all clean
diff --git a/Source/DirectFB/gfxdrivers/sh772x/README.sh7722 b/Source/DirectFB/gfxdrivers/sh772x/README.sh7722
new file mode 100755
index 0000000..45bbf87
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/README.sh7722
@@ -0,0 +1,172 @@
+Renesas SH7722 graphics driver
+==============================
+
+This driver supports the SH7722 SoC from Renesas Solutions Corp. controlling
+- LCDC (LCD Controller) for display
+- BEU (Blit Engine Unit) for blending of planes
+- TDG (2D Graphics) for accelerated operations
+
+It's using a kernel device called sh7722gfx which mainly does interrupt handling.
+
+The 2D Graphics unit supports display lists in RAM and reads them via DMA. These
+lists consist of double word entries, first word designates a register, second
+word contains the data to write. Once a list has been completely processed, the
+hardware generates an interrupt to start the next list.
+
+The kernel module allocates a ring buffer for usage as a display list. The user
+space prepares a block of commands and puts it into the ring buffer. If the hardware
+is idle, it's started directly from user space. When a DMA completion interrupt
+is received, the next block of commands is started from kernel space. If the
+hardware is still running the previous block, new commands are appended to the
+next one. The driver is designed to run without any locking or system calls. Only
+a few interrupts happen over time depending on the operations. The hardware is not
+getting idle, while commands are being sent to keep it busy. There's just a minimal
+gap which is the interrupt handler setting the new start address and kicking the
+hardware again.
+
+To build the kernel module use "make -f Makefile.kernel". You might want to set
+the variables KERNEL_SOURCE, KERNEL_BUILD (if != KERNEL_SOURCE), KERNEL_VERSION
+and DESTDIR.
+
+To run the driver you need the DevMem system module using the directfbrc.sh7722
+file (renamed to directfbrc in $prefix/etc).
+
+
+Performance (as of 2007-09-21, multi app, 127.79 BogoMIPS)
+----------------------------------------------------------
+
+Only 14% CPU load with df_andi running 800x480 at 28.1 fps :)
+
+Benchmarking with 256x256 in 16bit mode... (16bit)
+ CPU load
+Anti-aliased Text 3.020 secs ( 41.721 KChars/sec) [100%]
+Anti-aliased Text (blend) 3.328 secs ( 10.817 KChars/sec) [100%]
+Fill Rectangle 5.549 secs (* 69.681 MPixel/sec) [ 3%]
+Fill Rectangle (blend) 11.873 secs (* 22.079 MPixel/sec) [ 1%]
+Fill Rectangles [10] 9.384 secs (* 69.838 MPixel/sec) [ 0%]
+Fill Rectangles [10] (blend) 14.836 secs (* 22.086 MPixel/sec) [ 0%]
+Fill Triangles 3.024 secs (+ 50.929 MPixel/sec) [ 40%]
+Fill Triangles (blend) 3.064 secs (+ 20.319 MPixel/sec) [ 8%]
+Draw Rectangle 3.284 secs (* 6.942 KRects/sec) [ 26%]
+Draw Rectangle (blend) 3.302 secs (* 6.268 KRects/sec) [ 25%]
+Draw Lines [10] 3.238 secs (* 28.103 KLines/sec) [ 20%]
+Draw Lines [10] (blend) 3.198 secs (* 27.829 KLines/sec) [ 19%]
+Fill Spans 3.092 secs (* 61.466 MPixel/sec) [ 33%]
+Fill Spans (blend) 3.094 secs (* 21.181 MPixel/sec) [ 11%]
+Blit 10.436 secs (* 30.143 MPixel/sec) [ 2%]
+Blit colorkeyed 9.333 secs (* 32.301 MPixel/sec) [ 2%]
+Blit destination colorkeyed 3.763 secs ( 6.966 MPixel/sec) [ 99%]
+Blit with format conversion 13.369 secs (* 22.549 MPixel/sec) [ 1%]
+Blit with colorizing 4.419 secs ( 2.966 MPixel/sec) [100%]
+Blit from 32bit (blend) 21.973 secs (* 13.123 MPixel/sec) [ 1%]
+Blit from 32bit (blend) with colorizing 5.129 secs ( 1.277 MPixel/sec) [100%]
+Stretch Blit 10.271 secs (* 33.463 MPixel/sec) [ 3%]
+Stretch Blit colorkeyed 7.895 secs (* 35.159 MPixel/sec) [ 3%]
+
+(*) SH7722/BLT: 940 starts, 940 done, 940 interrupts, 43 wait_idle, 780 wait_next, 89 idle
+(*) SH7722/BLT: 24700744 words, 26277 words/start, 277536 words/idle, 10 starts/idle
+
+* = accelerated
++ = half way accelerated
+
+
+Performance (as of 2007-09-25, multi app, 127.79 BogoMIPS)
+----------------------------------------------------------
+
+Only 13% CPU load with df_andi running 800x480 at 28.8 fps :)
+Only 46% CPU load with ClanBomber2 running 800x600 at 48 fps :)
+
+Benchmarking with 256x256 in 16bit mode... (16bit)
+ CPU load
+Anti-aliased Text 3.057 secs (* 98.920 KChars/sec) [ 47%] !
+Anti-aliased Text (blend) 3.298 secs ( 10.915 KChars/sec) [100%]
+Fill Rectangle 5.732 secs (* 69.743 MPixel/sec) [ 3%]
+Fill Rectangle (blend) 11.571 secs (* 22.088 MPixel/sec) [ 1%]
+Fill Rectangles [10] 9.384 secs (* 69.838 MPixel/sec) [ 0%]
+Fill Rectangles [10] (blend) 14.836 secs (* 22.086 MPixel/sec) [ 0%]
+Fill Triangles 4.176 secs (* 61.989 MPixel/sec) [ 6%] !
+Fill Triangles (blend) 8.132 secs (* 21.759 MPixel/sec) [ 2%] !
+Draw Rectangle 3.216 secs (* 6.965 KRects/sec) [ 26%]
+Draw Rectangle (blend) 3.290 secs (* 6.322 KRects/sec) [ 22%]
+Draw Lines [10] 3.216 secs (* 28.296 KLines/sec) [ 14%]
+Draw Lines [10] (blend) 3.196 secs (* 28.160 KLines/sec) [ 14%]
+Fill Spans 3.086 secs (* 61.586 MPixel/sec) [ 25%]
+Fill Spans (blend) 3.092 secs (* 21.195 MPixel/sec) [ 7%]
+Blit 8.692 secs (* 30.159 MPixel/sec) [ 2%]
+Blit 180 4.783 secs (* 30.144 MPixel/sec) [ 2%] !
+Blit colorkeyed 11.965 secs (* 32.316 MPixel/sec) [ 2%]
+Blit destination colorkeyed 3.795 secs ( 6.907 MPixel/sec) [ 99%]
+Blit with format conversion 9.039 secs (* 22.476 MPixel/sec) [ 1%]
+Blit with colorizing 4.414 secs ( 2.969 MPixel/sec) [100%]
+Blit from 32bit (blend) 23.375 secs (* 13.177 MPixel/sec) [ 1%]
+Blit from 32bit (blend) with colorizing 5.137 secs ( 1.275 MPixel/sec) [100%]
+Stretch Blit 8.976 secs (* 33.495 MPixel/sec) [ 2%]
+Stretch Blit colorkeyed 9.728 secs (* 35.226 MPixel/sec) [ 2%]
+
+(*) SH7722/BLT: 521 starts, 521 done, 521 interrupts, 45 wait_idle, 363 wait_next, 90 idle
+(*) SH7722/BLT: 11511104 words, 22094 words/start, 127901 words/idle, 5 starts/idle
+
+* = accelerated
+! = updated
+
+
+Statistics
+----------
+
+The statistics at the end are more valuable when looking at one case at a time:
+
+Fill Rectangle 5.834 secs (* 69.647 MPixel/sec) [ 4%]
+
+(*) SH7722/BLT: 16 starts, 16 done, 16 interrupts, 4 wait_idle, 2 wait_next, 11 idle
+(*) SH7722/BLT: 74840 words, 4677 words/start, 6803 words/idle, 1 starts/idle
+
+This means that while the FillRectangle() benchmark was running, the hardware
+didn't get idle, which is obvious when running the benchmark for just 10 ms:
+
+Fill Rectangle 0.191 secs (* 68.624 MPixel/sec) [ 10%]
+
+(*) SH7722/BLT: 13 starts, 13 done, 13 interrupts, 4 wait_idle, 0 wait_next, 11 idle
+(*) SH7722/BLT: 2840 words, 218 words/start, 258 words/idle, 1 starts/idle
+
+See? The same number of times becoming idle, but a few less interrupts. Don't
+worry about the 191 ms the benchmark needed to complete, after 10 ms of stuffing
+the display list, we need to wait until the hardware is done before measuring
+the time it took and calculating the result.
+
+Here's FillSpans() which as opposed to FillRectangle() does a lot of small commands:
+
+Fill Spans 3.028 secs (* 61.467 MPixel/sec) [ 34%]
+
+(*) SH7722/BLT: 245 starts, 245 done, 245 interrupts, 3 wait_idle, 185 wait_next, 22 idle
+(*) SH7722/BLT: 5828128 words, 23788 words/start, 264914 words/idle, 11 starts/idle
+
+
+Example kernel log (debug mode)
+-------------------------------
+
+0.549.014 - sh7722_reset : Resetting hardware...
+0.549.046 - sh7722_reset : Initializing shared area...
+0.549.748 - sh7722_reset : Clearing interrupts...
+0.549.770 - sh7722_reset : Ready ( idle, hw 0- 0, next 0- 0, invalid, HC 0000000, INT 000000)
+0.568.700 - sh7722_wait : Waiting..... (running, hw 0- 54, next 56- 56, invalid, HC 1010111, INT 000000)
+0.573.339 - sh7722_tdg_irq : -Interrupt (running, hw 0- 54, next 56- 56, invalid, HC 0000000, INT 100100)
+0.573.397 - sh7722_tdg_irq : '-> Idle. (running, hw 0- 54, next 56- 56, invalid, HC 0000000, INT 000000)
+0.573.480 - sh7722_wait : ........done ( idle, hw 0- 54, next 56- 56, invalid, HC 0000000, INT 000000)
+0.583.575 - sh7722_wait : Waiting..... (running, hw 56- 78, next 80- 80, invalid, HC 1010111, INT 000000)
+0.588.414 - sh7722_tdg_irq : -Interrupt (running, hw 56- 78, next 80- 80, invalid, HC 0000000, INT 100100)
+0.588.470 - sh7722_tdg_irq : '-> Idle. (running, hw 56- 78, next 80- 80, invalid, HC 0000000, INT 000000)
+0.588.544 - sh7722_wait : ........done ( idle, hw 56- 78, next 80- 80, invalid, HC 0000000, INT 000000)
+0.601.336 - sh7722_tdg_irq : -Interrupt (running, hw 80- 102, next 104- 104, invalid, HC 0000000, INT 100100)
+0.601.420 - sh7722_tdg_irq : '-> Idle. (running, hw 80- 102, next 104- 104, invalid, HC 0000000, INT 000000)
+0.700.117 - sh7722_tdg_irq : -Interrupt (running, hw 104- 124, next 128- 128, invalid, HC 0000000, INT 100100)
+0.700.205 - sh7722_tdg_irq : '-> Idle. (running, hw 104- 124, next 128- 128, invalid, HC 0000000, INT 000000)
+3.115.419 - sh7722_tdg_irq : -Interrupt (running, hw 128- 220, next 224- 224, invalid, HC 0000000, INT 100100)
+3.115.506 - sh7722_tdg_irq : '-> Idle. (running, hw 128- 220, next 224- 224, invalid, HC 0000000, INT 000000)
+3.151.700 - sh7722_tdg_irq : -Interrupt (running, hw 224- 324, next 328- 328, invalid, HC 0000000, INT 100100)
+3.151.788 - sh7722_tdg_irq : '-> Idle. (running, hw 224- 324, next 328- 328, invalid, HC 0000000, INT 000000)
+3.159.160 - sh7722_wait : Waiting..... (running, hw 328- 444, next 448-12994, valid, HC 1010111, INT 000100)
+3.161.783 - sh7722_tdg_irq : -Interrupt (running, hw 328- 444, next 448-12994, valid, HC 0000000, INT 100100)
+3.161.839 - sh7722_tdg_irq : '-> Start! (running, hw 448-12994, next 12996-12996, invalid, HC 0000000, INT 000000)
+4.316.367 - sh7722_tdg_irq : -Interrupt (running, hw 448-12994, next 12996-12996, invalid, HC 0000000, INT 100100)
+4.316.434 - sh7722_tdg_irq : '-> Idle. (running, hw 448-12994, next 12996-12996, invalid, HC 0000000, INT 000000)
+4.316.505 - sh7722_wait : ........done ( idle, hw 448-12994, next 12996-12996, invalid, HC 0000000, INT 000000)
diff --git a/Source/DirectFB/gfxdrivers/sh772x/directfbrc.sh7722 b/Source/DirectFB/gfxdrivers/sh772x/directfbrc.sh7722
new file mode 100755
index 0000000..7417294
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/directfbrc.sh7722
@@ -0,0 +1,10 @@
+
+system = devmem
+
+video-phys = f800000 # Requires 'mem=120M' kernel option!!!!!
+video-length = 8388608 # 8MB of physically contiguous memory for acceleration
+
+mmio-phys = fd000000 # Start of 2DG register space
+mmio-length = 65536 # Size of register space
+
+accelerator = 11591 # 0x2D47 (2DG)
diff --git a/Source/DirectFB/gfxdrivers/sh772x/directfbrc.sh7723 b/Source/DirectFB/gfxdrivers/sh772x/directfbrc.sh7723
new file mode 100755
index 0000000..b8cb009
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/directfbrc.sh7723
@@ -0,0 +1,10 @@
+
+system = devmem
+
+video-phys = f800000 # Requires 'mem=120M' kernel option!!!!!
+video-length = 8388608 # 8MB of physically contiguous memory for acceleration
+
+mmio-phys = a4680000 # Start of 2DG register space
+mmio-length = 65536 # Size of register space
+
+accelerator = 11591 # 0x2D47 (2DG)
diff --git a/Source/DirectFB/gfxdrivers/sh772x/kernel-module/Makefile b/Source/DirectFB/gfxdrivers/sh772x/kernel-module/Makefile
new file mode 100755
index 0000000..d054dd5
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/kernel-module/Makefile
@@ -0,0 +1,3 @@
+obj-m += sh772x_gfx.o
+
+sh772x_gfx-y += sh772x_driver.o sh7722.o sh7723.o
diff --git a/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7722.c b/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7722.c
new file mode 100755
index 0000000..981cf69
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7722.c
@@ -0,0 +1,1192 @@
+/*
+ * SH7722 Graphics Device
+ *
+ * Copyright (C) 2006-2008 IGEL Co.,Ltd
+ *
+ * Written by Denis Oliver Kropp <dok@directfb.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License v2
+ * as published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/ioctl.h>
+#include <linux/miscdevice.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <sh772x_gfx.h>
+
+
+//#define SH7722GFX_DEBUG_2DG
+//#define SH7722GFX_DEBUG_JPU
+//#define SH7722GFX_IRQ_POLLER
+
+
+/**********************************************************************************************************************/
+
+#ifndef SH7722_BEU_IRQ
+#define SH7722_BEU_IRQ 53
+#endif
+
+#ifndef SH7722_VEU_IRQ
+#define SH7722_VEU_IRQ 54
+#endif
+
+#ifndef SH7722_JPU_IRQ
+#define SH7722_JPU_IRQ 27
+#endif
+
+#ifndef SH7722_TDG_IRQ
+#define SH7722_TDG_IRQ 109
+#endif
+
+/**********************************************************************************************************************/
+
+#define ENGINE_REG_TOP 0xFD000000
+#define SH7722_VEU_BASE 0xFE920000
+#define SH7722_BEU_BASE 0xFE930000
+#define SH7722_JPU_BASE 0xFEA00000
+
+#define BEM_REG(x) (*(volatile u32*)((x)+ENGINE_REG_TOP))
+#define VEU_REG(x) (*(volatile u32*)((x)+SH7722_VEU_BASE))
+#define BEU_REG(x) (*(volatile u32*)((x)+SH7722_BEU_BASE))
+#define JPU_REG(x) (*(volatile u32*)((x)+SH7722_JPU_BASE))
+
+#define BEM_HC_STATUS BEM_REG(0x00000)
+#define BEM_HC_RESET BEM_REG(0x00004)
+#define BEM_HC_CLOCK BEM_REG(0x00008)
+#define BEM_HC_INT_STATUS BEM_REG(0x00020)
+#define BEM_HC_INT_MASK BEM_REG(0x00024)
+#define BEM_HC_INT_CLEAR BEM_REG(0x00028)
+#define BEM_HC_CACHE_FLUSH BEM_REG(0x0002C)
+#define BEM_HC_DMA_ADR BEM_REG(0x00040)
+#define BEM_HC_DMA_START BEM_REG(0x00044)
+#define BEM_HC_DMA_STOP BEM_REG(0x00048)
+#define BEM_PE_CACHE BEM_REG(0x010B0)
+
+#define BEVTR BEU_REG(0x0018C)
+
+#define JPU_JCCMD JPU_REG(0x00004)
+#define JPU_JCSTS JPU_REG(0x00008)
+#define JPU_JINTE JPU_REG(0x00038)
+#define JPU_JINTS JPU_REG(0x0003C)
+#define JPU_JCDERR JPU_REG(0x00040)
+#define JPU_JCRST JPU_REG(0x00044)
+#define JPU_JIFDDVSZ JPU_REG(0x000B4)
+#define JPU_JIFDDHSZ JPU_REG(0x000B8)
+#define JPU_JIFDDYA1 JPU_REG(0x000BC)
+#define JPU_JIFDDCA1 JPU_REG(0x000C0)
+#define JPU_JIFDDYA2 JPU_REG(0x000C4)
+#define JPU_JIFDDCA2 JPU_REG(0x000C8)
+#define JPU_JIFESYA1 JPU_REG(0x00074)
+#define JPU_JIFESCA1 JPU_REG(0x00078)
+#define JPU_JIFESYA2 JPU_REG(0x0007C)
+#define JPU_JIFESCA2 JPU_REG(0x00080)
+#define JPU_JIFEDA1 JPU_REG(0x00090)
+#define JPU_JIFEDA2 JPU_REG(0x00094)
+
+#define VEU_VESTR VEU_REG(0x00000)
+#define VEU_VESWR VEU_REG(0x00010)
+#define VEU_VESSR VEU_REG(0x00014)
+#define VEU_VSAYR VEU_REG(0x00018)
+#define VEU_VSACR VEU_REG(0x0001c)
+#define VEU_VDAYR VEU_REG(0x00034)
+#define VEU_VDACR VEU_REG(0x00038)
+#define VEU_VTRCR VEU_REG(0x00050)
+#define VEU_VRFSR VEU_REG(0x00058)
+#define VEU_VEVTR VEU_REG(0x000A4)
+#define VEU_VSTAR VEU_REG(0x000b0)
+
+#define JINTS_MASK 0x00007C68
+#define JINTS_INS3_HEADER 0x00000008
+#define JINTS_INS5_ERROR 0x00000020
+#define JINTS_INS6_DONE 0x00000040
+#define JINTS_INS10_XFER_DONE 0x00000400
+#define JINTS_INS11_LINEBUF0 0x00000800
+#define JINTS_INS12_LINEBUF1 0x00001000
+#define JINTS_INS13_LOADED 0x00002000
+#define JINTS_INS14_RELOAD 0x00004000
+
+#define JCCMD_START 0x00000001
+#define JCCMD_RESTART 0x00000002
+#define JCCMD_END 0x00000004
+#define JCCMD_RESET 0x00000080
+#define JCCMD_LCMD2 0x00000100
+#define JCCMD_LCMD1 0x00000200
+#define JCCMD_READ_RESTART 0x00000400
+#define JCCMD_WRITE_RESTART 0x00000800
+
+#define VTRCR_CHRR 0x0000C000
+
+/**********************************************************************************************************************/
+
+#ifdef SH7722GFX_DEBUG_2DG
+#define QPRINT(x...) do { \
+ char buf[128]; \
+ struct timeval tv; \
+ do_gettimeofday( &tv ); \
+ snprintf( buf, sizeof(buf), x ); \
+ printk( KERN_DEBUG "%ld.%03ld.%03ld - %-17s: %s\n", \
+ tv.tv_sec - base_time.tv_sec, \
+ tv.tv_usec / 1000, tv.tv_usec % 1000, __FUNCTION__, buf ); \
+} while (0)
+#else
+#define QPRINT(x...) do {} while (0)
+#endif
+
+#define QDUMP(msg) QPRINT( "%-12s (%s, hw %5d-%5d, next %5d-%5d, %svalid, " \
+ "HC %07x, INT %06x)", msg, \
+ shared->hw_running ? "running" : " idle", \
+ shared->hw_start, \
+ shared->hw_end, \
+ shared->next_start, \
+ shared->next_end, \
+ shared->next_valid ? " " : "in", \
+ BEM_HC_STATUS, BEM_HC_INT_STATUS );
+
+/**********************************************************************************************************************/
+
+#ifdef SH7722GFX_DEBUG_JPU
+#define JPRINT(x...) do { \
+ char buf[128]; \
+ struct timeval tv; \
+ do_gettimeofday( &tv ); \
+ snprintf( buf, sizeof(buf), x ); \
+ printk( KERN_DEBUG "%ld.%03ld.%03ld - %-17s: %s\n", \
+ tv.tv_sec - base_time.tv_sec, \
+ tv.tv_usec / 1000, tv.tv_usec % 1000, __FUNCTION__, buf ); \
+} while (0)
+#else
+#define JPRINT(x...) do {} while (0)
+#endif
+
+/**********************************************************************************************************************/
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+# define USE_DMA_ALLOC_COHERENT
+#endif
+
+static DECLARE_WAIT_QUEUE_HEAD( wait_idle );
+static DECLARE_WAIT_QUEUE_HEAD( wait_next );
+
+static SH772xGfxSharedArea *shared;
+
+static struct timeval base_time;
+
+static struct page *shared_page;
+static unsigned int shared_order;
+
+#ifdef USE_DMA_ALLOC_COHERENT
+static unsigned long shared_phys;
+#endif
+
+#ifdef SH7722GFX_IRQ_POLLER
+static int stop_poller;
+#endif
+
+/**********************************************************************************************************************/
+
+static DECLARE_WAIT_QUEUE_HEAD( wait_jpeg_irq );
+static DECLARE_WAIT_QUEUE_HEAD( wait_jpeg_run );
+static DECLARE_WAIT_QUEUE_HEAD( wait_jpeg_lock );
+
+static struct page *jpeg_page;
+static unsigned int jpeg_order;
+static volatile void *jpeg_area;
+static u32 jpeg_buffers;
+static int jpeg_buffer;
+static u32 jpeg_error;
+static int jpeg_encode;
+static int jpeg_reading;
+static int jpeg_writing;
+static int jpeg_reading_line;
+static int jpeg_writing_line;
+static int jpeg_height;
+static int jpeg_inputheight;
+static unsigned long jpeg_phys;
+static int jpeg_end;
+static u32 jpeg_linebufs;
+static int jpeg_linebuf;
+static int jpeg_line;
+static int jpeg_line_veu; /* is the VEU done yet? */
+static int veu_linebuf;
+static int veu_running;
+
+static pid_t jpeg_locked;
+
+/**********************************************************************************************************************/
+
+static int
+sh7722_reset( SH772xGfxSharedArea *shared )
+{
+ int i;
+
+ do_gettimeofday( &base_time );
+
+ QPRINT( "Resetting hardware..." );
+
+ BEM_HC_CLOCK = 0;
+ for (i=0; i<30000; i++);
+ BEM_HC_CLOCK = 0x1111;
+
+ BEM_HC_RESET = 0x1111;
+ for (i=0; i<30000; i++);
+ BEM_HC_RESET = 0;
+
+
+ QPRINT( "Initializing shared area..." );
+
+ memset( (void*) shared, 0, sizeof(SH772xGfxSharedArea) );
+
+#ifdef USE_DMA_ALLOC_COHERENT
+ shared->buffer_phys = shared_phys;
+#else
+ shared->buffer_phys = virt_to_phys(&shared->buffer[0]);
+#endif
+ shared->jpeg_phys = virt_to_phys(jpeg_area);
+ shared->magic = SH7722GFX_SHARED_MAGIC;
+
+
+ QPRINT( "Clearing interrupts..." );
+
+ BEM_HC_INT_CLEAR = 0x111111;
+ BEM_HC_INT_MASK = 0x110011;
+
+ BEM_HC_CACHE_FLUSH = 0;
+
+ QDUMP( "Ready" );
+
+ return 0;
+}
+
+static int
+sh7722_wait_idle( SH772xGfxSharedArea *shared )
+{
+ int ret;
+
+ QDUMP( "Waiting....." );
+
+ /* Does not need to be atomic. There's a lock in user space,
+ * but anyhow, this is just for statistics. */
+ shared->num_wait_idle++;
+
+ ret = wait_event_interruptible_timeout( wait_idle, !shared->hw_running, 42*HZ );
+ if (!ret) {
+ printk( KERN_ERR "%s: TIMEOUT! (%srunning, hw %d-%d, next %d-%d - %svalid, "
+ "STATUS 0x%08x, INT_STATUS 0x%08x)\n",
+ __FUNCTION__,
+ shared->hw_running ? "" : "not ",
+ shared->hw_start,
+ shared->hw_end,
+ shared->next_start,
+ shared->next_end,
+ shared->next_valid ? "" : "not ",
+ BEM_HC_STATUS, BEM_HC_INT_STATUS );
+ }
+
+ QDUMP( "........done" );
+
+ return (ret > 0) ? 0 : (ret < 0) ? ret : -ETIMEDOUT;
+}
+
+static int
+sh7722_wait_next( SH772xGfxSharedArea *shared )
+{
+ int ret;
+
+ QDUMP( "Waiting....." );
+
+ /* Does not need to be atomic. There's a lock in user space,
+ * but anyhow, this is just for statistics. */
+ shared->num_wait_next++;
+
+ ret = wait_event_interruptible_timeout( wait_next, !shared->hw_running ||
+ shared->next_start == shared->next_end, 42*HZ );
+ if (!ret) {
+ printk( KERN_ERR "%s: TIMEOUT! (%srunning, hw %d-%d, next %d-%d - %svalid, "
+ "STATUS 0x%08x, INT_STATUS 0x%08x)\n",
+ __FUNCTION__,
+ shared->hw_running ? "" : "not ",
+ shared->hw_start,
+ shared->hw_end,
+ shared->next_start,
+ shared->next_end,
+ shared->next_valid ? "" : "not ",
+ BEM_HC_STATUS, BEM_HC_INT_STATUS );
+ }
+
+ QDUMP( "........done" );
+
+ return (ret > 0) ? 0 : (ret < 0) ? ret : -ETIMEDOUT;
+}
+
+/**********************************************************************************************************************/
+
+static int
+sh7722_wait_jpeg( SH772xGfxSharedArea *shared )
+{
+ int ret;
+
+ ret = wait_event_interruptible_timeout( wait_jpeg_irq, shared->jpeg_ints, HZ );
+ if (!ret) {
+ printk( KERN_ERR "%s: TIMEOUT! (status 0x%08x, ints 0x%08x)\n", __FUNCTION__, JPU_JCSTS, JPU_JINTS );
+ }
+
+ return (ret > 0) ? 0 : (ret < 0) ? ret : -ETIMEDOUT;
+}
+
+static int
+sh7722_run_jpeg( SH772xGfxSharedArea *shared,
+ SH7722JPEG *jpeg )
+{
+ int ret;
+ int encode = (jpeg->flags & SH7722_JPEG_FLAG_ENCODE) ? 1 : 0;
+ int convert = (jpeg->flags & SH7722_JPEG_FLAG_CONVERT) ? 1 : 0;
+
+ JPRINT( "run JPEG called %d", jpeg->state );
+
+ switch (jpeg->state) {
+ case SH7722_JPEG_START:
+ JPRINT( "START (buffers: %d, flags: 0x%x)", jpeg->buffers, jpeg->flags );
+
+ jpeg_line = 0;
+ jpeg_line_veu = 0;
+ jpeg_end = 0;
+ jpeg_error = 0;
+ jpeg_encode = encode;
+ jpeg_reading = 0;
+ jpeg_writing = 2;
+ jpeg_reading_line = encode && !convert;
+ jpeg_writing_line = !encode;
+ jpeg_height = jpeg->height;
+ jpeg_inputheight = jpeg->inputheight;
+ jpeg_phys = jpeg->phys;
+ jpeg_linebuf = 0;
+ jpeg_linebufs = 0;
+ jpeg_buffer = 0;
+ jpeg_buffers = jpeg->buffers;
+ veu_linebuf = 0;
+ veu_running = 0;
+
+ jpeg->state = SH7722_JPEG_RUN;
+ jpeg->error = 0;
+
+// if (!encode || !convert)
+ JPU_JCCMD = JCCMD_START;
+ break;
+
+ case SH7722_JPEG_RUN:
+ JPRINT( "RUN (buffers: %d)", jpeg->buffers );
+
+ /* Validate loaded buffers. */
+ jpeg_buffers |= jpeg->buffers;
+ break;
+
+ default:
+ printk( KERN_ERR "%s: INVALID STATE %d! (status 0x%08x, ints 0x%08x)\n",
+ __FUNCTION__, jpeg->state, JPU_JCSTS, JPU_JINTS );
+ return -EINVAL;
+ }
+
+ if (encode) {
+ if (convert) {
+ if (jpeg_linebufs != 3 && !veu_running) {
+ JPRINT( " '-> convert start (buffers: %d, veu linebuf: %d)", jpeg_buffers, veu_linebuf );
+
+ veu_running = 1;
+
+ VEU_VDAYR = veu_linebuf ? JPU_JIFESYA2 : JPU_JIFESYA1;
+ VEU_VDACR = veu_linebuf ? JPU_JIFESCA2 : JPU_JIFESCA1;
+ VEU_VESTR = 0x1;
+ }
+ }
+ if (jpeg_buffers && !jpeg_writing) {
+ JPRINT( " '-> write start (buffers: %d)", jpeg_buffers );
+
+ jpeg_writing = 1;
+ JPU_JCCMD = JCCMD_WRITE_RESTART;
+ }
+ }
+ else if (jpeg_buffers && !jpeg_reading) {
+ JPRINT( " '-> read start (buffers: %d)", jpeg_buffers );
+
+ jpeg_reading = 1;
+ JPU_JCCMD = JCCMD_READ_RESTART;
+ }
+
+ ret = wait_event_interruptible_timeout( wait_jpeg_run,
+ jpeg_end || jpeg_error ||
+ (jpeg_buffers != 3 && (jpeg->flags & SH7722_JPEG_FLAG_RELOAD)), 5 * HZ );
+ if (ret < 0)
+ return ret;
+
+ if (!ret) {
+ printk( KERN_ERR "%s: TIMEOUT! (JCSTS 0x%08x, JINTS 0x%08x, JCRST 0x%08x)\n", __FUNCTION__,
+ JPU_JCSTS, JPU_JINTS, JPU_JCRST );
+ return -ETIMEDOUT;
+ }
+
+ if (jpeg_error) {
+ /* Return error. */
+ jpeg->state = SH7722_JPEG_END;
+ jpeg->error = jpeg_error;
+
+ JPRINT( " '-> ERROR (0x%x)", jpeg->error );
+ }
+ else {
+ /* Return buffers to reload or to empty. */
+ jpeg->buffers = jpeg_buffers ^ 3;
+
+ if (jpeg_end) {
+ JPRINT( " '-> END" );
+
+ /* Return end. */
+ jpeg->state = SH7722_JPEG_END;
+ jpeg->buffers |= 1 << jpeg_buffer;
+ }
+ else if (encode)
+ JPRINT( " '-> LOADED (%d)", jpeg->buffers );
+ else
+ JPRINT( " '-> RELOAD (%d)", jpeg->buffers );
+ }
+
+ return 0;
+}
+
+static int
+sh7722_lock_jpeg( SH772xGfxSharedArea *shared )
+{
+ int ret;
+
+ if (jpeg_locked) {
+ ret = wait_event_interruptible_timeout( wait_jpeg_lock, !jpeg_locked, 5 * HZ );
+ if (ret < 0)
+ return ret;
+
+ if (!ret) {
+ printk( KERN_ERR "%s: TIMEOUT! (status 0x%08x, ints 0x%08x)\n", __FUNCTION__, JPU_JCSTS, JPU_JINTS );
+ return -ETIMEDOUT;
+ }
+ }
+
+ jpeg_locked = current->pid;
+
+ return 0;
+}
+
+static int
+sh7722_unlock_jpeg( SH772xGfxSharedArea *shared )
+{
+ if (jpeg_locked != current->pid)
+ return -EIO;
+
+ jpeg_locked = 0;
+
+ wake_up_all( &wait_jpeg_lock );
+
+ return 0;
+}
+
+/**********************************************************************************************************************/
+
+static irqreturn_t
+sh7722_jpu_irq( int irq, void *ctx )
+{
+ u32 ints;
+ SH772xGfxSharedArea *shared = ctx;
+
+ ints = JPU_JINTS;
+
+ JPU_JINTS = ~ints & JINTS_MASK;
+
+ if (ints & (JINTS_INS3_HEADER | JINTS_INS5_ERROR | JINTS_INS6_DONE))
+ JPU_JCCMD = JCCMD_END;
+
+ JPRINT( " ... JPU int 0x%08x (veu_linebuf:%d,jpeg_linebuf:%d,jpeg_linebufs:%d,jpeg_line:%d,jpeg_buffers:%d)",
+ ints, veu_linebuf, jpeg_linebuf, jpeg_linebufs, jpeg_line, jpeg_buffers );
+
+ if (ints) {
+ shared->jpeg_ints |= ints;
+
+ wake_up_all( &wait_jpeg_irq );
+
+ /* Header */
+ if (ints & JINTS_INS3_HEADER) {
+ JPRINT( " -> HEADER (%dx%d)", JPU_JIFDDHSZ, JPU_JIFDDVSZ );
+ }
+
+ /* Error */
+ if (ints & JINTS_INS5_ERROR) {
+ jpeg_error = JPU_JCDERR;
+
+ JPRINT( " -> ERROR 0x%08x!", jpeg_error );
+
+ wake_up_all( &wait_jpeg_run );
+ }
+
+ /* Done */
+ if (ints & JINTS_INS6_DONE) {
+ jpeg_end = 1;
+
+ JPRINT( " -> DONE" );
+
+ JPU_JCCMD = JCCMD_END;
+
+ wake_up_all( &wait_jpeg_run );
+ }
+
+ /* Done */
+ if (ints & JINTS_INS10_XFER_DONE) {
+ jpeg_end = 1;
+
+ JPRINT( " -> XFER DONE" );
+
+ JPU_JCCMD = JCCMD_END;
+
+ wake_up_all( &wait_jpeg_run );
+ }
+
+ /* Line buffer ready? FIXME: encoding */
+ if (ints & (JINTS_INS11_LINEBUF0 | JINTS_INS12_LINEBUF1)) {
+ JPRINT( " -> LINEBUF %d", jpeg_linebuf );
+
+ if (jpeg_encode) {
+ jpeg_linebufs &= ~(1 << jpeg_linebuf);
+
+ jpeg_linebuf = jpeg_linebuf ? 0 : 1;
+
+ if (jpeg_linebufs) {
+ jpeg_reading_line = 1; /* should still be one */
+
+ if (!jpeg_end)
+ JPU_JCCMD = JCCMD_LCMD2 | JCCMD_LCMD1;
+ }
+ else {
+ jpeg_reading_line = 0;
+ }
+
+ jpeg_line += 16;
+
+ if (jpeg_line_veu<jpeg_height && !veu_running && !jpeg_end) {
+ int offset = 0;
+ int n = 0;
+
+ JPRINT( " -> CONVERT %d", veu_linebuf );
+
+ veu_running = 1;
+
+ /* we will not update VESSR or VRFSR to prevent recalculating
+ * the input lines in case of partial content.
+ * This prevents hangups in case of program errors */
+
+ n = jpeg_line_veu * jpeg_inputheight;
+ while (n >= jpeg_height*8) { offset+=8; n -= jpeg_height*8; }
+ while (n >= jpeg_height) { offset++; n -= jpeg_height; }
+
+ /* VEU_VSACR is only used for CbCr, so we can simplify a bit */
+ n = (VEU_VTRCR & VTRCR_CHRR) ? 0 : 1;
+
+ VEU_VSAYR = jpeg_phys + offset * VEU_VESWR;
+ VEU_VSACR = jpeg_phys + ((offset >> n) + jpeg_height) * VEU_VESWR;
+
+ VEU_VDAYR = veu_linebuf ? JPU_JIFESYA2 : JPU_JIFESYA1;
+ VEU_VDACR = veu_linebuf ? JPU_JIFESCA2 : JPU_JIFESCA1;
+ VEU_VESTR = 0x1;
+ }
+ }
+ else {
+ jpeg_linebufs |= (1 << jpeg_linebuf);
+
+ jpeg_linebuf = jpeg_linebuf ? 0 : 1;
+
+ if (jpeg_linebufs != 3) {
+ jpeg_writing_line = 1; /* should still be one */
+
+ if (jpeg_line > 0 && !jpeg_end)
+ JPU_JCCMD = JCCMD_LCMD1 | JCCMD_LCMD2;
+ }
+ else {
+ jpeg_writing_line = 0;
+ }
+
+ jpeg_line += 16;
+
+ if (!veu_running && !jpeg_end && !jpeg_error) {
+ JPRINT( " -> CONVERT %d", veu_linebuf );
+
+ veu_running = 1;
+
+ VEU_VSAYR = veu_linebuf ? JPU_JIFDDYA2 : JPU_JIFDDYA1;
+ VEU_VSACR = veu_linebuf ? JPU_JIFDDCA2 : JPU_JIFDDCA1;
+ VEU_VESTR = 0x101;
+ }
+ }
+ }
+
+ /* Loaded */
+ if (ints & JINTS_INS13_LOADED) {
+ JPRINT( " -> LOADED %d (writing: %d)", jpeg_buffer, jpeg_writing );
+
+ jpeg_buffers &= ~(1 << jpeg_buffer);
+
+ jpeg_buffer = jpeg_buffer ? 0 : 1;
+
+ jpeg_writing--;
+
+ wake_up_all( &wait_jpeg_run );
+ }
+
+ /* Reload */
+ if (ints & JINTS_INS14_RELOAD) {
+ JPRINT( " -> RELOAD %d", jpeg_buffer );
+
+ jpeg_buffers &= ~(1 << jpeg_buffer);
+
+ jpeg_buffer = jpeg_buffer ? 0 : 1;
+
+ if (jpeg_buffers) {
+ jpeg_reading = 1; /* should still be one */
+
+ JPU_JCCMD = JCCMD_READ_RESTART;
+ }
+ else
+ jpeg_reading = 0;
+
+ wake_up_all( &wait_jpeg_run );
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+/**********************************************************************************************************************/
+
+static irqreturn_t
+sh7722_veu_irq( int irq, void *ctx )
+{
+ u32 events = VEU_VEVTR;
+
+ VEU_VEVTR = ~events & 0x101;
+
+ JPRINT( " ... VEU int 0x%08x (veu_linebuf:%d,jpeg_linebuf:%d,jpeg_linebufs:%d,jpeg_line:%d)",
+ events, veu_linebuf, jpeg_linebuf, jpeg_linebufs, jpeg_line );
+
+ /* update the lines processed.
+ * If we have tmpphys memory, we are ready now (veu lines == height) */
+ jpeg_line_veu += (VEU_VRFSR >> 16);
+
+ if (jpeg_encode) {
+ /* Fill line buffers. */
+ jpeg_linebufs |= 1 << veu_linebuf;
+
+ /* Resume encoding if it was blocked. */
+ if (!jpeg_reading_line && !jpeg_end && !jpeg_error && jpeg_linebufs) {
+ JPRINT( " -> ENCODE %d", veu_linebuf );
+ jpeg_reading_line = 1;
+ JPU_JCCMD = JCCMD_LCMD2 | JCCMD_LCMD1;
+ }
+
+ veu_linebuf = veu_linebuf ? 0 : 1;
+
+ if( jpeg_line_veu < jpeg_height /* still some more lines to do */
+ && jpeg_linebufs != 3 /* and still some place to put them */
+ && !jpeg_end /* safety, should not happen */
+ && !jpeg_error ) {
+ int offset = 0;
+ int n = 0;
+
+ JPRINT( " -> CONVERT %d", veu_linebuf );
+
+ n = jpeg_line_veu * jpeg_inputheight;
+ while (n >= jpeg_height*8) { offset+=8; n -= jpeg_height*8; }
+ while (n >= jpeg_height) { offset++; n -= jpeg_height; }
+
+ /* VEU_VSACR is only used for CbCr, so we can simplify a bit */
+ n = (VEU_VTRCR & VTRCR_CHRR) ? 0 : 1;
+
+ VEU_VSAYR = jpeg_phys + offset * VEU_VESWR;
+ VEU_VSACR = jpeg_phys + ((offset >> n) + jpeg_height) * VEU_VESWR;
+
+ VEU_VDAYR = veu_linebuf ? JPU_JIFESYA2 : JPU_JIFESYA1;
+ VEU_VDACR = veu_linebuf ? JPU_JIFESCA2 : JPU_JIFESCA1;
+
+ veu_running = 1; /* kick VEU to continue */
+ VEU_VESTR = 0x1;
+ }
+ else {
+ veu_running = 0;
+ }
+ }
+ else {
+ /* Release line buffer. */
+ jpeg_linebufs &= ~(1 << veu_linebuf);
+
+ /* Resume decoding if it was blocked. */
+ if (!jpeg_writing_line && !jpeg_end && !jpeg_error && jpeg_linebufs != 3) {
+ JPRINT( " -> RESUME %d", jpeg_linebuf );
+
+ jpeg_writing_line = 1;
+
+ JPU_JCCMD = JCCMD_LCMD1 | JCCMD_LCMD2;
+ }
+
+ veu_linebuf = veu_linebuf ? 0 : 1;
+
+ if (jpeg_linebufs) {
+ JPRINT( " -> CONVERT %d", veu_linebuf );
+
+ veu_running = 1; /* should still be one */
+
+ VEU_VSAYR = veu_linebuf ? JPU_JIFDDYA2 : JPU_JIFDDYA1;
+ VEU_VSACR = veu_linebuf ? JPU_JIFDDCA2 : JPU_JIFDDCA1;
+ VEU_VESTR = 0x101;
+ }
+ else {
+ if (jpeg_end)
+ wake_up_all( &wait_jpeg_run );
+
+ veu_running = 0;
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+/**********************************************************************************************************************/
+
+static irqreturn_t
+sh7722_beu_irq( int irq, void *ctx )
+{
+ BEVTR = 0;
+
+ /* Nothing here so far. But Vsync could be added. */
+
+ return IRQ_HANDLED;
+}
+
+/**********************************************************************************************************************/
+
+static irqreturn_t
+sh7722_tdg_irq( int irq, void *ctx )
+{
+ SH772xGfxSharedArea *shared = ctx;
+ u32 status = BEM_HC_INT_STATUS;
+
+ if (! (status & 0x111111)) {
+#ifndef SH7722GFX_IRQ_POLLER
+ printk( KERN_WARNING "%s: bogus interrupt, INT_STATUS 0x%08x!\n", __FUNCTION__, status );
+#endif
+ return IRQ_NONE;
+ }
+
+ if (status & ~0x100)
+ QDUMP( "-Interrupt" );
+
+ if (status & ~0x101100)
+ printk( KERN_ERR "%s: error! INT_STATUS 0x%08x!\n", __FUNCTION__, status );
+
+ shared->num_interrupts++;
+
+ /* Clear the interrupt. */
+ BEM_HC_INT_CLEAR = status;
+
+ if (status & 0x100010) {
+ if (!shared->hw_running)
+ printk( KERN_WARNING "%s: hw not running? INT_STATUS 0x%08x!\n", __FUNCTION__, status );
+
+ if (status & 0x10) {
+ printk( KERN_ERR "%s: RUNAWAY! (%srunning, hw %d-%d, next %d-%d - %svalid, "
+ "STATUS 0x%08x, INT_STATUS 0x%08x)\n",
+ __FUNCTION__,
+ shared->hw_running ? "" : "not ",
+ shared->hw_start,
+ shared->hw_end,
+ shared->next_start,
+ shared->next_end,
+ shared->next_valid ? "" : "not ",
+ BEM_HC_STATUS, status );
+
+ BEM_HC_RESET = 0x1111;
+ }
+
+ /* Next valid means user space is not in the process of extending the buffer. */
+ if (shared->next_valid && shared->next_start != shared->next_end) {
+ shared->hw_start = shared->next_start;
+ shared->hw_end = shared->next_end;
+
+ shared->next_start = shared->next_end = (shared->hw_end + 1 + 3) & ~3;
+ shared->next_valid = 0;
+
+ shared->num_words += shared->hw_end - shared->hw_start;
+
+ shared->num_starts++;
+
+ QDUMP( " '-> Start!" );
+
+ BEM_HC_DMA_ADR = shared->buffer_phys + shared->hw_start*4;
+ BEM_HC_DMA_START = 1;
+
+ wake_up_all( &wait_next );
+ }
+ else {
+ shared->num_idle++;
+
+ QDUMP( " '-> Idle." );
+
+ BEM_PE_CACHE = 1;
+
+ shared->hw_running = 0;
+
+ wake_up_all( &wait_next );
+ wake_up_all( &wait_idle );
+ }
+
+ shared->num_done++;
+ }
+
+ return IRQ_HANDLED;
+}
+
+#ifdef SH7722GFX_IRQ_POLLER
+static int
+sh7722_tdg_irq_poller( void *arg )
+{
+ daemonize( "%s", __FUNCTION__ );
+
+ sigfillset( &current->blocked );
+
+ while (!stop_poller) {
+ set_current_state( TASK_UNINTERRUPTIBLE );
+ schedule_timeout( 1 );
+
+ sh7722_tdg_irq( SH7722_TDG_IRQ, (void*) arg );
+ }
+
+ stop_poller = 0;
+
+ return 0;
+}
+#endif
+
+/**********************************************************************************************************************/
+/**********************************************************************************************************************/
+
+static int
+sh7722gfx_flush( struct file *filp,
+ fl_owner_t id )
+{
+ if (jpeg_locked == current->pid) {
+ jpeg_locked = 0;
+
+ wake_up_all( &wait_jpeg_lock );
+ }
+
+ return 0;
+}
+
+static int
+sh7722gfx_ioctl( struct inode *inode,
+ struct file *filp,
+ unsigned int cmd,
+ unsigned long arg )
+{
+ int ret;
+ SH772xRegister reg;
+ SH7722JPEG jpeg;
+
+ switch (cmd) {
+ case SH772xGFX_IOCTL_RESET:
+ return sh7722_reset( shared );
+
+ case SH772xGFX_IOCTL_WAIT_IDLE:
+ return sh7722_wait_idle( shared );
+
+ case SH772xGFX_IOCTL_WAIT_NEXT:
+ return sh7722_wait_next( shared );
+
+ case SH772xGFX_IOCTL_SETREG32:
+ if (copy_from_user( &reg, (void*)arg, sizeof(SH772xRegister) ))
+ return -EFAULT;
+
+ /* VEU, BEU, LCDC, VOU, JPEG */
+ if (reg.address < 0xFE920000 || reg.address > 0xFEA102D0)
+ return -EACCES;
+
+ *(volatile __u32 *) reg.address = reg.value;
+
+ return 0;
+
+ case SH772xGFX_IOCTL_GETREG32:
+ if (copy_from_user( &reg, (void*)arg, sizeof(SH772xRegister) ))
+ return -EFAULT;
+
+ /* VEU, BEU, LCDC, VOU, JPEG */
+ if (reg.address < 0xFE920000 || reg.address > 0xFEA102D0)
+ return -EACCES;
+
+ reg.value = *(volatile __u32 *) reg.address;
+
+ if (copy_to_user( (void*)arg, &reg, sizeof(SH772xRegister) ))
+ return -EFAULT;
+
+ return 0;
+
+ case SH7722GFX_IOCTL_WAIT_JPEG:
+ return sh7722_wait_jpeg( shared );
+
+ case SH7722GFX_IOCTL_RUN_JPEG:
+ if (copy_from_user( &jpeg, (void*)arg, sizeof(SH7722JPEG) ))
+ return -EFAULT;
+
+ ret = sh7722_run_jpeg( shared, &jpeg );
+ if (ret)
+ return ret;
+
+ if (copy_to_user( (void*)arg, &jpeg, sizeof(SH7722JPEG) ))
+ return -EFAULT;
+
+ return 0;
+
+ case SH7722GFX_IOCTL_LOCK_JPEG:
+ return sh7722_lock_jpeg( shared );
+
+ case SH7722GFX_IOCTL_UNLOCK_JPEG:
+ return sh7722_unlock_jpeg( shared );
+ }
+
+ return -ENOSYS;
+}
+
+static int
+sh7722gfx_mmap( struct file *file,
+ struct vm_area_struct *vma )
+{
+ unsigned int size;
+
+ /* Just allow mapping at offset 0. */
+ if (vma->vm_pgoff)
+ return -EINVAL;
+
+ /* Check size of requested mapping. */
+ size = vma->vm_end - vma->vm_start;
+ if (size != PAGE_ALIGN(sizeof(SH772xGfxSharedArea)))
+ return -EINVAL;
+
+ /* Set reserved and I/O flag for the area. */
+ vma->vm_flags |= VM_RESERVED | VM_IO;
+
+ /* Select uncached access. */
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+#ifdef USE_DMA_ALLOC_COHERENT
+ return remap_pfn_range( vma, vma->vm_start,
+ (__u32)shared >> PAGE_SHIFT,
+ size, vma->vm_page_prot );
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
+ return remap_pfn_range( vma, vma->vm_start,
+ virt_to_phys((void*)shared) >> PAGE_SHIFT,
+ size, vma->vm_page_prot );
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+ return remap_page_range( vma, vma->vm_start,
+ virt_to_phys((void*)shared),
+ size, vma->vm_page_prot );
+#else
+ return io_remap_page_range( vma->vm_start,
+ virt_to_phys((void*)shared),
+ size, vma->vm_page_prot );
+#endif
+}
+
+/**********************************************************************************************************************/
+
+static struct file_operations sh7722gfx_fops = {
+ flush: sh7722gfx_flush,
+ ioctl: sh7722gfx_ioctl,
+ mmap: sh7722gfx_mmap
+};
+
+static struct miscdevice sh7722gfx_miscdev = {
+ minor: 196, // 7*7*2*2
+ name: "sh772x_gfx",
+ fops: &sh7722gfx_fops
+};
+
+/**********************************************************************************************************************/
+
+int
+sh7722_init( void )
+{
+ int i;
+ int ret;
+
+ /* Register the SH7722 graphics device. */
+ ret = misc_register( &sh7722gfx_miscdev );
+ if (ret < 0) {
+ printk( KERN_ERR "%s: misc_register() for minor %d failed! (error %d)\n",
+ __FUNCTION__, sh7722gfx_miscdev.minor, ret );
+ return ret;
+ }
+
+ /* Allocate and initialize the shared area. */
+#ifdef USE_DMA_ALLOC_COHERENT
+ shared = dma_alloc_coherent( NULL, sizeof(SH772xGfxSharedArea),
+ (dma_addr_t*)&shared_phys, GFP_KERNEL );
+
+ printk( KERN_INFO "sh7722gfx: shared area at %p [%lx/%lx] using %d bytes\n",
+ shared, virt_to_phys(shared), shared_phys, sizeof(SH772xGfxSharedArea) );
+
+#else
+ shared_order = get_order(PAGE_ALIGN(sizeof(SH772xGfxSharedArea)));
+ shared_page = alloc_pages( GFP_DMA | GFP_KERNEL, shared_order );
+ shared = ioremap( virt_to_phys( page_address(shared_page) ),
+ PAGE_ALIGN(sizeof(SH772xGfxSharedArea)) );
+
+ for (i=0; i<1<<shared_order; i++)
+ SetPageReserved( shared_page + i );
+
+ printk( KERN_INFO "sh7722gfx: shared area (order %d) at %p [%lx] using %d bytes\n",
+ shared_order, shared, virt_to_phys(shared), sizeof(SH772xGfxSharedArea) );
+#endif
+
+
+ /* Allocate and initialize the JPEG area. */
+ jpeg_order = get_order(SH7722GFX_JPEG_SIZE);
+ jpeg_page = alloc_pages( GFP_DMA | GFP_KERNEL, jpeg_order );
+ jpeg_area = ioremap( virt_to_phys( page_address(jpeg_page) ),
+ PAGE_ALIGN(SH7722GFX_JPEG_SIZE) );
+
+ for (i=0; i<1<<jpeg_order; i++)
+ SetPageReserved( jpeg_page + i );
+
+ printk( KERN_INFO "sh7722gfx: jpeg area (order %d) at %p [%lx] using %d bytes\n",
+ jpeg_order, jpeg_area, virt_to_phys(jpeg_area), SH7722GFX_JPEG_SIZE );
+
+
+ /* Register the BEU interrupt handler. */
+ ret = request_irq( SH7722_BEU_IRQ, sh7722_beu_irq, IRQF_DISABLED, "BEU", (void*) shared );
+ if (ret) {
+ printk( KERN_ERR "%s: request_irq() for interrupt %d failed! (error %d)\n",
+ __FUNCTION__, SH7722_BEU_IRQ, ret );
+ goto error_beu;
+ }
+
+#ifdef SH7722GFX_IRQ_POLLER
+ kernel_thread( sh7722_tdg_irq_poller, (void*) shared, CLONE_KERNEL );
+#else
+ /* Register the TDG interrupt handler. */
+ ret = request_irq( SH7722_TDG_IRQ, sh7722_tdg_irq, IRQF_DISABLED, "TDG", (void*) shared );
+ if (ret) {
+ printk( KERN_ERR "%s: request_irq() for interrupt %d failed! (error %d)\n",
+ __FUNCTION__, SH7722_TDG_IRQ, ret );
+ goto error_tdg;
+ }
+#endif
+
+ /* Register the JPU interrupt handler. */
+ ret = request_irq( SH7722_JPU_IRQ, sh7722_jpu_irq, IRQF_DISABLED, "JPU", (void*) shared );
+ if (ret) {
+ printk( KERN_ERR "%s: request_irq() for interrupt %d failed! (error %d)\n",
+ __FUNCTION__, SH7722_JPU_IRQ, ret );
+ goto error_jpu;
+ }
+
+#if 0
+ /* Register the VEU interrupt handler. */
+ ret = request_irq( SH7722_VEU_IRQ, sh7722_veu_irq, IRQF_DISABLED, "VEU", (void*) shared );
+ if (ret) {
+ printk( KERN_ERR "%s: request_irq() for interrupt %d failed! (error %d)\n",
+ __FUNCTION__, SH7722_VEU_IRQ, ret );
+ goto error_veu;
+ }
+#endif
+
+ sh7722_reset( shared );
+
+ return 0;
+
+
+error_veu:
+ free_irq( SH7722_JPU_IRQ, (void*) shared );
+
+error_jpu:
+#ifndef SH7722GFX_IRQ_POLLER
+ free_irq( SH7722_TDG_IRQ, (void*) shared );
+
+error_tdg:
+#endif
+ free_irq( SH7722_BEU_IRQ, (void*) shared );
+
+error_beu:
+ for (i=0; i<1<<jpeg_order; i++)
+ ClearPageReserved( jpeg_page + i );
+
+ __free_pages( jpeg_page, jpeg_order );
+
+
+ for (i=0; i<1<<shared_order; i++)
+ ClearPageReserved( shared_page + i );
+
+ __free_pages( shared_page, shared_order );
+
+
+ misc_deregister( &sh7722gfx_miscdev );
+
+ return ret;
+}
+
+/**********************************************************************************************************************/
+
+void
+sh7722_exit( void )
+{
+ int i;
+
+
+ free_irq( SH7722_VEU_IRQ, (void*) shared );
+ free_irq( SH7722_JPU_IRQ, (void*) shared );
+
+#ifdef SH7722GFX_IRQ_POLLER
+ stop_poller = 1;
+
+ while (stop_poller) {
+ set_current_state( TASK_UNINTERRUPTIBLE );
+ schedule_timeout( 1 );
+ }
+#else
+ free_irq( SH7722_TDG_IRQ, (void*) shared );
+#endif
+
+ free_irq( SH7722_BEU_IRQ, (void*) shared );
+
+ misc_deregister( &sh7722gfx_miscdev );
+
+
+ for (i=0; i<1<<jpeg_order; i++)
+ ClearPageReserved( jpeg_page + i );
+
+ __free_pages( jpeg_page, jpeg_order );
+
+
+#ifdef USE_DMA_ALLOC_COHERENT
+ dma_free_coherent( NULL, sizeof(SH772xGfxSharedArea),
+ (void*)shared, (dma_addr_t)shared_phys );
+#else
+ for (i=0; i<1<<shared_order; i++)
+ ClearPageReserved( shared_page + i );
+
+ __free_pages( shared_page, shared_order );
+#endif
+}
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7722.h b/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7722.h
new file mode 100755
index 0000000..fc6f049
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7722.h
@@ -0,0 +1,21 @@
+/*
+ * SH7722/SH7723 Graphics Device
+ *
+ * Copyright (C) 2006-2008 IGEL Co.,Ltd
+ *
+ * Written by Denis Oliver Kropp <dok@directfb.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License v2
+ * as published by the Free Software Foundation.
+ */
+
+#ifndef __SH7722_H__
+#define __SH7722_H__
+
+int sh7722_init( void );
+void sh7722_exit( void );
+
+#endif
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7723.c b/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7723.c
new file mode 100755
index 0000000..ea64cf4
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7723.c
@@ -0,0 +1,566 @@
+/*
+ * SH7723 Graphics Device
+ *
+ * Copyright (C) 2006-2008 IGEL Co.,Ltd
+ *
+ * Written by Janine Kropp <nin@directfb.org>,
+ * Denis Oliver Kropp <dok@directfb.org>
+ *
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License v2
+ * as published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/ioctl.h>
+#include <linux/miscdevice.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
+#include <asm/mach/irq.h>
+#endif
+
+#include <sh772x_gfx.h>
+
+
+//#define SH7723GFX_DEBUG_2DG
+//#define SH7723GFX_IRQ_POLLER
+
+
+/**********************************************************************************************************************/
+
+#ifndef SH7723_BEU_IRQ
+#define SH7723_BEU_IRQ 53
+#endif
+
+#ifndef SH7723_TDG_IRQ
+#define SH7723_TDG_IRQ 44
+#endif
+
+/**********************************************************************************************************************/
+
+#define ENGINE_REG_TOP 0xA4680000
+#define SH7723_BEU_BASE 0xFE930000
+
+#define M2DG_REG(x) (*(volatile u32*)((x)+ENGINE_REG_TOP))
+#define BEU_REG(x) (*(volatile u32*)((x)+SH7723_BEU_BASE))
+
+#define M2DG_SCLR M2DG_REG(0x000)
+#define M2DG_DLSAR M2DG_REG(0x048)
+
+
+#define M2DG_STATUS M2DG_REG(0x004)
+#define M2DG_STATUS_CLEAR M2DG_REG(0x008)
+#define M2DG_INT_ENABLE M2DG_REG(0x00c)
+
+#define M2DG_SCLR_START 0x00000001
+#define M2DG_SCLR_RESET 0x80000000
+
+#define M2DG_INT_TRAP 0x0001
+#define M2DG_INT_INTERRUPT 0x0002
+#define M2DG_INT_ERROR 0x0004
+#define M2DG_INT_ANY 0x0007
+
+#define BEVTR BEU_REG(0x0018C)
+
+/**********************************************************************************************************************/
+
+#ifdef SH7723GFX_DEBUG_2DG
+#define QPRINT(x...) do { \
+ char buf[128]; \
+ struct timeval tv; \
+ do_gettimeofday( &tv ); \
+ snprintf( buf, sizeof(buf), x ); \
+ printk( KERN_DEBUG "%ld.%03ld.%03ld - %-17s: %s\n", \
+ tv.tv_sec - base_time.tv_sec, \
+ tv.tv_usec / 1000, tv.tv_usec % 1000, __FUNCTION__, buf ); \
+} while (0)
+#else
+#define QPRINT(x...) do {} while (0)
+#endif
+
+#define QDUMP(msg) QPRINT( "%-12s (%s, hw %5d-%5d, next %5d-%5d, %svalid, " \
+ "STATUS 0x%07x)", msg, \
+ shared->hw_running ? "running" : " idle", \
+ shared->hw_start, \
+ shared->hw_end, \
+ shared->next_start, \
+ shared->next_end, \
+ shared->next_valid ? " " : "in", \
+ M2DG_STATUS & M2DG_INT_ANY );
+
+/**********************************************************************************************************************/
+
+static DECLARE_WAIT_QUEUE_HEAD( wait_idle );
+static DECLARE_WAIT_QUEUE_HEAD( wait_next );
+
+static SH772xGfxSharedArea *shared;
+
+static struct timeval base_time;
+
+#ifndef SHARED_AREA_PHYS
+static struct page *shared_page;
+static unsigned int shared_order;
+#endif
+
+#ifdef SH7723GFX_IRQ_POLLER
+static int stop_poller;
+#endif
+
+/**********************************************************************************************************************/
+
+static int
+sh7723_reset( SH772xGfxSharedArea *shared )
+{
+ do_gettimeofday( &base_time );
+
+ QPRINT( "Resetting hardware..." );
+
+ M2DG_SCLR = M2DG_SCLR_RESET;
+ udelay( 5 );
+ M2DG_SCLR = 0;
+
+ QPRINT( "Initializing shared area..." );
+
+ memset( (void*) shared, 0, sizeof(SH772xGfxSharedArea) );
+
+ shared->buffer_phys = virt_to_phys(&shared->buffer[0]);
+ shared->magic = SH7723GFX_SHARED_MAGIC;
+
+
+ QPRINT( "Clearing interrupts..." );
+
+ M2DG_STATUS_CLEAR = M2DG_INT_ANY;
+
+ M2DG_INT_ENABLE = M2DG_INT_ANY;
+
+ QDUMP( "Ready" );
+
+ return 0;
+}
+
+/* copied from board-ap325rxa.c */
+#define PORT_PSCR 0xA405011E
+#define PORT_PSDR 0xA405013E
+#define FPGA_LCDREG 0xB4100180
+#define FPGA_BKLREG 0xB4100212
+
+static int
+sh7723_power_display( void )
+{
+ msleep(100);
+
+ /* ASD AP-320/325 LCD ON */
+ ctrl_outw(0x0018, FPGA_LCDREG);
+
+ /* backlight */
+ ctrl_outw((ctrl_inw(PORT_PSCR) & ~0x00C0) | 0x40, PORT_PSCR);
+ ctrl_outb(ctrl_inb(PORT_PSDR) & ~0x08, PORT_PSDR);
+ ctrl_outw(0x100, FPGA_BKLREG);
+
+ return 0;
+}
+
+static int
+sh7723_wait_idle( SH772xGfxSharedArea *shared )
+{
+ int ret;
+
+ QDUMP( "Waiting....." );
+
+ /* Does not need to be atomic. There's a lock in user space,
+ * but anyhow, this is just for statistics. */
+ shared->num_wait_idle++;
+
+ ret = wait_event_interruptible_timeout( wait_idle, !shared->hw_running, 42*HZ );
+ if (!ret) {
+ printk( KERN_ERR "%s: TIMEOUT! (%srunning, hw %d-%d, next %d-%d - %svalid, "
+ "STATUS 0x%08x)\n",
+ __FUNCTION__,
+ shared->hw_running ? "" : "not ",
+ shared->hw_start,
+ shared->hw_end,
+ shared->next_start,
+ shared->next_end,
+ shared->next_valid ? "" : "not ",
+ M2DG_STATUS & M2DG_INT_ANY );
+ }
+
+ QDUMP( "........done" );
+
+ return (ret > 0) ? 0 : (ret < 0) ? ret : -ETIMEDOUT;
+}
+
+static int
+sh7723_wait_next( SH772xGfxSharedArea *shared )
+{
+ int ret;
+
+ QDUMP( "Waiting....." );
+
+ /* Does not need to be atomic. There's a lock in user space,
+ * but anyhow, this is just for statistics. */
+ shared->num_wait_next++;
+
+ ret = wait_event_interruptible_timeout( wait_next, !shared->hw_running ||
+ shared->next_start == shared->next_end, 42*HZ );
+ if (!ret) {
+ printk( KERN_ERR "%s: TIMEOUT! (%srunning, hw %d-%d, next %d-%d - %svalid, "
+ "STATUS 0x%08x)\n",
+ __FUNCTION__,
+ shared->hw_running ? "" : "not ",
+ shared->hw_start,
+ shared->hw_end,
+ shared->next_start,
+ shared->next_end,
+ shared->next_valid ? "" : "not ",
+ M2DG_STATUS & M2DG_INT_ANY );
+ }
+
+ QDUMP( "........done" );
+
+ return (ret > 0) ? 0 : (ret < 0) ? ret : -ETIMEDOUT;
+}
+
+/**********************************************************************************************************************/
+
+static irqreturn_t
+sh7723_beu_irq( int irq, void *ctx )
+{
+ BEVTR = 0;
+
+ /* Nothing here so far. But Vsync could be added. */
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t
+sh7723_tdg_irq( int irq, void *ctx )
+{
+ SH772xGfxSharedArea *shared = ctx;
+ u32 status = M2DG_STATUS & M2DG_INT_ANY;
+
+ if (! (status & M2DG_INT_ANY)) {
+#ifndef SH7723GFX_IRQ_POLLER
+ printk( KERN_WARNING "%s: bogus interrupt, STATUS 0x%08x!\n", __FUNCTION__, status );
+#endif
+ return IRQ_NONE;
+ }
+
+// if (status & ~0x100)
+ QDUMP( "-Interrupt" );
+
+ if (status & M2DG_INT_ERROR)
+ printk( KERN_ERR "%s: error! STATUS 0x%08x!\n", __FUNCTION__, status );
+
+ shared->num_interrupts++;
+
+ /* Clear the interrupt. */
+ M2DG_STATUS_CLEAR = status;
+
+ if (status & (M2DG_INT_TRAP | M2DG_INT_ERROR)) {
+ if (!shared->hw_running)
+ printk( KERN_WARNING "%s: huh, hw running? STATUS 0x%08x!\n", __FUNCTION__, status );
+
+ if (status & M2DG_INT_ERROR) {
+ printk( KERN_ERR "%s: ERROR! (%srunning, hw %d-%d, next %d-%d - %svalid, "
+ "STATUS 0x%08x)\n",
+ __FUNCTION__,
+ shared->hw_running ? "" : "not ",
+ shared->hw_start,
+ shared->hw_end,
+ shared->next_start,
+ shared->next_end,
+ shared->next_valid ? "" : "not ",
+ status );
+
+ M2DG_SCLR = M2DG_SCLR_RESET;
+ }
+
+ /* Next valid means user space is not in the process of extending the buffer. */
+ if (shared->next_valid && shared->next_start != shared->next_end) {
+ shared->hw_start = shared->next_start;
+ shared->hw_end = shared->next_end;
+
+ shared->next_start = shared->next_end = (shared->hw_end + 1 + 3) & ~3;
+ shared->next_valid = 0;
+
+ shared->num_words += shared->hw_end - shared->hw_start;
+
+ shared->num_starts++;
+
+ QDUMP( " '-> Start!" );
+
+ M2DG_DLSAR = shared->buffer_phys + shared->hw_start*4;
+ M2DG_SCLR = M2DG_SCLR_START;
+
+ wake_up_all( &wait_next );
+ }
+ else {
+ shared->num_idle++;
+
+ QDUMP( " '-> Idle." );
+
+//check if needed
+// BEM_PE_CACHE = 1;
+
+ shared->hw_running = 0;
+
+ wake_up_all( &wait_next );
+ wake_up_all( &wait_idle );
+ }
+
+ shared->num_done++;
+ }
+
+ return IRQ_HANDLED;
+}
+
+#ifdef SH7723GFX_IRQ_POLLER
+static int
+sh7723_tdg_irq_poller( void *arg )
+{
+ daemonize( "%s", __FUNCTION__ );
+
+ sigfillset( &current->blocked );
+
+ while (!stop_poller) {
+ set_current_state( TASK_UNINTERRUPTIBLE );
+ schedule_timeout( 1 );
+
+ sh7723_tdg_irq( SH7723_TDG_IRQ, (void*) arg );
+ }
+
+ stop_poller = 0;
+
+ return 0;
+}
+#endif
+
+/**********************************************************************************************************************/
+
+static int
+sh7723gfx_ioctl( struct inode *inode,
+ struct file *filp,
+ unsigned int cmd,
+ unsigned long arg )
+{
+ SH772xRegister reg;
+
+ switch (cmd) {
+ case SH772xGFX_IOCTL_RESET:
+ return sh7723_reset( shared );
+
+ case SH772xGFX_IOCTL_WAIT_IDLE:
+ return sh7723_wait_idle( shared );
+
+ case SH772xGFX_IOCTL_WAIT_NEXT:
+ return sh7723_wait_next( shared );
+
+ case SH772xGFX_IOCTL_SETREG32:
+ if (copy_from_user( &reg, (void*)arg, sizeof(SH772xRegister) ))
+ return -EFAULT;
+
+ /* BEU, LCDC, VOU, 2DG */
+ if ((reg.address < 0xFE930000 || reg.address > 0xFEA102D0) &&
+ (reg.address < 0xA4680000 || reg.address > 0xA468FFFF))
+ return -EACCES;
+
+ *(volatile __u32 *) reg.address = reg.value;
+
+ return 0;
+
+ case SH772xGFX_IOCTL_GETREG32:
+ if (copy_from_user( &reg, (void*)arg, sizeof(SH772xRegister) ))
+ return -EFAULT;
+
+ /* BEU, LCDC, VOU */
+ if ((reg.address < 0xFE930000 || reg.address > 0xFEA102D0) &&
+ (reg.address < 0xA4680000 || reg.address > 0xA468FFFF))
+ return -EACCES;
+
+ reg.value = *(volatile __u32 *) reg.address;
+
+ if (copy_to_user( (void*)arg, &reg, sizeof(SH772xRegister) ))
+ return -EFAULT;
+
+ return 0;
+
+ case SH772xGFX_IOCTL_POWER_DISPLAY:
+ return sh7723_power_display( );
+ }
+
+ return -ENOSYS;
+}
+
+static int
+sh7723gfx_mmap( struct file *file,
+ struct vm_area_struct *vma )
+{
+ unsigned int size;
+
+ /* Just allow mapping at offset 0. */
+ if (vma->vm_pgoff)
+ return -EINVAL;
+
+ /* Check size of requested mapping. */
+ size = vma->vm_end - vma->vm_start;
+ if (size != PAGE_ALIGN(sizeof(SH772xGfxSharedArea)))
+ return -EINVAL;
+
+ /* Set reserved and I/O flag for the area. */
+ vma->vm_flags |= VM_RESERVED | VM_IO;
+
+ /* Select uncached access. */
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
+ return remap_pfn_range( vma, vma->vm_start,
+ virt_to_phys((void*)shared) >> PAGE_SHIFT,
+ size, vma->vm_page_prot );
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+ return remap_page_range( vma, vma->vm_start,
+ virt_to_phys((void*)shared),
+ size, vma->vm_page_prot );
+#else
+ return io_remap_page_range( vma->vm_start,
+ virt_to_phys((void*)shared),
+ size, vma->vm_page_prot );
+#endif
+}
+
+/**********************************************************************************************************************/
+
+static struct file_operations sh7723gfx_fops = {
+ ioctl: sh7723gfx_ioctl,
+ mmap: sh7723gfx_mmap
+};
+
+static struct miscdevice sh7723gfx_miscdev = {
+ minor: 196, // 7*7*2*2
+ name: "sh772x_gfx",
+ fops: &sh7723gfx_fops
+};
+
+/**********************************************************************************************************************/
+
+int
+sh7723_init( void )
+{
+#ifndef SHARED_AREA_PHYS
+ int i;
+#endif
+ int ret;
+
+ /* Register the SH7723 graphics device. */
+ ret = misc_register( &sh7723gfx_miscdev );
+ if (ret < 0) {
+ printk( KERN_ERR "%s: misc_register() for minor %d failed! (error %d)\n",
+ __FUNCTION__, sh7723gfx_miscdev.minor, ret );
+ return ret;
+ }
+
+ /* Allocate and initialize the shared area. */
+#ifdef SHARED_AREA_PHYS
+#if SHARED_AREA_SIZE < PAGE_ALIGN(sizeof(SH772xGfxSharedArea))
+#error SHARED_AREA_SIZE < PAGE_ALIGN(sizeof(SH772xGfxSharedArea))!
+#endif
+ shared = ioremap( SHARED_AREA_PHYS, PAGE_ALIGN(sizeof(SH772xGfxSharedArea)) );
+#else
+ shared_order = get_order(sizeof(SH772xGfxSharedArea));
+ shared_page = alloc_pages( GFP_DMA | GFP_KERNEL, shared_order );
+ shared = ioremap( virt_to_phys( page_address(shared_page) ),
+ PAGE_ALIGN(sizeof(SH772xGfxSharedArea)) );
+
+ for (i=0; i<1<<shared_order; i++)
+ SetPageReserved( shared_page + i );
+#endif
+
+ printk( KERN_INFO "sh7723gfx: shared area (order %d) at %p [%lx] using %d bytes\n",
+ shared_order, shared, virt_to_phys(shared), sizeof(SH772xGfxSharedArea) );
+
+ /* Register the BEU interrupt handler. */
+ ret = request_irq( SH7723_BEU_IRQ, sh7723_beu_irq, IRQF_DISABLED, "BEU", (void*) shared );
+ if (ret) {
+ printk( KERN_ERR "%s: request_irq() for BEU interrupt %d failed! (error %d)\n",
+ __FUNCTION__, SH7723_BEU_IRQ, ret );
+ goto error_beu;
+ }
+
+#ifdef SH7723GFX_IRQ_POLLER
+ kernel_thread( sh7723_tdg_irq_poller, (void*) shared, CLONE_KERNEL );
+#else
+ /* Register the TDG interrupt handler. */
+ ret = request_irq( SH7723_TDG_IRQ, sh7723_tdg_irq, IRQF_DISABLED, "TDG", (void*) shared );
+ if (ret) {
+ printk( KERN_ERR "%s: request_irq() for TDG interrupt %d failed! (error %d)\n",
+ __FUNCTION__, SH7723_TDG_IRQ, ret );
+ goto error_tdg;
+ }
+#endif
+
+ sh7723_reset( shared );
+
+ return 0;
+
+
+error_tdg:
+ free_irq( SH7723_BEU_IRQ, (void*) shared );
+
+error_beu:
+#ifndef SHARED_AREA_PHYS
+ for (i=0; i<1<<shared_order; i++)
+ ClearPageReserved( shared_page + i );
+
+ __free_pages( shared_page, shared_order );
+#endif
+
+ misc_deregister( &sh7723gfx_miscdev );
+
+ return ret;
+}
+
+/**********************************************************************************************************************/
+
+void
+sh7723_exit( void )
+{
+#ifndef SHARED_AREA_PHYS
+ int i;
+#endif
+
+
+#ifdef SH7723GFX_IRQ_POLLER
+ stop_poller = 1;
+
+ while (stop_poller) {
+ set_current_state( TASK_UNINTERRUPTIBLE );
+ schedule_timeout( 1 );
+ }
+#else
+ free_irq( SH7723_TDG_IRQ, (void*) shared );
+#endif
+
+ free_irq( SH7723_BEU_IRQ, (void*) shared );
+
+ misc_deregister( &sh7723gfx_miscdev );
+
+
+#ifndef SHARED_AREA_PHYS
+ for (i=0; i<1<<shared_order; i++)
+ ClearPageReserved( shared_page + i );
+
+ __free_pages( shared_page, shared_order );
+#endif
+}
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7723.h b/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7723.h
new file mode 100755
index 0000000..dcaf481
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7723.h
@@ -0,0 +1,21 @@
+/*
+ * SH7722/SH7723 Graphics Device
+ *
+ * Copyright (C) 2006-2008 IGEL Co.,Ltd
+ *
+ * Written by Denis Oliver Kropp <dok@directfb.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License v2
+ * as published by the Free Software Foundation.
+ */
+
+#ifndef __SH7723_H__
+#define __SH7723_H__
+
+int sh7723_init( void );
+void sh7723_exit( void );
+
+#endif
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh772x_driver.c b/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh772x_driver.c
new file mode 100755
index 0000000..aba270b
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh772x_driver.c
@@ -0,0 +1,82 @@
+/*
+ * SH7722/SH7723 Graphics Device
+ *
+ * Copyright (C) 2006-2008 IGEL Co.,Ltd
+ *
+ * Written by Denis Oliver Kropp <dok@directfb.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License v2
+ * as published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include <asm/io.h>
+#include <asm/processor.h>
+
+#include "sh7722.h"
+#include "sh7723.h"
+
+
+/**********************************************************************************************************************/
+
+static int sh772x_init = 0;
+
+/**********************************************************************************************************************/
+
+static int __init
+sh772x_driver_init( void )
+{
+ int ret = -ENODEV;
+
+ if ((ctrl_inl(CCN_PVR) & 0xffff00) == 0x300800) {
+ switch (ctrl_inl(CCN_PRR) & 0xf00) {
+ case 0xa00:
+ ret = sh7722_init();
+ if (ret)
+ return ret;
+
+ sh772x_init = 7722;
+ break;
+
+ case 0x500:
+ ret = sh7723_init();
+ if (ret)
+ return ret;
+
+ sh772x_init = 7723;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+module_init( sh772x_driver_init );
+
+/**********************************************************************************************************************/
+
+static void __exit
+sh772x_driver_exit( void )
+{
+ switch (sh772x_init) {
+ case 7722:
+ sh7722_exit();
+ break;
+
+ case 7723:
+ sh7723_exit();
+ break;
+ }
+}
+
+module_exit( sh772x_driver_exit );
+
+/**********************************************************************************************************************/
+
+MODULE_AUTHOR( "Denis Oliver Kropp <dok@directfb.org> & Janine Kropp <nin@directfb.org>" );
+MODULE_LICENSE( "GPL v2" );
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh772x_gfx.h b/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh772x_gfx.h
new file mode 100755
index 0000000..7c1abb5
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh772x_gfx.h
@@ -0,0 +1,105 @@
+#ifndef __SH772X_GFX_H__
+#define __SH772X_GFX_H__
+
+#include <asm/types.h>
+
+
+#define SH772xGFX_BUFFER_WORDS 0x1f000 /* Number of 32bit words in display list (ring buffer). */
+
+#define SH7722GFX_SHARED_MAGIC 0x77220001 /* Increase if binary compatibility is broken. */
+#define SH7723GFX_SHARED_MAGIC 0x77230001 /* Increase if binary compatibility is broken. */
+
+#define SH7722GFX_JPEG_RELOAD_SIZE (64 * 1024)
+#define SH7722GFX_JPEG_LINEBUFFER_PITCH (2560)
+#define SH7722GFX_JPEG_LINEBUFFER_HEIGHT (16)
+#define SH7722GFX_JPEG_LINEBUFFER_SIZE (SH7722GFX_JPEG_LINEBUFFER_PITCH * SH7722GFX_JPEG_LINEBUFFER_HEIGHT * 2)
+#define SH7722GFX_JPEG_LINEBUFFER_SIZE_Y (SH7722GFX_JPEG_LINEBUFFER_PITCH * SH7722GFX_JPEG_LINEBUFFER_HEIGHT)
+#define SH7722GFX_JPEG_SIZE (SH7722GFX_JPEG_LINEBUFFER_SIZE * 2 + SH7722GFX_JPEG_RELOAD_SIZE * 2)
+
+
+typedef volatile struct {
+ u32 buffer[SH772xGFX_BUFFER_WORDS];
+
+
+ int hw_start;
+ int hw_end;
+
+ int hw_running;
+
+
+ int next_start;
+ int next_end;
+
+ int next_valid;
+
+
+ unsigned long buffer_phys;
+
+ unsigned int num_words;
+ unsigned int num_starts;
+ unsigned int num_done;
+ unsigned int num_interrupts;
+ unsigned int num_wait_idle;
+ unsigned int num_wait_next;
+ unsigned int num_idle;
+
+ u32 jpeg_ints;
+ unsigned long jpeg_phys;
+
+ u32 magic;
+} SH772xGfxSharedArea;
+
+
+typedef struct {
+ u32 address; /* in */
+ u32 value; /* in/out */
+} SH772xRegister;
+
+
+typedef enum {
+ SH7722_JPEG_START,
+ SH7722_JPEG_RUN,
+ SH7722_JPEG_END
+} SH7722JPEGState;
+
+typedef enum {
+ SH7722_JPEG_FLAG_RELOAD = 0x00000001, /* enable reload mode */
+ SH7722_JPEG_FLAG_CONVERT = 0x00000002, /* enable conversion through VEU */
+ SH7722_JPEG_FLAG_ENCODE = 0x00000004 /* set encoding mode */
+} SH7722JPEGFlags;
+
+typedef struct {
+ SH7722JPEGState state; /* starting, running or ended (done/error) */
+ SH7722JPEGFlags flags; /* control decoding options */
+
+ u32 buffers; /* input = loaded buffers, output = buffers to reload */
+ u32 error; /* valid in END state, non-zero means error */
+
+ unsigned long phys; /* needed in case of scaling, prevents rounding errors */
+ int height;
+ int inputheight;
+} SH7722JPEG;
+
+
+/* Just initialization and synchronization.
+ * Hardware is started from user space via MMIO to DMA registers. */
+#define SH772xGFX_IOCTL_RESET _IO( 'G', 0 )
+#define SH772xGFX_IOCTL_WAIT_IDLE _IO( 'G', 1 )
+#define SH772xGFX_IOCTL_WAIT_NEXT _IO( 'G', 2 )
+
+/* JPEG processing, requires programming from user space. */
+#define SH7722GFX_IOCTL_WAIT_JPEG _IO ( 'J', 0 )
+#define SH7722GFX_IOCTL_RUN_JPEG _IOWR( 'J', 1, SH7722JPEG )
+#define SH7722GFX_IOCTL_LOCK_JPEG _IO ( 'J', 2 )
+#define SH7722GFX_IOCTL_UNLOCK_JPEG _IO ( 'J', 3 )
+
+
+/* Register access limited to BEU, LCDC, VOU and JPU. */
+#define SH772xGFX_IOCTL_SETREG32 _IOW( 'g', 0, SH772xRegister )
+#define SH772xGFX_IOCTL_GETREG32 _IOR( 'g', 1, SH772xRegister )
+
+/* Generic IOCTL to power the display, do this after programming the LCD Controller */
+#define SH772xGFX_IOCTL_POWER_DISPLAY _IO( 'k', 0 )
+
+#endif
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722.c b/Source/DirectFB/gfxdrivers/sh772x/sh7722.c
new file mode 100755
index 0000000..4d09928
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722.c
@@ -0,0 +1,490 @@
+#ifdef SH7722_DEBUG_DRIVER
+#define DIRECT_ENABLE_DEBUG
+#endif
+
+#include <stdio.h>
+#include <jpeglib.h>
+
+#undef HAVE_STDLIB_H
+
+#include <config.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#include <asm/types.h>
+
+#include <directfb.h>
+#include <directfb_util.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/system.h>
+
+#include <misc/conf.h>
+
+#include <core/core.h>
+#include <core/gfxcard.h>
+#include <core/layers.h>
+#include <core/screens.h>
+#include <core/system.h>
+
+#include <core/graphics_driver.h>
+
+DFB_GRAPHICS_DRIVER( sh7722 )
+
+
+#include "sh7722.h"
+#include "sh7722_blt.h"
+#include "sh7722_jpeglib.h"
+#include "sh7722_layer.h"
+#include "sh7722_lcd.h"
+#include "sh7722_multi.h"
+#include "sh7722_screen.h"
+
+#include "sh7723_blt.h"
+
+#ifdef SH772X_FBDEV_SUPPORT
+#include <linux/fb.h>
+#include <sys/mman.h>
+#endif
+
+
+D_DEBUG_DOMAIN( SH7722_Driver, "SH7722/Driver", "Renesas SH7722 Driver" );
+
+/**********************************************************************************************************************/
+
+static int
+driver_probe( CoreGraphicsDevice *device )
+{
+ D_DEBUG_AT( SH7722_Driver, "%s()\n", __FUNCTION__ );
+
+ return dfb_gfxcard_get_accelerator( device ) == 0x2D47;
+}
+
+static void
+driver_get_info( CoreGraphicsDevice *device,
+ GraphicsDriverInfo *info )
+{
+ D_DEBUG_AT( SH7722_Driver, "%s()\n", __FUNCTION__ );
+
+ /* fill driver info structure */
+ snprintf( info->name,
+ DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH,
+ "Renesas SH772x Driver" );
+
+ snprintf( info->vendor,
+ DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH,
+ "Denis & Janine Kropp" );
+
+ info->version.major = 0;
+ info->version.minor = 9;
+
+ info->driver_data_size = sizeof(SH7722DriverData);
+ info->device_data_size = sizeof(SH7722DeviceData);
+}
+
+static DFBResult
+driver_init_driver( CoreGraphicsDevice *device,
+ GraphicsDeviceFuncs *funcs,
+ void *driver_data,
+ void *device_data,
+ CoreDFB *core )
+{
+ DFBResult ret;
+ SH7722DriverData *sdrv = driver_data;
+ SH7722DeviceData *sdev = device_data;
+
+ D_DEBUG_AT( SH7722_Driver, "%s()\n", __FUNCTION__ );
+
+ /* Keep pointer to shared device data. */
+ sdrv->dev = device_data;
+
+ /* Keep core and device pointer. */
+ sdrv->core = core;
+ sdrv->device = device;
+
+ /* Open the drawing engine device. */
+ sdrv->gfx_fd = direct_try_open( "/dev/sh772x_gfx", "/dev/misc/sh772x_gfx", O_RDWR, true );
+ if (sdrv->gfx_fd < 0)
+ return DFB_INIT;
+
+ /* Map its shared data. */
+ sdrv->gfx_shared = mmap( NULL, direct_page_align( sizeof(SH772xGfxSharedArea) ),
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED, sdrv->gfx_fd, 0 );
+ if (sdrv->gfx_shared == MAP_FAILED) {
+ D_PERROR( "SH7722/Driver: Could not map shared area!\n" );
+ close( sdrv->gfx_fd );
+ return DFB_INIT;
+ }
+
+ sdrv->mmio_base = dfb_gfxcard_map_mmio( device, 0, -1 );
+ if (!sdrv->mmio_base) {
+ D_PERROR( "SH7722/Driver: Could not map MMIO area!\n" );
+ munmap( (void*) sdrv->gfx_shared, direct_page_align( sizeof(SH772xGfxSharedArea) ) );
+ close( sdrv->gfx_fd );
+ return DFB_INIT;
+ }
+
+ /* Check the magic value. */
+ switch (sdrv->gfx_shared->magic) {
+ case SH7722GFX_SHARED_MAGIC:
+ sdev->sh772x = 7722;
+
+ /* Initialize function table. */
+ funcs->EngineReset = sh7722EngineReset;
+ funcs->EngineSync = sh7722EngineSync;
+ funcs->EmitCommands = sh7722EmitCommands;
+ funcs->CheckState = sh7722CheckState;
+ funcs->SetState = sh7722SetState;
+ funcs->FillTriangle = sh7722FillTriangle;
+ funcs->Blit = sh7722Blit;
+ funcs->StretchBlit = sh7722StretchBlit;
+ funcs->FlushTextureCache = sh7722FlushTextureCache;
+
+ /* Initialize JPEG library. */
+ ret = SH7722_JPEG_Initialize();
+ if (ret) {
+ D_DERROR( ret, "SH7722/Driver: JPEG initialization failed!\n" );
+ dfb_gfxcard_unmap_mmio( device, sdrv->mmio_base, -1 );
+ munmap( (void*) sdrv->gfx_shared, direct_page_align( sizeof(SH772xGfxSharedArea) ) );
+ close( sdrv->gfx_fd );
+ return DFB_INIT;
+ }
+ break;
+
+ case SH7723GFX_SHARED_MAGIC:
+ sdev->sh772x = 7723;
+
+ /* Initialize function table. */
+ funcs->EngineReset = sh7723EngineReset;
+ funcs->EngineSync = sh7723EngineSync;
+ funcs->EmitCommands = sh7723EmitCommands;
+ funcs->CheckState = sh7723CheckState;
+ funcs->SetState = sh7723SetState;
+ funcs->FillRectangle = sh7723FillRectangle;
+ funcs->FillTriangle = sh7723FillTriangle;
+ funcs->DrawRectangle = sh7723DrawRectangle;
+ funcs->DrawLine = sh7723DrawLine;
+ funcs->Blit = sh7723Blit;
+ break;
+
+ default:
+ D_ERROR( "SH772x/Driver: Magic value 0x%08x doesn't match 0x%08x or 0x%08x!\n",
+ sdrv->gfx_shared->magic, SH7722GFX_SHARED_MAGIC, SH7723GFX_SHARED_MAGIC );
+ dfb_gfxcard_unmap_mmio( device, sdrv->mmio_base, -1 );
+ munmap( (void*) sdrv->gfx_shared, direct_page_align( sizeof(SH772xGfxSharedArea) ) );
+ close( sdrv->gfx_fd );
+ return DFB_INIT;
+ }
+
+
+ /* Get virtual address for the LCD buffer in slaves here,
+ master does it in driver_init_device(). */
+#ifndef SH772X_FBDEV_SUPPORT
+ if (!dfb_core_is_master( core ))
+ sdrv->lcd_virt = dfb_gfxcard_memory_virtual( device, sdev->lcd_offset );
+#endif
+
+
+ /* Register primary screen. */
+ sdrv->screen = dfb_screens_register( device, driver_data, &sh7722ScreenFuncs );
+
+ /* Register three input system layers. */
+ sdrv->input1 = dfb_layers_register( sdrv->screen, driver_data, &sh7722LayerFuncs );
+ sdrv->input2 = dfb_layers_register( sdrv->screen, driver_data, &sh7722LayerFuncs );
+ sdrv->input3 = dfb_layers_register( sdrv->screen, driver_data, &sh7722LayerFuncs );
+
+ /* Register multi window layer. */
+ sdrv->multi = dfb_layers_register( sdrv->screen, driver_data, &sh7722MultiLayerFuncs );
+
+ return DFB_OK;
+}
+
+static DFBResult
+driver_init_device( CoreGraphicsDevice *device,
+ GraphicsDeviceInfo *device_info,
+ void *driver_data,
+ void *device_data )
+{
+ SH7722DriverData *sdrv = driver_data;
+ SH7722DeviceData *sdev = device_data;
+
+ D_DEBUG_AT( SH7722_Driver, "%s()\n", __FUNCTION__ );
+
+ /* FIXME: Add a runtime option / config file. */
+ sdev->lcd_format = DSPF_RGB16;
+
+ /* Check format of LCD buffer. */
+ switch (sdev->lcd_format) {
+ case DSPF_RGB16:
+ case DSPF_NV16:
+ break;
+
+ default:
+ return DFB_UNSUPPORTED;
+ }
+
+ if (sdev->sh772x == 7723)
+ memset( dfb_gfxcard_memory_virtual(device,0), 0, dfb_gfxcard_memory_length() );
+
+ /*
+ * Setup LCD buffer.
+ */
+#ifdef SH772X_FBDEV_SUPPORT
+ {
+ struct fb_fix_screeninfo fsi;
+ struct fb_var_screeninfo vsi;
+ int fbdev;
+
+ if ((fbdev = open("/dev/fb", O_RDONLY)) < 0) {
+ D_ERROR( "SH7722/Driver: Can't open fbdev to get LCDC info!\n" );
+ return DFB_FAILURE;
+ }
+
+ if (ioctl(fbdev, FBIOGET_FSCREENINFO, &fsi) < 0) {
+ D_ERROR( "SH7722/Driver: FBIOGET_FSCREEINFO failed.\n" );
+ close(fbdev);
+ return DFB_FAILURE;
+ }
+
+ if (ioctl(fbdev, FBIOGET_VSCREENINFO, &vsi) < 0) {
+ D_ERROR( "SH7722/Driver: FBIOGET_VSCREEINFO failed.\n" );
+ close(fbdev);
+ return DFB_FAILURE;
+ }
+
+ sdev->lcd_width = vsi.xres;
+ sdev->lcd_height = vsi.yres;
+ sdev->lcd_pitch = fsi.line_length;
+ sdev->lcd_size = fsi.smem_len;
+ sdev->lcd_offset = 0;
+ sdev->lcd_phys = fsi.smem_start;
+#if 0
+ sdrv->lcd_virt = mmap(NULL, fsi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED,
+ fbdev, 0);
+ if (sdrv->lcd_virt == MAP_FAILED) {
+ D_PERROR( "SH7722/Driver: mapping fbdev failed.\n" );
+ close(fbdev);
+ return DFB_FAILURE;
+ }
+
+ /* Clear LCD buffer. */
+ switch (sdev->lcd_format) {
+ case DSPF_RGB16:
+ memset( (void*) sdrv->lcd_virt, 0x00, sdev->lcd_height * sdev->lcd_pitch );
+ break;
+
+ case DSPF_NV16:
+ memset( (void*) sdrv->lcd_virt, 0x10, sdev->lcd_height * sdev->lcd_pitch );
+ memset( (void*) sdrv->lcd_virt + sdev->lcd_height * sdev->lcd_pitch, 0x80, sdev->lcd_height * sdev->lcd_pitch );
+ break;
+
+ default:
+ D_BUG( "unsupported format" );
+ return DFB_BUG;
+ }
+#endif
+
+ close(fbdev);
+ }
+#else
+ sdev->lcd_width = SH7722_LCD_WIDTH;
+ sdev->lcd_height = SH7722_LCD_HEIGHT;
+ sdev->lcd_pitch = (DFB_BYTES_PER_LINE( sdev->lcd_format, sdev->lcd_width ) + 0xf) & ~0xf;
+ sdev->lcd_size = DFB_PLANE_MULTIPLY( sdev->lcd_format, sdev->lcd_height ) * sdev->lcd_pitch;
+ sdev->lcd_offset = dfb_gfxcard_reserve_memory( device, sdev->lcd_size );
+
+ if (sdev->lcd_offset < 0) {
+ D_ERROR( "SH7722/Driver: Allocating %d bytes for the LCD buffer failed!\n", sdev->lcd_size );
+ return DFB_FAILURE;
+ }
+
+ sdev->lcd_phys = dfb_gfxcard_memory_physical( device, sdev->lcd_offset );
+
+ /* Get virtual addresses for LCD buffer in master here,
+ slaves do it in driver_init_driver(). */
+ sdrv->lcd_virt = dfb_gfxcard_memory_virtual( device, sdev->lcd_offset );
+#endif
+
+ D_INFO( "SH7722/LCD: Allocated %dx%d %s Buffer (%d bytes) at 0x%08lx (%p)\n",
+ sdev->lcd_width, sdev->lcd_height, dfb_pixelformat_name(sdev->lcd_format),
+ sdev->lcd_size, sdev->lcd_phys, sdrv->lcd_virt );
+
+ D_ASSERT( ! (sdev->lcd_pitch & 0xf) );
+ D_ASSERT( ! (sdev->lcd_phys & 0xf) );
+
+ /*
+ * Initialize hardware.
+ */
+
+ switch (sdev->sh772x) {
+ case 7722:
+ /* Reset the drawing engine. */
+ sh7722EngineReset( sdrv, sdev );
+
+ /* Fill in the device info. */
+ snprintf( device_info->name, DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "SH7722" );
+ snprintf( device_info->vendor, DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "Renesas" );
+
+ /* Set device limitations. */
+ device_info->limits.surface_byteoffset_alignment = 16;
+ device_info->limits.surface_bytepitch_alignment = 8;
+
+ /* Set device capabilities. */
+ device_info->caps.flags = CCF_CLIPPING | CCF_RENDEROPTS;
+ device_info->caps.accel = SH7722_SUPPORTED_DRAWINGFUNCTIONS |
+ SH7722_SUPPORTED_BLITTINGFUNCTIONS;
+ device_info->caps.drawing = SH7722_SUPPORTED_DRAWINGFLAGS;
+ device_info->caps.blitting = SH7722_SUPPORTED_BLITTINGFLAGS;
+
+ /* Change font format for acceleration. */
+ if (!dfb_config->software_only) {
+ dfb_config->font_format = DSPF_ARGB;
+ dfb_config->font_premult = false;
+ }
+ break;
+
+ case 7723:
+ /* Reset the drawing engine. */
+ sh7723EngineReset( sdrv, sdev );
+
+ /* Fill in the device info. */
+ snprintf( device_info->name, DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "SH7723" );
+ snprintf( device_info->vendor, DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "Renesas" );
+
+ /* Set device limitations. */
+ device_info->limits.surface_byteoffset_alignment = 512;
+ device_info->limits.surface_bytepitch_alignment = 64;
+
+ /* Set device capabilities. */
+ device_info->caps.flags = CCF_CLIPPING | CCF_RENDEROPTS;
+ device_info->caps.accel = SH7723_SUPPORTED_DRAWINGFUNCTIONS | \
+ SH7723_SUPPORTED_BLITTINGFUNCTIONS;
+ device_info->caps.drawing = SH7723_SUPPORTED_DRAWINGFLAGS;
+ device_info->caps.blitting = SH7723_SUPPORTED_BLITTINGFLAGS;
+
+ break;
+
+ default:
+ D_BUG( "unexpected device" );
+ return DFB_BUG;
+ }
+
+
+ /* Wait for idle BEU. */
+ while (SH7722_GETREG32( sdrv, BSTAR ) & 1);
+
+ /* Disable all inputs. */
+ SH7722_SETREG32( sdrv, BESTR, 0 );
+
+ /* Disable all multi windows. */
+ SH7722_SETREG32( sdrv, BMWCR0, SH7722_GETREG32( sdrv, BMWCR0 ) & ~0xf );
+
+#ifndef SH772X_FBDEV_SUPPORT
+ /* Clear LCD buffer. */
+ switch (sdev->lcd_format) {
+ case DSPF_RGB16:
+ memset( (void*) sdrv->lcd_virt, 0x00, sdev->lcd_height * sdev->lcd_pitch );
+ break;
+
+ case DSPF_NV16:
+ memset( (void*) sdrv->lcd_virt, 0x10, sdev->lcd_height * sdev->lcd_pitch );
+ memset( (void*) sdrv->lcd_virt + sdev->lcd_height * sdev->lcd_pitch, 0x80, sdev->lcd_height * sdev->lcd_pitch );
+ break;
+
+ default:
+ D_BUG( "unsupported format" );
+ return DFB_BUG;
+ }
+#endif
+
+ /*
+ * TODO: Make LCD Buffer format and primary BEU format runtime configurable.
+ */
+
+ /* Set output pixel format of the BEU. */
+ switch (sdev->lcd_format) {
+ case DSPF_RGB16:
+ SH7722_SETREG32( sdrv, BPKFR, BPKFR_RY_RGB | WPCK_RGB16 );
+ break;
+
+ case DSPF_NV16:
+ SH7722_SETREG32( sdrv, BPKFR, BPKFR_RY_RGB | BPKFR_TE_ENABLED | CHDS_YCBCR422 );
+ SH7722_SETREG32( sdrv, BDACR, sdev->lcd_phys + sdev->lcd_height * sdev->lcd_pitch );
+ break;
+
+ default:
+ D_BUG( "unsupported format" );
+ return DFB_BUG;
+ }
+
+ SH7722_SETREG32( sdrv, BPROCR, 0x00000000 );
+
+ /* Have BEU render into LCD buffer. */
+ SH7722_SETREG32( sdrv, BBLCR1, MT_MEMORY );
+ SH7722_SETREG32( sdrv, BDAYR, sdev->lcd_phys & 0xfffffffc );
+ SH7722_SETREG32( sdrv, BDMWR, sdev->lcd_pitch & 0x0003fffc );
+
+#ifndef SH772X_FBDEV_SUPPORT
+ /* Setup LCD controller to show the buffer. */
+ sh7722_lcd_setup( sdrv, sdev->lcd_width, sdev->lcd_height,
+ sdev->lcd_phys, sdev->lcd_pitch, sdev->lcd_format, false );
+#endif
+
+ /* Initialize BEU lock. */
+ fusion_skirmish_init( &sdev->beu_lock, "BEU", dfb_core_world(sdrv->core) );
+
+ return DFB_OK;
+}
+
+static void
+driver_close_device( CoreGraphicsDevice *device,
+ void *driver_data,
+ void *device_data )
+{
+ SH7722DeviceData *sdev = device_data;
+
+ D_DEBUG_AT( SH7722_Driver, "%s()\n", __FUNCTION__ );
+
+ /* Destroy BEU lock. */
+ fusion_skirmish_destroy( &sdev->beu_lock );
+}
+
+static void
+driver_close_driver( CoreGraphicsDevice *device,
+ void *driver_data )
+{
+ SH7722DriverData *sdrv = driver_data;
+ SH772xGfxSharedArea *shared = sdrv->gfx_shared;
+
+ (void) shared;
+
+ D_DEBUG_AT( SH7722_Driver, "%s()\n", __FUNCTION__ );
+
+ D_INFO( "SH7722/BLT: %u starts, %u done, %u interrupts, %u wait_idle, %u wait_next, %u idle\n",
+ shared->num_starts, shared->num_done, shared->num_interrupts,
+ shared->num_wait_idle, shared->num_wait_next, shared->num_idle );
+
+ D_INFO( "SH7722/BLT: %u words, %u words/start, %u words/idle, %u starts/idle\n",
+ shared->num_words,
+ shared->num_words / shared->num_starts,
+ shared->num_words / shared->num_idle,
+ shared->num_starts / shared->num_idle );
+
+ /* Shutdown JPEG library. */
+ SH7722_JPEG_Shutdown();
+
+ /* Unmap shared area. */
+ munmap( (void*) sdrv->gfx_shared, direct_page_align( sizeof(SH772xGfxSharedArea) ) );
+
+ /* Close Drawing Engine device. */
+ close( sdrv->gfx_fd );
+}
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722.h b/Source/DirectFB/gfxdrivers/sh772x/sh7722.h
new file mode 100755
index 0000000..0a80512
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722.h
@@ -0,0 +1,131 @@
+#ifndef __SH7722__SH7722_H__
+#define __SH7722__SH7722_H__
+
+#include <sys/ioctl.h>
+
+#include <sh772x_gfx.h>
+
+#include "sh7722_regs.h"
+#include "sh7722_types.h"
+
+
+#define SH772X_FBDEV_SUPPORT
+// #define JPU_SUPPORT
+
+/******************************************************************************
+ * Platform specific values (FIXME: add runtime config)
+ */
+
+#define ALGO_AP325
+#undef SH7722_ALGO_PANEL
+
+/* LCD Panel Configuration */
+#if defined(SH7722_ALGO_PANEL)
+# define SH7722_LCD_WIDTH 640
+# define SH7722_LCD_HEIGHT 480
+#elif defined(ALGO_AP325)
+# define SH7722_LCD_WIDTH 800
+# define SH7722_LCD_HEIGHT 480
+#else
+# define SH7722_LCD_WIDTH 800
+# define SH7722_LCD_HEIGHT 480
+#endif
+
+
+/******************************************************************************
+ * Register access
+ */
+
+//#define SH7722_TDG_REG_USE_IOCTLS
+
+#ifdef SH7722_TDG_REG_USE_IOCTLS
+static inline u32
+SH7722_TDG_GETREG32( SH7722DriverData *sdrv,
+ u32 address )
+{
+ SH772xRegister reg = { address, 0 };
+
+ if (ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_GETREG32, &reg ) < 0)
+ D_PERROR( "SH772xGFX_IOCTL_GETREG32( 0x%08x )\n", reg.address );
+
+ return reg.value;
+}
+
+static inline void
+SH7722_TDG_SETREG32( SH7722DriverData *sdrv,
+ u32 address,
+ u32 value )
+{
+ SH772xRegister reg = { address, value };
+
+ if (ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_SETREG32, &reg ) < 0)
+ D_PERROR( "SH772xGFX_IOCTL_SETREG32( 0x%08x, 0x%08x )\n", reg.address, reg.value );
+}
+#else
+static inline u32
+SH7722_TDG_GETREG32( SH7722DriverData *sdrv,
+ u32 address )
+{
+ D_ASSERT( address >= dfb_config->mmio_phys );
+ D_ASSERT( address < (dfb_config->mmio_phys + dfb_config->mmio_length) );
+
+ return *(volatile u32*)(sdrv->mmio_base + (address - dfb_config->mmio_phys));
+}
+
+static inline void
+SH7722_TDG_SETREG32( SH7722DriverData *sdrv,
+ u32 address,
+ u32 value )
+{
+ D_ASSERT( address >= dfb_config->mmio_phys );
+ D_ASSERT( address < (dfb_config->mmio_phys + dfb_config->mmio_length) );
+
+ *(volatile u32*)(sdrv->mmio_base + (address - dfb_config->mmio_phys)) = value;
+}
+#endif
+
+
+static inline u32
+SH7722_GETREG32( SH7722DriverData *sdrv,
+ u32 address )
+{
+ SH772xRegister reg = { address, 0 };
+
+ if (ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_GETREG32, &reg ) < 0)
+ D_PERROR( "SH772xGFX_IOCTL_GETREG32( 0x%08x )\n", reg.address );
+
+ return reg.value;
+}
+
+static inline void
+SH7722_SETREG32( SH7722DriverData *sdrv,
+ u32 address,
+ u32 value )
+{
+ SH772xRegister reg = { address, value };
+
+ if (ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_SETREG32, &reg ) < 0)
+ D_PERROR( "SH772xGFX_IOCTL_SETREG32( 0x%08x, 0x%08x )\n", reg.address, reg.value );
+}
+
+
+static inline void
+BEU_Start( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev )
+{
+ /* Wait for idle BEU. */
+ while (SH7722_GETREG32( sdrv, BSTAR ) & 1);
+
+ /* Start operation! */
+ SH7722_SETREG32( sdrv, BESTR, (sdev->input_mask << 8) | 1 );
+}
+
+static inline void
+BEU_Wait( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev )
+{
+ /* Wait for idle BEU. */
+ while (SH7722_GETREG32( sdrv, BSTAR ) & 1);
+}
+
+#endif
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_blt.c b/Source/DirectFB/gfxdrivers/sh772x/sh7722_blt.c
new file mode 100755
index 0000000..ec373f8
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_blt.c
@@ -0,0 +1,2013 @@
+#ifdef SH7722_DEBUG_BLT
+#define DIRECT_ENABLE_DEBUG
+#endif
+
+
+#include <config.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <malloc.h>
+#include <errno.h>
+
+#include <asm/types.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/memcpy.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/surface.h>
+#include <core/surface_buffer.h>
+
+#include <gfx/convert.h>
+
+#include "sh7722.h"
+#include "sh7722_blt.h"
+
+
+D_DEBUG_DOMAIN( SH7722_BLT, "SH7722/BLT", "Renesas SH7722 Drawing Engine" );
+
+D_DEBUG_DOMAIN( SH7722_StartStop, "SH7722/StartStop", "Renesas SH7722 Drawing Start/Stop" );
+
+/*
+ * State validation flags.
+ *
+ * There's no prefix because of the macros below.
+ */
+enum {
+ DEST = 0x00000001,
+ CLIP = 0x00000002,
+ DEST_CLIP = 0x00000003,
+
+ SOURCE = 0x00000010,
+ MASK = 0x00000020,
+
+ COLOR = 0x00000100,
+
+ COLOR_KEY = 0x00001000,
+ COLOR_CHANGE = 0x00002000,
+
+ BLENDING = 0x00010000,
+
+ MATRIX = 0x00100000,
+
+ BLIT_OP = 0x01000000,
+
+ ALL = 0x01113133
+};
+
+/*
+ * Map pixel formats.
+ */
+static int pixel_formats[DFB_NUM_PIXELFORMATS];
+
+__attribute__((constructor)) static void initialization( void )
+{
+ D_DEBUG_AT( SH7722_BLT, "%s()\n", __FUNCTION__ );
+
+ pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_RGB32) ] = 0;
+ pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_ARGB) ] = 0;
+ pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_RGB16) ] = 1;
+ pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_RGB555) ] = 2;
+ pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_ARGB1555)] = 3;
+ pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)] = 4;
+ pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_RGB444) ] = 4;
+ pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_RGB18) ] = 6;
+ pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_ARGB1666)] = 6;
+ pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_ARGB6666)] = 6;
+ pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_RGB24) ] = 7;
+ pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_A1) ] = 8;
+ pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_A8) ] = 10;
+}
+
+/*
+ * State handling macros.
+ */
+
+#define SH7722_VALIDATE(flags) do { sdev->v_flags |= (flags); } while (0)
+#define SH7722_INVALIDATE(flags) do { sdev->v_flags &= ~(flags); } while (0)
+
+#define SH7722_CHECK_VALIDATE(flag) do { \
+ if ((sdev->v_flags & flag) != flag) \
+ sh7722_validate_##flag( sdrv, sdev, state ); \
+ } while (0)
+
+#define DUMP_INFO() D_DEBUG_AT( SH7722_BLT, " -> %srunning, hw %d-%d, next %d-%d - %svalid\n", \
+ sdrv->gfx_shared->hw_running ? "" : "not ", \
+ sdrv->gfx_shared->hw_start, \
+ sdrv->gfx_shared->hw_end, \
+ sdrv->gfx_shared->next_start, \
+ sdrv->gfx_shared->next_end, \
+ sdrv->gfx_shared->next_valid ? "" : "not " );
+
+#define AA_COEF 133
+
+/**********************************************************************************************************************/
+
+static bool sh7722FillRectangle ( void *drv, void *dev, DFBRectangle *rect );
+static bool sh7722FillRectangleMatrixAA( void *drv, void *dev, DFBRectangle *rect );
+
+static bool sh7722DrawRectangle ( void *drv, void *dev, DFBRectangle *rect );
+static bool sh7722DrawRectangleMatrixAA( void *drv, void *dev, DFBRectangle *rect );
+
+static bool sh7722DrawLine ( void *drv, void *dev, DFBRegion *line );
+static bool sh7722DrawLineMatrix ( void *drv, void *dev, DFBRegion *line );
+static bool sh7722DrawLineAA ( void *drv, void *dev, DFBRegion *line );
+
+/**********************************************************************************************************************/
+
+static inline bool
+check_blend_functions( const CardState *state )
+{
+ switch (state->src_blend) {
+ case DSBF_ZERO:
+ case DSBF_ONE:
+ case DSBF_DESTCOLOR:
+ case DSBF_INVDESTCOLOR:
+ case DSBF_SRCALPHA:
+ case DSBF_INVSRCALPHA:
+ case DSBF_DESTALPHA:
+ case DSBF_INVDESTALPHA:
+ return true;
+
+ default:
+ break;
+ }
+ switch (state->dst_blend) {
+ case DSBF_ZERO:
+ case DSBF_ONE:
+ case DSBF_SRCCOLOR:
+ case DSBF_INVSRCCOLOR:
+ case DSBF_SRCALPHA:
+ case DSBF_INVSRCALPHA:
+ case DSBF_DESTALPHA:
+ case DSBF_INVDESTALPHA:
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+/**********************************************************************************************************************/
+
+static inline bool
+start_hardware( SH7722DriverData *sdrv )
+{
+ SH772xGfxSharedArea *shared = sdrv->gfx_shared;
+
+ D_DEBUG_AT( SH7722_BLT, "%s()\n", __FUNCTION__ );
+
+ DUMP_INFO();
+
+ if (shared->hw_running || !shared->next_valid || shared->next_end == shared->next_start)
+ return false;
+
+ shared->hw_running = true;
+ shared->hw_start = shared->next_start;
+ shared->hw_end = shared->next_end;
+
+ shared->next_start = shared->next_end = (shared->hw_end + 1 + 3) & ~3;
+ shared->next_valid = false;
+
+ shared->num_words += shared->hw_end - shared->hw_start;
+
+ shared->num_starts++;
+
+ DUMP_INFO();
+
+ D_ASSERT( shared->buffer[shared->hw_end] == 0xF0000000 );
+
+ SH7722_TDG_SETREG32( sdrv, BEM_HC_DMA_ADR, shared->buffer_phys + shared->hw_start*4 );
+ SH7722_TDG_SETREG32( sdrv, BEM_HC_DMA_START, 1 );
+
+ return true;
+}
+
+__attribute__((noinline))
+static void
+flush_prepared( SH7722DriverData *sdrv )
+{
+ SH772xGfxSharedArea *shared = sdrv->gfx_shared;
+ unsigned int timeout = 2;
+
+ D_DEBUG_AT( SH7722_BLT, "%s()\n", __FUNCTION__ );
+
+ DUMP_INFO();
+
+ D_ASSERT( sdrv->prep_num < SH772xGFX_BUFFER_WORDS );
+ D_ASSERT( sdrv->prep_num <= D_ARRAY_SIZE(sdrv->prep_buf) );
+
+ /* Something prepared? */
+ while (sdrv->prep_num) {
+ int next_end;
+
+ /* Mark shared information as invalid. From this point on the interrupt handler
+ * will not continue with the next block, and we'll start the hardware ourself. */
+ shared->next_valid = false;
+
+ /* Check if there's enough space at the end.
+ * Wait until hardware has started next block before it gets too big. */
+ if (shared->next_end + sdrv->prep_num >= SH772xGFX_BUFFER_WORDS ||
+ shared->next_end - shared->next_start >= SH772xGFX_BUFFER_WORDS/4)
+ {
+ /* If there's no next block waiting, start at the beginning. */
+ if (shared->next_start == shared->next_end)
+ shared->next_start = shared->next_end = 0;
+ else {
+ D_ASSERT( shared->buffer[shared->hw_end] == 0xF0000000 );
+
+ /* Mark area as valid again. */
+ shared->next_valid = true;
+
+ /* Start in case it got idle while doing the checks. */
+ if (!start_hardware( sdrv )) {
+ /*
+ * Hardware has not been started (still running).
+ * Check for timeout. */
+ if (!timeout--) {
+ D_ERROR( "SH7722/Blt: Timeout waiting for processing!\n" );
+ direct_log_printf( NULL, " -> %srunning, hw %d-%d, next %d-%d - %svalid\n", \
+ sdrv->gfx_shared->hw_running ? "" : "not ", \
+ sdrv->gfx_shared->hw_start, \
+ sdrv->gfx_shared->hw_end, \
+ sdrv->gfx_shared->next_start, \
+ sdrv->gfx_shared->next_end, \
+ sdrv->gfx_shared->next_valid ? "" : "not " );
+ D_ASSERT( shared->buffer[shared->hw_end] == 0xF0000000 );
+ sh7722EngineReset( sdrv, sdrv->dev );
+ }
+
+ /* Wait til next block is started. */
+ ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_WAIT_NEXT );
+ }
+
+ /* Start over with the checks. */
+ continue;
+ }
+ }
+
+ /* We are appending in case there was already a next block. */
+ next_end = shared->next_end + sdrv->prep_num;
+
+ /* Reset the timeout counter. */
+ timeout = 2;
+
+ /* While the hardware is running... */
+ while (shared->hw_running) {
+ D_ASSERT( shared->buffer[shared->hw_end] == 0xF0000000 );
+
+ /* ...make sure we don't over lap with its current buffer, otherwise wait. */
+ if (shared->hw_start > next_end || shared->hw_end < shared->next_start)
+ break;
+
+ /* Check for timeout. */
+ if (!timeout--) {
+ D_ERROR( "SH7722/Blt: Timeout waiting for space!\n" );
+ direct_log_printf( NULL, " -> %srunning, hw %d-%d, next %d-%d - %svalid\n", \
+ sdrv->gfx_shared->hw_running ? "" : "not ", \
+ sdrv->gfx_shared->hw_start, \
+ sdrv->gfx_shared->hw_end, \
+ sdrv->gfx_shared->next_start, \
+ sdrv->gfx_shared->next_end, \
+ sdrv->gfx_shared->next_valid ? "" : "not " );
+ D_ASSERT( shared->buffer[shared->hw_end] == 0xF0000000 );
+ sh7722EngineReset( sdrv, sdrv->dev );
+ }
+
+ /* Wait til next block is started. */
+ ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_WAIT_NEXT );
+ }
+
+ /* Copy from local to shared buffer. */
+ direct_memcpy( (void*) &shared->buffer[shared->next_end], &sdrv->prep_buf[0], sdrv->prep_num * sizeof(__u32) );
+
+ /* Terminate the block. */
+ shared->buffer[next_end] = 0xF0000000;
+
+ /* Update next block information and mark valid. */
+ shared->next_end = next_end;
+ shared->next_valid = true;
+
+ /* Reset local counter. */
+ sdrv->prep_num = 0;
+ }
+
+ /* Start in case it is idle. */
+ start_hardware( sdrv );
+}
+
+static inline __u32 *
+start_buffer( SH7722DriverData *sdrv,
+ int space )
+{
+ /* Check for space in local buffer. */
+ if (sdrv->prep_num + space > SH7722GFX_MAX_PREPARE) {
+ /* Flush local buffer. */
+ flush_prepared( sdrv );
+
+ D_ASSERT( sdrv->prep_num == 0 );
+ }
+
+ /* Return next write position. */
+ return &sdrv->prep_buf[sdrv->prep_num];
+}
+
+static inline void
+submit_buffer( SH7722DriverData *sdrv,
+ int entries )
+{
+ D_ASSERT( sdrv->prep_num + entries <= SH7722GFX_MAX_PREPARE );
+
+ /* Increment next write position. */
+ sdrv->prep_num += entries;
+}
+
+/**********************************************************************************************************************/
+
+static inline void
+sh7722_validate_DEST_CLIP( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev,
+ CardState *state )
+{
+ __u32 *prep = start_buffer( sdrv, 10 );
+
+ D_DEBUG_AT( SH7722_BLT, "%s( 0x%08lx [%d] - %4d,%4d-%4dx%4d )\n", __FUNCTION__,
+ state->dst.phys, state->dst.pitch, DFB_RECTANGLE_VALS_FROM_REGION( &state->clip ) );
+
+ /* Set clip. */
+ prep[0] = BEM_PE_SC0_MIN;
+ prep[1] = SH7722_XY( state->clip.x1, state->clip.y1 );
+
+ prep[2] = BEM_PE_SC0_MAX;
+ prep[3] = SH7722_XY( state->clip.x2, state->clip.y2 );
+
+ /* Only clip? */
+ if (sdev->v_flags & DEST) {
+ submit_buffer( sdrv, 4 );
+ }
+ else {
+ CoreSurface *surface = state->destination;
+ CoreSurfaceBuffer *buffer = state->dst.buffer;
+
+ sdev->dst_phys = state->dst.phys;
+ sdev->dst_pitch = state->dst.pitch;
+ sdev->dst_bpp = DFB_BYTES_PER_PIXEL( buffer->format );
+ sdev->dst_index = DFB_PIXELFORMAT_INDEX( buffer->format ) % DFB_NUM_PIXELFORMATS;
+
+ /* Set destination. */
+ prep[4] = BEM_PE_DST;
+ prep[5] = pixel_formats[sdev->dst_index];
+
+ prep[6] = BEM_PE_DST_BASE;
+ prep[7] = sdev->dst_phys;
+
+ prep[8] = BEM_PE_DST_SIZE;
+ prep[9] = SH7722_XY( sdev->dst_pitch / sdev->dst_bpp, surface->config.size.h );
+
+ submit_buffer( sdrv, 10 );
+ }
+
+ /* Set the flags. */
+ SH7722_VALIDATE( DEST_CLIP );
+}
+
+static inline void
+sh7722_validate_SOURCE( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev,
+ CardState *state )
+{
+ CoreSurface *surface = state->source;
+ CoreSurfaceBuffer *buffer = state->src.buffer;
+ __u32 *prep = start_buffer( sdrv, 6 );
+
+ sdev->src_phys = state->src.phys;
+ sdev->src_pitch = state->src.pitch;
+ sdev->src_bpp = DFB_BYTES_PER_PIXEL( buffer->format );
+ sdev->src_index = DFB_PIXELFORMAT_INDEX( buffer->format ) % DFB_NUM_PIXELFORMATS;
+
+ /* Set source. */
+ prep[0] = BEM_TE_SRC;
+ prep[1] = pixel_formats[sdev->src_index];
+
+ prep[2] = BEM_TE_SRC_BASE;
+ prep[3] = sdev->src_phys;
+
+ prep[4] = BEM_TE_SRC_SIZE;
+ prep[5] = SH7722_XY( sdev->src_pitch / sdev->src_bpp, surface->config.size.h );
+
+ submit_buffer( sdrv, 6 );
+
+ /* Set the flag. */
+ SH7722_VALIDATE( SOURCE );
+}
+
+__attribute__((noinline))
+static void
+sh7722_validate_MASK( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev,
+ CardState *state )
+{
+ CoreSurface *surface = state->source_mask;
+ CoreSurfaceBuffer *buffer = state->src_mask.buffer;
+ __u32 *prep = start_buffer( sdrv, 6 );
+
+ sdev->mask_phys = state->src_mask.phys;
+ sdev->mask_pitch = state->src_mask.pitch;
+ sdev->mask_format = buffer->format;
+ sdev->mask_index = DFB_PIXELFORMAT_INDEX( buffer->format ) % DFB_NUM_PIXELFORMATS;
+ sdev->mask_offset = state->src_mask_offset;
+ sdev->mask_flags = state->src_mask_flags;
+
+ /* Set mask. */
+ prep[0] = BEM_TE_MASK;
+ prep[1] = TE_MASK_ENABLE | pixel_formats[sdev->mask_index];
+
+ prep[2] = BEM_TE_MASK_SIZE;
+ prep[3] = SH7722_XY( sdev->mask_pitch / DFB_BYTES_PER_PIXEL(sdev->mask_format), surface->config.size.h );
+
+ prep[4] = BEM_TE_MASK_BASE;
+ prep[5] = sdev->mask_phys + sdev->mask_pitch * sdev->mask_offset.y +
+ DFB_BYTES_PER_LINE( sdev->mask_format, sdev->mask_offset.x );
+
+ submit_buffer( sdrv, 6 );
+
+ /* Set the flag. */
+ SH7722_VALIDATE( MASK );
+}
+
+static inline void
+sh7722_validate_COLOR( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev,
+ CardState *state )
+{
+ __u32 *prep = start_buffer( sdrv, 4 );
+
+ prep[0] = BEM_BE_COLOR1;
+ prep[1] = PIXEL_ARGB( state->color.a,
+ state->color.r,
+ state->color.g,
+ state->color.b );
+
+ prep[2] = BEM_WR_FGC;
+ prep[3] = prep[1];
+
+ submit_buffer( sdrv, 4 );
+
+ /* Set the flag. */
+ SH7722_VALIDATE( COLOR );
+}
+
+__attribute__((noinline))
+static void
+sh7722_validate_COLOR_KEY( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev,
+ CardState *state )
+{
+ CoreSurfaceBuffer *buffer = state->src.buffer;
+ __u32 *prep = start_buffer( sdrv, 4 );
+
+ prep[0] = BEM_PE_CKEY;
+ prep[1] = CKEY_EXCLUDE_ALPHA | CKEY_EXCLUDE_UNUSED | CKEY_B_ENABLE;
+
+ prep[2] = BEM_PE_CKEY_B;
+
+ switch (buffer->format) {
+ case DSPF_ARGB:
+ case DSPF_RGB32:
+ prep[3] = state->src_colorkey;
+ break;
+
+ case DSPF_RGB16:
+ prep[3] = RGB16_TO_RGB32( state->src_colorkey );
+ break;
+
+ case DSPF_ARGB1555:
+ case DSPF_RGB555:
+ prep[3] = ARGB1555_TO_RGB32( state->src_colorkey );
+ break;
+
+ case DSPF_ARGB4444:
+ case DSPF_RGB444:
+ prep[3] = ARGB4444_TO_RGB32( state->src_colorkey );
+ break;
+
+ default:
+ D_BUG( "unexpected pixelformat" );
+ }
+
+ submit_buffer( sdrv, 4 );
+
+ /* Set the flag. */
+ SH7722_VALIDATE( COLOR_KEY );
+}
+
+/* let compiler decide here :) */
+static void
+sh7722_validate_COLOR_CHANGE( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev,
+ CardState *state )
+{
+ __u32 *prep = start_buffer( sdrv, 6 );
+
+ prep[0] = BEM_PE_COLORCHANGE;
+ prep[1] = COLORCHANGE_COMPARE_FIRST | COLORCHANGE_EXCLUDE_UNUSED;
+
+ prep[2] = BEM_PE_COLORCHANGE_0;
+ prep[3] = 0xffffff;
+
+ prep[4] = BEM_PE_COLORCHANGE_1;
+ prep[5] = PIXEL_ARGB( state->color.a,
+ state->color.r,
+ state->color.g,
+ state->color.b );
+
+ submit_buffer( sdrv, 6 );
+
+ /* Set the flag. */
+ SH7722_VALIDATE( COLOR_CHANGE );
+}
+
+/* DSBF_UNKNOWN = 0 */
+/* BLE_DSTF_ZERO = 0 DSBF_ZERO = 1 */
+/* BLE_DSTF_ONE = 1 DSBF_ONE = 2 */
+/* BLE_DSTF_SRC = 2 DSBF_SRCCOLOR = 3 */
+/* BLE_DSTF_1_SRC = 3 DSBF_INVSRCCOLOR = 4 */
+/* BLE_DSTF_SRC_A = 4 DSBF_SRCALPHA = 5 */
+/* BLE_DSTF_1_SRC_A = 5 DSBF_INVSRCALPHA = 6 */
+/* BLE_DSTF_DST_A = 6 DSBF_DESTALPHA = 7 */
+/* BLE_DSTF_1_DST_A = 7 DSBF_INVDESTALPHA = 8 */
+/* DSBF_DESTCOLOR = 9 */
+/* Hey, matches!!? :-P DSBF_INVDESTCOLOR = 10 */
+/* DSBF_SRCALPHASAT = 11 */
+
+static inline void
+sh7722_validate_BLENDING( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev,
+ CardState *state )
+{
+ __u32 *prep = start_buffer( sdrv, 2 );
+
+ sdev->ble_dstf = (state->dst_blend - 1) & 7;
+ sdev->ble_srcf = ((state->src_blend - 1) & 7) << 4;
+
+ prep[0] = BEM_PE_FIXEDALPHA;
+ prep[1] = (state->color.a << 24) | (state->color.a << 16);
+
+ submit_buffer( sdrv, 2 );
+
+ /* Set the flag. */
+ SH7722_VALIDATE( BLENDING );
+}
+
+__attribute__((noinline))
+static void
+sh7722_validate_MATRIX( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev,
+ CardState *state )
+{
+ __u32 *prep = start_buffer( sdrv, 12 );
+
+ prep[0] = BEM_BE_MATRIX_A;
+ prep[1] = state->matrix[0];
+
+ prep[2] = BEM_BE_MATRIX_B;
+ prep[3] = state->matrix[1];
+
+ prep[4] = BEM_BE_MATRIX_C;
+ prep[5] = state->matrix[2];
+
+ prep[6] = BEM_BE_MATRIX_D;
+ prep[7] = state->matrix[3];
+
+ prep[8] = BEM_BE_MATRIX_E;
+ prep[9] = state->matrix[4];
+
+ prep[10] = BEM_BE_MATRIX_F;
+ prep[11] = state->matrix[5];
+
+ submit_buffer( sdrv, 12 );
+
+ /* Keep for CPU transformation of lines. */
+ direct_memcpy( sdev->matrix, state->matrix, sizeof(s32) * 6 );
+
+ /* Set the flag. */
+ SH7722_VALIDATE( MATRIX );
+}
+
+static inline void
+sh7722_validate_BLIT_OP( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev,
+ CardState *state )
+{
+ __u32 *prep = start_buffer( sdrv, 2 );
+
+ prep[0] = BEM_PE_OPERATION;
+ prep[1] = BLE_FUNC_NONE;
+
+ if (state->blittingflags & DSBLIT_XOR)
+ prep[1] |= BLE_ROP_XOR;
+
+ if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
+ prep[1] |= BLE_FUNC_AxB_plus_CxD | sdev->ble_srcf | sdev->ble_dstf;
+
+ switch (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
+ case DSBLIT_BLEND_ALPHACHANNEL:
+ prep[1] |= BLE_SRCA_SOURCE_ALPHA;
+ break;
+
+ case DSBLIT_BLEND_COLORALPHA:
+ prep[1] |= BLE_SRCA_FIXED;
+ break;
+ }
+ }
+ else if (state->blittingflags & DSBLIT_SRC_MASK_ALPHA)
+ prep[1] |= BLE_FUNC_AxB_plus_CxD | BLE_SRCA_ALPHA_CHANNEL | BLE_SRCF_SRC_A | BLE_DSTF_1_SRC_A;
+
+ submit_buffer( sdrv, 2 );
+
+ /* Set the flag. */
+ SH7722_VALIDATE( BLIT_OP );
+}
+
+/**********************************************************************************************************************/
+
+__attribute__((noinline))
+static void
+invalidate_ckey( SH7722DriverData *sdrv, SH7722DeviceData *sdev )
+{
+ __u32 *prep = start_buffer( sdrv, 4 );
+
+ prep[0] = BEM_PE_CKEY;
+ prep[1] = 0;
+
+ prep[2] = BEM_PE_CKEY_B;
+ prep[3] = 0;
+
+ submit_buffer( sdrv, 4 );
+
+ sdev->ckey_b_enabled = false;
+
+ SH7722_INVALIDATE( COLOR_KEY );
+}
+
+__attribute__((noinline))
+static void
+invalidate_color_change( SH7722DriverData *sdrv, SH7722DeviceData *sdev )
+{
+ __u32 *prep = start_buffer( sdrv, 2 );
+
+ prep[0] = BEM_PE_COLORCHANGE;
+ prep[1] = COLORCHANGE_DISABLE;
+
+ submit_buffer( sdrv, 2 );
+
+ sdev->color_change_enabled = false;
+
+ SH7722_INVALIDATE( COLOR_CHANGE );
+}
+
+__attribute__((noinline))
+static void
+invalidate_mask( SH7722DriverData *sdrv, SH7722DeviceData *sdev )
+{
+ u32 *prep = start_buffer( sdrv, 2 );
+
+ prep[0] = BEM_TE_MASK;
+ prep[1] = TE_MASK_DISABLE;
+
+ submit_buffer( sdrv, 2 );
+
+ sdev->mask_enabled = false;
+
+ SH7722_INVALIDATE( MASK );
+}
+
+/**********************************************************************************************************************/
+
+DFBResult
+sh7722EngineSync( void *drv, void *dev )
+{
+ DFBResult ret = DFB_OK;
+ SH7722DriverData *sdrv = drv;
+ SH772xGfxSharedArea *shared = sdrv->gfx_shared;
+
+ D_DEBUG_AT( SH7722_BLT, "%s()\n", __FUNCTION__ );
+
+ DUMP_INFO();
+
+ while (shared->hw_running && ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_WAIT_IDLE ) < 0) {
+ if (errno == EINTR)
+ continue;
+
+ ret = errno2result( errno );
+ D_PERROR( "SH7722/BLT: SH7722GFX_IOCTL_WAIT_IDLE failed!\n" );
+
+ direct_log_printf( NULL, " -> %srunning, hw %d-%d, next %d-%d - %svalid\n", \
+ sdrv->gfx_shared->hw_running ? "" : "not ", \
+ sdrv->gfx_shared->hw_start, \
+ sdrv->gfx_shared->hw_end, \
+ sdrv->gfx_shared->next_start, \
+ sdrv->gfx_shared->next_end, \
+ sdrv->gfx_shared->next_valid ? "" : "not " );
+
+ break;
+ }
+
+ if (ret == DFB_OK) {
+ D_ASSERT( !shared->hw_running );
+ D_ASSERT( !shared->next_valid );
+ }
+
+ return ret;
+}
+
+void
+sh7722EngineReset( void *drv, void *dev )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+ __u32 *prep;
+
+ D_DEBUG_AT( SH7722_BLT, "%s()\n", __FUNCTION__ );
+
+ DUMP_INFO();
+
+ ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_RESET );
+
+ prep = start_buffer( sdrv, 20 );
+
+ prep[0] = BEM_PE_OPERATION;
+ prep[1] = 0x00000000;
+
+ prep[2] = BEM_PE_COLORCHANGE;
+ prep[3] = 0x00000000;
+
+ prep[4] = BEM_PE_CKEY;
+ prep[5] = 0x00000000;
+
+ prep[6] = BEM_PE_CKEY_B;
+ prep[7] = 0;
+
+ prep[8] = BEM_PE_FIXEDALPHA;
+ prep[9] = 0x80000000;
+
+ prep[10] = BEM_TE_SRC_CNV;
+ prep[11] = 0x00100010; /* full conversion of Ad, As, Cd and Cs */
+
+ prep[12] = BEM_TE_FILTER;
+ prep[13] = 0x00000000; /* 0 = nearest, 3 = up bilinear / down average */
+
+ prep[14] = BEM_PE_SC;
+ prep[15] = 0x00000001; /* enable clipping */
+
+ prep[16] = BEM_BE_ORIGIN;
+ prep[17] = SH7722_XY( 0, 0 );
+
+ prep[18] = BEM_TE_MASK_CNV;
+ prep[19] = 2;
+
+ submit_buffer( sdrv, 20 );
+
+ sdev->ckey_b_enabled = false;
+ sdev->color_change_enabled = false;
+ sdev->mask_enabled = false;
+}
+
+void
+sh7722EmitCommands( void *drv, void *dev )
+{
+ SH7722DriverData *sdrv = drv;
+
+ D_DEBUG_AT( SH7722_BLT, "%s()\n", __FUNCTION__ );
+
+ flush_prepared( sdrv );
+}
+
+void
+sh7722FlushTextureCache( void *drv, void *dev )
+{
+ SH7722DriverData *sdrv = drv;
+ __u32 *prep = start_buffer( sdrv, 4 );
+
+ D_DEBUG_AT( SH7722_BLT, "%s()\n", __FUNCTION__ );
+
+ DUMP_INFO();
+
+ prep[0] = BEM_PE_CACHE;
+ prep[1] = 2;
+
+ prep[2] = BEM_TE_INVALID;
+ prep[3] = 1;
+
+ submit_buffer( sdrv, 4 );
+}
+
+/**********************************************************************************************************************/
+
+void
+sh7722CheckState( void *drv,
+ void *dev,
+ CardState *state,
+ DFBAccelerationMask accel )
+{
+ D_DEBUG_AT( SH7722_BLT, "%s( %p, 0x%08x )\n", __FUNCTION__, state, accel );
+
+ /* Return if the desired function is not supported at all. */
+ if (accel & ~(SH7722_SUPPORTED_DRAWINGFUNCTIONS | SH7722_SUPPORTED_BLITTINGFUNCTIONS))
+ return;
+
+ /* Return if the destination format is not supported. */
+ switch (state->destination->config.format) {
+ case DSPF_ARGB:
+ case DSPF_RGB32:
+ case DSPF_RGB16:
+ case DSPF_ARGB1555:
+ case DSPF_RGB555:
+ case DSPF_ARGB4444:
+ case DSPF_RGB444:
+ break;
+ default:
+ return;
+ }
+
+ /* Check if drawing or blitting is requested. */
+ if (DFB_DRAWING_FUNCTION( accel )) {
+ /* Return if unsupported drawing flags are set. */
+ if (state->drawingflags & ~SH7722_SUPPORTED_DRAWINGFLAGS)
+ return;
+
+ /* Return if blending with unsupported blend functions is requested. */
+ if (state->drawingflags & DSDRAW_BLEND) {
+ /* Check blend functions. */
+ if (!check_blend_functions( state ))
+ return;
+
+ /* XOR only without blending. */
+ if (state->drawingflags & DSDRAW_XOR)
+ return;
+ }
+
+ /* Enable acceleration of drawing functions. */
+ state->accel |= SH7722_SUPPORTED_DRAWINGFUNCTIONS;
+ }
+ else {
+ DFBSurfaceBlittingFlags flags = state->blittingflags;
+
+ /* Return if unsupported blitting flags are set. */
+ if (flags & ~SH7722_SUPPORTED_BLITTINGFLAGS)
+ return;
+
+ /* Return if the source format is not supported. */
+ switch (state->source->config.format) {
+ case DSPF_ARGB:
+ case DSPF_RGB32:
+ case DSPF_RGB16:
+ case DSPF_ARGB1555:
+ case DSPF_RGB555:
+ case DSPF_ARGB4444:
+ case DSPF_RGB444:
+ break;
+
+ default:
+ return;
+ }
+
+ /* Return if blending with unsupported blend functions is requested. */
+ if (flags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
+ /* Check blend functions. */
+ if (!check_blend_functions( state ))
+ return;
+ }
+
+ /* XOR only without blending etc. */
+ if (flags & DSBLIT_XOR &&
+ flags & ~(DSBLIT_SRC_COLORKEY | DSBLIT_ROTATE180 | DSBLIT_XOR))
+ return;
+
+ /* Return if colorizing for non-font surfaces is requested. */
+ if ((flags & DSBLIT_COLORIZE) && !(state->source->type & CSTF_FONT))
+ return;
+
+ /* Return if blending with both alpha channel and value is requested. */
+ if (D_FLAGS_ARE_SET( flags, DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA))
+ return;
+
+ /* Mask checking. */
+ if (flags & DSBLIT_SRC_MASK_ALPHA) {
+ if (!state->source_mask)
+ return;
+
+ /* Return if the source mask format is not supported. */
+ switch (state->source_mask->config.format) {
+ case DSPF_A1:
+ case DSPF_A8:
+ break;
+
+ default:
+ return;
+ }
+ }
+
+ /* Enable acceleration of blitting functions. */
+ state->accel |= SH7722_SUPPORTED_BLITTINGFUNCTIONS;
+ }
+}
+
+/*
+ * Make sure that the hardware is programmed for execution of 'accel' according to the 'state'.
+ */
+void
+sh7722SetState( void *drv,
+ void *dev,
+ GraphicsDeviceFuncs *funcs,
+ CardState *state,
+ DFBAccelerationMask accel )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+ StateModificationFlags modified = state->mod_hw;
+
+ D_DEBUG_AT( SH7722_BLT, "%s( %p, 0x%08x ) <- modified 0x%08x\n",
+ __FUNCTION__, state, accel, modified );
+ DUMP_INFO();
+
+ /*
+ * 1) Invalidate hardware states
+ *
+ * Each modification to the hw independent state invalidates one or more hardware states.
+ */
+
+ /* Simply invalidate all? */
+ if (modified == SMF_ALL) {
+ SH7722_INVALIDATE( ALL );
+ }
+ else if (modified) {
+ /* Invalidate destination registers. */
+ if (modified & SMF_DESTINATION)
+ SH7722_INVALIDATE( DEST );
+
+ /* Invalidate clipping registers. */
+ if (modified & SMF_CLIP)
+ SH7722_INVALIDATE( CLIP );
+
+ /* Invalidate source registers. */
+ if (modified & SMF_SOURCE)
+ SH7722_INVALIDATE( SOURCE | COLOR_KEY );
+ else if (modified & SMF_SRC_COLORKEY)
+ SH7722_INVALIDATE( COLOR_KEY );
+
+ /* Invalidate mask registers. */
+ if (modified & (SMF_SOURCE_MASK | SMF_SOURCE_MASK_VALS))
+ SH7722_INVALIDATE( MASK );
+
+ /* Invalidate color registers. */
+ if (modified & SMF_COLOR)
+ SH7722_INVALIDATE( BLENDING | COLOR | COLOR_CHANGE );
+ else if (modified & (SMF_SRC_BLEND | SMF_SRC_BLEND))
+ SH7722_INVALIDATE( BLENDING );
+
+ /* Invalidate matrix registers. */
+ if (modified & SMF_MATRIX)
+ SH7722_INVALIDATE( MATRIX );
+
+ /* Invalidate blitting operation. */
+ if (modified & SMF_BLITTING_FLAGS)
+ SH7722_INVALIDATE( BLIT_OP );
+ }
+
+ /*
+ * 2) Validate hardware states
+ *
+ * Each function has its own set of states that need to be validated.
+ */
+
+ /* Always requiring valid destination and clip. */
+ SH7722_CHECK_VALIDATE( DEST_CLIP );
+
+ /* Use transformation matrix? */
+ if (state->render_options & DSRO_MATRIX)
+ SH7722_CHECK_VALIDATE( MATRIX );
+
+ /* Depending on the function... */
+ switch (accel) {
+ case DFXL_FILLRECTANGLE:
+ case DFXL_FILLTRIANGLE:
+ case DFXL_DRAWRECTANGLE:
+ case DFXL_DRAWLINE:
+ /* ...require valid color. */
+ SH7722_CHECK_VALIDATE( COLOR );
+
+ /* Use blending? */
+ if (state->drawingflags & DSDRAW_BLEND) {
+ /* need valid source and destination blend factors */
+ SH7722_CHECK_VALIDATE( BLENDING );
+ }
+
+ /* Clear old ckeys */
+ if (sdev->ckey_b_enabled)
+ invalidate_ckey( sdrv, sdev );
+
+ /* Clear old mask */
+ if (sdev->mask_enabled)
+ invalidate_mask( sdrv, sdev );
+
+ /* Choose function. */
+ switch (accel) {
+ case DFXL_FILLRECTANGLE:
+ if (state->render_options & (DSRO_MATRIX | DSRO_ANTIALIAS))
+ funcs->FillRectangle = sh7722FillRectangleMatrixAA;
+ else
+ funcs->FillRectangle = sh7722FillRectangle;
+ break;
+
+ case DFXL_DRAWRECTANGLE:
+ if (state->render_options & (DSRO_MATRIX | DSRO_ANTIALIAS))
+ funcs->DrawRectangle = sh7722DrawRectangleMatrixAA;
+ else
+ funcs->DrawRectangle = sh7722DrawRectangle;
+ break;
+
+ case DFXL_DRAWLINE:
+ if (state->render_options & DSRO_ANTIALIAS)
+ funcs->DrawLine = sh7722DrawLineAA;
+ else if (state->render_options & DSRO_MATRIX)
+ funcs->DrawLine = sh7722DrawLineMatrix;
+ else
+ funcs->DrawLine = sh7722DrawLine;
+ break;
+
+ default:
+ break;
+ }
+
+ /*
+ * 3) Tell which functions can be called without further validation, i.e. SetState()
+ *
+ * When the hw independent state is changed, this collection is reset.
+ */
+ state->set = SH7722_SUPPORTED_DRAWINGFUNCTIONS;
+ break;
+
+ case DFXL_BLIT:
+ case DFXL_STRETCHBLIT:
+ /* ...require valid source. */
+ SH7722_CHECK_VALIDATE( SOURCE );
+
+ /* Use blending? */
+ if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
+ /* need valid source and destination blend factors */
+ SH7722_CHECK_VALIDATE( BLENDING );
+ }
+
+ /* Use color keying? */
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY) {
+ /* Need valid color key settings (enabling). */
+ SH7722_CHECK_VALIDATE( COLOR_KEY );
+
+ sdev->ckey_b_enabled = true;
+ }
+ /* Disable color keying? */
+ else if (sdev->ckey_b_enabled)
+ invalidate_ckey( sdrv, sdev );
+
+ /* Use color change? */
+ if (state->blittingflags & DSBLIT_COLORIZE) {
+ /* Need valid color change settings (enabling). */
+ SH7722_CHECK_VALIDATE( COLOR_CHANGE );
+
+ sdev->color_change_enabled = true;
+ }
+ /* Disable color change? */
+ else if (sdev->color_change_enabled)
+ invalidate_color_change( sdrv, sdev );
+
+ /* Use mask? */
+ if (state->blittingflags & DSBLIT_SRC_MASK_ALPHA) {
+ /* need valid mask */
+ SH7722_CHECK_VALIDATE( MASK );
+
+ sdev->mask_enabled = true;
+ }
+ /* Disable mask? */
+ else if (sdev->mask_enabled)
+ invalidate_mask( sdrv, sdev );
+
+ SH7722_CHECK_VALIDATE( BLIT_OP );
+
+ /*
+ * 3) Tell which functions can be called without further validation, i.e. SetState()
+ *
+ * When the hw independent state is changed, this collection is reset.
+ */
+ state->set = SH7722_SUPPORTED_BLITTINGFUNCTIONS;
+ break;
+
+ default:
+ D_BUG( "unexpected drawing/blitting function" );
+ break;
+ }
+
+ sdev->dflags = state->drawingflags;
+ sdev->bflags = state->blittingflags;
+ sdev->render_options = state->render_options;
+ sdev->color = state->color;
+
+ /*
+ * 4) Clear modification flags
+ *
+ * All flags have been evaluated in 1) and remembered for further validation.
+ * If the hw independent state is not modified, this function won't get called
+ * for subsequent rendering functions, unless they aren't defined by 3).
+ */
+ state->mod_hw = 0;
+}
+
+/**********************************************************************************************************************/
+
+static inline void
+draw_rectangle( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev,
+ int x1, int y1,
+ int x2, int y2,
+ int x3, int y3,
+ int x4, int y4,
+ bool antialias,
+ bool full )
+{
+ u32 ctrl = antialias ? WR_CTRL_ANTIALIAS : 0;
+ u32 *prep = start_buffer( sdrv, full ? 24 : 12 );
+
+ if (antialias) {
+ prep[0] = BEM_WR_FGC;
+ prep[1] = PIXEL_ARGB( (sdev->color.a * AA_COEF) >> 8,
+ (sdev->color.r * AA_COEF) >> 8,
+ (sdev->color.g * AA_COEF) >> 8,
+ (sdev->color.b * AA_COEF) >> 8 );
+
+ prep[2] = BEM_PE_FIXEDALPHA;
+ prep[3] = (sdev->color.a * AA_COEF) << 16;
+ }
+ else {
+ prep[0] = BEM_WR_FGC;
+ prep[1] = PIXEL_ARGB( sdev->color.a,
+ sdev->color.r,
+ sdev->color.g,
+ sdev->color.b );
+
+ prep[2] = BEM_PE_FIXEDALPHA;
+ prep[3] = (sdev->color.a << 24) << (sdev->color.a << 16);
+ }
+
+ prep[4] = BEM_WR_V1;
+ prep[5] = SH7722_XY( x1, y1 );
+
+ prep[6] = BEM_WR_V2;
+ prep[7] = SH7722_XY( x2, y2 );
+
+ prep[8] = BEM_PE_OPERATION;
+ prep[9] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
+ sdev->ble_srcf |
+ BLE_SRCA_FIXED |
+ sdev->ble_dstf)
+ :
+ (antialias ?
+ (BLE_FUNC_AxB_plus_CxD |
+ BLE_SRCF_ONE |
+ BLE_SRCA_FIXED |
+ BLE_DSTF_1_SRC_A) : BLE_FUNC_NONE
+ );
+
+ if (sdev->dflags & DSDRAW_XOR)
+ prep[9] |= BLE_ROP_XOR;
+
+ prep[10] = BEM_WR_CTRL;
+ prep[11] = WR_CTRL_LINE | ctrl;
+
+ if (full) {
+ prep[12] = BEM_WR_V2;
+ prep[13] = SH7722_XY( x3, y3 );
+ prep[14] = BEM_WR_CTRL;
+ prep[15] = WR_CTRL_POLYLINE | ctrl;
+
+ prep[16] = BEM_WR_V2;
+ prep[17] = SH7722_XY( x4, y4 );
+ prep[18] = BEM_WR_CTRL;
+ prep[19] = WR_CTRL_POLYLINE | ctrl;
+
+ prep[20] = BEM_WR_V2;
+ prep[21] = SH7722_XY( x1, y1 );
+ prep[22] = BEM_WR_CTRL;
+ prep[23] = WR_CTRL_POLYLINE | ctrl;
+
+ submit_buffer( sdrv, 24 );
+ }
+ else {
+ prep[7] = SH7722_XY( x3, y3 );
+ prep[11] |= WR_CTRL_ENDPOINT;
+
+ submit_buffer( sdrv, 12 );
+ }
+}
+
+/*
+ * Render a filled rectangle using the current hardware state.
+ */
+static bool
+sh7722FillRectangle( void *drv, void *dev, DFBRectangle *rect )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+ __u32 *prep = start_buffer( sdrv, 8 );
+
+ D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__,
+ DFB_RECTANGLE_VALS( rect ) );
+ DUMP_INFO();
+
+ prep[0] = BEM_BE_V1;
+ prep[1] = SH7722_XY( rect->x, rect->y );
+
+ prep[2] = BEM_BE_V2;
+ prep[3] = SH7722_XY( rect->w, rect->h );
+
+ prep[4] = BEM_PE_OPERATION;
+ prep[5] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
+ sdev->ble_srcf |
+ BLE_SRCA_FIXED |
+ sdev->ble_dstf) : BLE_FUNC_NONE;
+
+ if (sdev->dflags & DSDRAW_XOR)
+ prep[5] |= BLE_ROP_XOR;
+
+ prep[6] = BEM_BE_CTRL;
+ prep[7] = BE_CTRL_RECTANGLE | BE_CTRL_SCANMODE_LINE;
+
+ submit_buffer( sdrv, 8 );
+
+ return true;
+}
+
+/*
+ * This version sends a quadrangle to have all four edges transformed.
+ */
+static bool
+sh7722FillRectangleMatrixAA( void *drv, void *dev, DFBRectangle *rect )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+ __u32 *prep;
+
+ D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__,
+ DFB_RECTANGLE_VALS( rect ) );
+ DUMP_INFO();
+
+
+ if (sdev->render_options & DSRO_ANTIALIAS) {
+ int x1 = rect->x;
+ int y1 = rect->y;
+ int x2 = rect->x + rect->w;
+ int y2 = rect->y;
+ int x3 = rect->x + rect->w;
+ int y3 = rect->y + rect->h;
+ int x4 = rect->x;
+ int y4 = rect->y + rect->h;
+
+ if (sdev->render_options & DSRO_MATRIX) {
+ int t;
+
+ t = ((x1 * sdev->matrix[0]) +
+ (y1 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
+ y1 = ((x1 * sdev->matrix[3]) +
+ (y1 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
+ x1 = t;
+
+ t = ((x2 * sdev->matrix[0]) +
+ (y2 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
+ y2 = ((x2 * sdev->matrix[3]) +
+ (y2 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
+ x2 = t;
+
+ t = ((x3 * sdev->matrix[0]) +
+ (y3 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
+ y3 = ((x3 * sdev->matrix[3]) +
+ (y3 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
+ x3 = t;
+
+ t = ((x4 * sdev->matrix[0]) +
+ (y4 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
+ y4 = ((x4 * sdev->matrix[3]) +
+ (y4 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
+ x4 = t;
+ }
+
+ prep = start_buffer( sdrv, 28 );
+
+ prep[0] = BEM_WR_FGC;
+ prep[1] = PIXEL_ARGB( (sdev->color.a * AA_COEF) >> 8,
+ (sdev->color.r * AA_COEF) >> 8,
+ (sdev->color.g * AA_COEF) >> 8,
+ (sdev->color.b * AA_COEF) >> 8 );
+
+ prep[2] = BEM_PE_FIXEDALPHA;
+ prep[3] = (sdev->color.a * AA_COEF) << 16;
+
+ prep[4] = BEM_WR_V1;
+ prep[5] = SH7722_XY( x1, y1 );
+
+ prep[6] = BEM_WR_V2;
+ prep[7] = SH7722_XY( x2, y2 );
+
+ prep[8] = BEM_PE_OPERATION;
+ prep[9] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
+ sdev->ble_srcf |
+ BLE_SRCA_FIXED |
+ sdev->ble_dstf)
+ :
+ (BLE_FUNC_AxB_plus_CxD |
+ BLE_SRCF_ONE |
+ BLE_SRCA_FIXED |
+ BLE_DSTF_1_SRC_A);
+
+ if (sdev->dflags & DSDRAW_XOR)
+ prep[9] |= BLE_ROP_XOR;
+
+ prep[10] = BEM_WR_CTRL;
+ prep[11] = WR_CTRL_LINE | WR_CTRL_ANTIALIAS;
+
+ if (rect->h > 1 && rect->w > 1) {
+ prep[12] = BEM_WR_V2;
+ prep[13] = SH7722_XY( x3, y3 );
+ prep[14] = BEM_WR_CTRL;
+ prep[15] = WR_CTRL_POLYLINE | WR_CTRL_ANTIALIAS;
+
+ prep[16] = BEM_WR_V2;
+ prep[17] = SH7722_XY( x4, y4 );
+ prep[18] = BEM_WR_CTRL;
+ prep[19] = WR_CTRL_POLYLINE | WR_CTRL_ANTIALIAS;
+
+ prep[20] = BEM_WR_V2;
+ prep[21] = SH7722_XY( x1, y1 );
+ prep[22] = BEM_WR_CTRL;
+ prep[23] = WR_CTRL_POLYLINE | WR_CTRL_ANTIALIAS;
+
+ prep[24] = BEM_WR_FGC;
+ prep[25] = PIXEL_ARGB( sdev->color.a,
+ sdev->color.r,
+ sdev->color.g,
+ sdev->color.b );
+
+ prep[26] = BEM_PE_FIXEDALPHA;
+ prep[27] = (sdev->color.a << 24) << (sdev->color.a << 16);
+
+ submit_buffer( sdrv, 28 );
+ }
+ else {
+ prep[7] = SH7722_XY( x3, y3 );
+ prep[11] |= WR_CTRL_ENDPOINT;
+
+ prep[12] = BEM_WR_FGC;
+ prep[13] = PIXEL_ARGB( sdev->color.a,
+ sdev->color.r,
+ sdev->color.g,
+ sdev->color.b );
+
+ prep[14] = BEM_PE_FIXEDALPHA;
+ prep[15] = (sdev->color.a << 24) << (sdev->color.a << 16);
+
+ submit_buffer( sdrv, 16 );
+ }
+ }
+
+
+ prep = start_buffer( sdrv, 12 );
+
+ prep[0] = BEM_BE_V1;
+ prep[1] = SH7722_XY( rect->x, rect->y );
+
+ prep[2] = BEM_BE_V2;
+ prep[3] = SH7722_XY( rect->x, rect->y + rect->h );
+
+ prep[4] = BEM_BE_V3;
+ prep[5] = SH7722_XY( rect->x + rect->w, rect->y );
+
+ prep[6] = BEM_BE_V4;
+ prep[7] = SH7722_XY( rect->x + rect->w, rect->y + rect->h );
+
+ prep[8] = BEM_PE_OPERATION;
+ prep[9] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
+ sdev->ble_srcf |
+ BLE_SRCA_FIXED |
+ sdev->ble_dstf) : BLE_FUNC_NONE;
+
+ if (sdev->dflags & DSDRAW_XOR)
+ prep[9] |= BLE_ROP_XOR;
+
+ prep[10] = BEM_BE_CTRL;
+
+ if (sdev->render_options & DSRO_MATRIX)
+ prep[11] = BE_CTRL_QUADRANGLE | BE_CTRL_SCANMODE_4x4 |
+ BE_CTRL_MATRIX | BE_CTRL_FIXMODE_16_16;// | BE_CTRL_ORIGIN;
+ else
+ prep[11] = BE_CTRL_QUADRANGLE | BE_CTRL_SCANMODE_LINE;
+
+ submit_buffer( sdrv, 12 );
+
+ return true;
+}
+
+/*
+ * Render a filled triangle using the current hardware state.
+ */
+bool
+sh7722FillTriangle( void *drv, void *dev, DFBTriangle *tri )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+ __u32 *prep;
+
+ D_DEBUG_AT( SH7722_BLT, "%s( %d,%d - %d,%d - %d,%d )\n", __FUNCTION__,
+ tri->x1, tri->y1, tri->x2, tri->y2, tri->x3, tri->y3 );
+ DUMP_INFO();
+
+
+ if (sdev->render_options & DSRO_ANTIALIAS) {
+ int x1, y1;
+ int x2, y2;
+ int x3, y3;
+
+ if (sdev->render_options & DSRO_MATRIX) {
+ x1 = ((tri->x1 * sdev->matrix[0]) +
+ (tri->y1 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
+ y1 = ((tri->x1 * sdev->matrix[3]) +
+ (tri->y1 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
+
+ x2 = ((tri->x2 * sdev->matrix[0]) +
+ (tri->y2 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
+ y2 = ((tri->x2 * sdev->matrix[3]) +
+ (tri->y2 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
+
+ x3 = ((tri->x3 * sdev->matrix[0]) +
+ (tri->y3 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
+ y3 = ((tri->x3 * sdev->matrix[3]) +
+ (tri->y3 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
+ }
+ else {
+ x1 = tri->x1;
+ y1 = tri->y1;
+ x2 = tri->x2;
+ y2 = tri->y2;
+ x3 = tri->x3;
+ y3 = tri->y3;
+ }
+
+ prep = start_buffer( sdrv, 24 );
+
+ prep[0] = BEM_WR_FGC;
+ prep[1] = PIXEL_ARGB( (sdev->color.a * AA_COEF) >> 8,
+ (sdev->color.r * AA_COEF) >> 8,
+ (sdev->color.g * AA_COEF) >> 8,
+ (sdev->color.b * AA_COEF) >> 8 );
+
+ prep[2] = BEM_PE_FIXEDALPHA;
+ prep[3] = (sdev->color.a * AA_COEF) << 16;
+
+ prep[4] = BEM_WR_V1;
+ prep[5] = SH7722_XY( x1, y1 );
+
+ prep[6] = BEM_WR_V2;
+ prep[7] = SH7722_XY( x2, y2 );
+
+ prep[8] = BEM_PE_OPERATION;
+ prep[9] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
+ sdev->ble_srcf |
+ BLE_SRCA_FIXED |
+ sdev->ble_dstf)
+ :
+ (BLE_FUNC_AxB_plus_CxD |
+ BLE_SRCF_ONE |
+ BLE_SRCA_FIXED |
+ BLE_DSTF_1_SRC_A);
+
+ if (sdev->dflags & DSDRAW_XOR)
+ prep[9] |= BLE_ROP_XOR;
+
+ prep[10] = BEM_WR_CTRL;
+ prep[11] = WR_CTRL_LINE | WR_CTRL_ANTIALIAS;
+
+ prep[12] = BEM_WR_V2;
+ prep[13] = SH7722_XY( x3, y3 );
+ prep[14] = BEM_WR_CTRL;
+ prep[15] = WR_CTRL_POLYLINE | WR_CTRL_ANTIALIAS;
+
+ prep[16] = BEM_WR_V2;
+ prep[17] = SH7722_XY( x1, y1 );
+ prep[18] = BEM_WR_CTRL;
+ prep[19] = WR_CTRL_POLYLINE | WR_CTRL_ANTIALIAS;
+
+ prep[20] = BEM_WR_FGC;
+ prep[21] = PIXEL_ARGB( sdev->color.a,
+ sdev->color.r,
+ sdev->color.g,
+ sdev->color.b );
+
+ prep[22] = BEM_PE_FIXEDALPHA;
+ prep[23] = (sdev->color.a << 24) << (sdev->color.a << 16);
+
+ submit_buffer( sdrv, 24 );
+ }
+
+
+ prep = start_buffer( sdrv, 12 );
+
+ prep[0] = BEM_BE_V1;
+ prep[1] = SH7722_XY( tri->x1, tri->y1 );
+
+ prep[2] = BEM_BE_V2;
+ prep[3] = SH7722_XY( tri->x2, tri->y2 );
+
+ prep[4] = BEM_BE_V3;
+ prep[5] = SH7722_XY( tri->x3, tri->y3 );
+
+ prep[6] = BEM_BE_V4;
+ prep[7] = SH7722_XY( tri->x3, tri->y3 );
+
+ prep[8] = BEM_PE_OPERATION;
+ prep[9] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
+ sdev->ble_srcf |
+ BLE_SRCA_FIXED |
+ sdev->ble_dstf) : BLE_FUNC_NONE;
+
+ if (sdev->dflags & DSDRAW_XOR)
+ prep[9] |= BLE_ROP_XOR;
+
+ prep[10] = BEM_BE_CTRL;
+ prep[11] = BE_CTRL_QUADRANGLE | BE_CTRL_SCANMODE_LINE;
+
+ if (sdev->render_options & DSRO_MATRIX)
+ prep[11] |= BE_CTRL_MATRIX | BE_CTRL_FIXMODE_16_16;// | BE_CTRL_ORIGIN;
+
+ submit_buffer( sdrv, 12 );
+
+ return true;
+}
+
+/*
+ * Render rectangle outlines using the current hardware state.
+ */
+static bool
+sh7722DrawRectangle( void *drv, void *dev, DFBRectangle *rect )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+ __u32 *prep = start_buffer( sdrv, 20 );
+
+ int x1 = rect->x;
+ int y1 = rect->y;
+ int x2 = rect->x + rect->w;
+ int y2 = rect->y + rect->h;
+
+ D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__,
+ DFB_RECTANGLE_VALS( rect ) );
+ DUMP_INFO();
+
+ prep[0] = BEM_WR_V1;
+ prep[1] = (y1 << 16) | x1;
+
+ prep[2] = BEM_WR_V2;
+ prep[3] = (y1 << 16) | x2;
+
+ prep[4] = BEM_PE_OPERATION;
+ prep[5] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
+ sdev->ble_srcf |
+ BLE_SRCA_FIXED |
+ sdev->ble_dstf) : BLE_FUNC_NONE;
+
+ if (sdev->dflags & DSDRAW_XOR)
+ prep[5] |= BLE_ROP_XOR;
+
+ prep[6] = BEM_WR_CTRL;
+ prep[7] = WR_CTRL_LINE;
+
+ if (rect->h > 1 && rect->w > 1) {
+ prep[8] = BEM_WR_V2;
+ prep[9] = (y2 << 16) | x2;
+ prep[10] = BEM_WR_CTRL;
+ prep[11] = WR_CTRL_POLYLINE;
+
+ prep[12] = BEM_WR_V2;
+ prep[13] = (y2 << 16) | x1;
+ prep[14] = BEM_WR_CTRL;
+ prep[15] = WR_CTRL_POLYLINE;
+
+ prep[16] = BEM_WR_V2;
+ prep[17] = (y1 << 16) | x1;
+ prep[18] = BEM_WR_CTRL;
+ prep[19] = WR_CTRL_POLYLINE;
+
+ submit_buffer( sdrv, 20 );
+ }
+ else {
+ prep[3] = (y2 << 16) | x2;
+ prep[7] |= WR_CTRL_ENDPOINT;
+
+ submit_buffer( sdrv, 8 );
+ }
+
+ return true;
+}
+
+static bool
+sh7722DrawRectangleMatrixAA( void *drv, void *dev, DFBRectangle *rect )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+
+ int x1 = rect->x;
+ int y1 = rect->y;
+ int x2 = rect->x + rect->w;
+ int y2 = rect->y;
+ int x3 = rect->x + rect->w;
+ int y3 = rect->y + rect->h;
+ int x4 = rect->x;
+ int y4 = rect->y + rect->h;
+
+ D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__,
+ DFB_RECTANGLE_VALS( rect ) );
+ DUMP_INFO();
+
+ if (sdev->render_options & DSRO_MATRIX) {
+ int t;
+
+ t = ((x1 * sdev->matrix[0]) +
+ (y1 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
+ y1 = ((x1 * sdev->matrix[3]) +
+ (y1 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
+ x1 = t;
+
+ t = ((x2 * sdev->matrix[0]) +
+ (y2 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
+ y2 = ((x2 * sdev->matrix[3]) +
+ (y2 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
+ x2 = t;
+
+ t = ((x3 * sdev->matrix[0]) +
+ (y3 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
+ y3 = ((x3 * sdev->matrix[3]) +
+ (y3 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
+ x3 = t;
+
+ t = ((x4 * sdev->matrix[0]) +
+ (y4 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
+ y4 = ((x4 * sdev->matrix[3]) +
+ (y4 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
+ x4 = t;
+ }
+
+ if (sdev->render_options & DSRO_ANTIALIAS)
+ draw_rectangle( sdrv, sdev, x1, y1, x2, y2, x3, y3, x4, y4, true, rect->h > 1 && rect->w > 1 );
+
+ draw_rectangle( sdrv, sdev, x1, y1, x2, y2, x3, y3, x4, y4, false, rect->h > 1 && rect->w > 1 );
+
+ return true;
+}
+
+/*
+ * Render a line using the current hardware state.
+ */
+static bool
+sh7722DrawLine( void *drv, void *dev, DFBRegion *line )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+ __u32 *prep = start_buffer( sdrv, 8 );
+
+ D_DEBUG_AT( SH7722_BLT, "%s( %d, %d -> %d, %d )\n", __FUNCTION__,
+ DFB_REGION_VALS( line ) );
+ DUMP_INFO();
+
+ prep[0] = BEM_WR_V1;
+ prep[1] = SH7722_XY( line->x1, line->y1 );
+
+ prep[2] = BEM_WR_V2;
+ prep[3] = SH7722_XY( line->x2, line->y2 );
+
+ prep[4] = BEM_PE_OPERATION;
+ prep[5] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
+ sdev->ble_srcf |
+ BLE_SRCA_FIXED |
+ sdev->ble_dstf) : BLE_FUNC_NONE;
+
+ if (sdev->dflags & DSDRAW_XOR)
+ prep[5] |= BLE_ROP_XOR;
+
+ prep[6] = BEM_WR_CTRL;
+ prep[7] = WR_CTRL_LINE | WR_CTRL_ENDPOINT;
+
+ submit_buffer( sdrv, 8 );
+
+ return true;
+}
+
+static bool
+sh7722DrawLineMatrix( void *drv, void *dev, DFBRegion *line )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+ __u32 *prep = start_buffer( sdrv, 8 );
+
+ D_DEBUG_AT( SH7722_BLT, "%s( %d, %d -> %d, %d )\n", __FUNCTION__,
+ DFB_REGION_VALS( line ) );
+ DUMP_INFO();
+
+ int x1 = ((line->x1 * sdev->matrix[0]) +
+ (line->y1 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
+ int y1 = ((line->x1 * sdev->matrix[3]) +
+ (line->y1 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
+
+ int x2 = ((line->x2 * sdev->matrix[0]) +
+ (line->y2 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
+ int y2 = ((line->x2 * sdev->matrix[3]) +
+ (line->y2 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
+
+ prep[0] = BEM_WR_V1;
+ prep[1] = SH7722_XY( x1, y1 );
+
+ prep[2] = BEM_WR_V2;
+ prep[3] = SH7722_XY( x2, y2 );
+
+ prep[4] = BEM_PE_OPERATION;
+ prep[5] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
+ sdev->ble_srcf |
+ BLE_SRCA_FIXED |
+ sdev->ble_dstf) : BLE_FUNC_NONE;
+
+ if (sdev->dflags & DSDRAW_XOR)
+ prep[5] |= BLE_ROP_XOR;
+
+ prep[6] = BEM_WR_CTRL;
+ prep[7] = WR_CTRL_LINE | WR_CTRL_ENDPOINT;
+
+ submit_buffer( sdrv, 8 );
+
+ return true;
+}
+
+static bool
+sh7722DrawLineAA( void *drv, void *dev, DFBRegion *line )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+ __u32 *prep = start_buffer( sdrv, 24 );
+ int x1, y1;
+ int x2, y2;
+
+ D_DEBUG_AT( SH7722_BLT, "%s( %d, %d -> %d, %d )\n", __FUNCTION__,
+ DFB_REGION_VALS( line ) );
+ DUMP_INFO();
+
+ if (sdev->render_options & DSRO_MATRIX) {
+ x1 = ((line->x1 * sdev->matrix[0]) +
+ (line->y1 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
+ y1 = ((line->x1 * sdev->matrix[3]) +
+ (line->y1 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
+
+ x2 = ((line->x2 * sdev->matrix[0]) +
+ (line->y2 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
+ y2 = ((line->x2 * sdev->matrix[3]) +
+ (line->y2 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
+ }
+ else {
+ x1 = line->x1;
+ y1 = line->y1;
+ x2 = line->x2;
+ y2 = line->y2;
+ }
+
+ prep[0] = BEM_WR_FGC;
+ prep[1] = PIXEL_ARGB( (sdev->color.a * AA_COEF) >> 8,
+ (sdev->color.r * AA_COEF) >> 8,
+ (sdev->color.g * AA_COEF) >> 8,
+ (sdev->color.b * AA_COEF) >> 8 );
+
+ prep[2] = BEM_PE_FIXEDALPHA;
+ prep[3] = (sdev->color.a * AA_COEF) << 16;
+
+ prep[4] = BEM_WR_V1;
+ prep[5] = SH7722_XY( x1, y1 );
+
+ prep[6] = BEM_WR_V2;
+ prep[7] = SH7722_XY( x2, y2 );
+
+ prep[8] = BEM_PE_OPERATION;
+ prep[9] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
+ sdev->ble_srcf |
+ BLE_SRCA_FIXED |
+ sdev->ble_dstf)
+ :
+ (BLE_FUNC_AxB_plus_CxD |
+ BLE_SRCF_ONE |
+ BLE_SRCA_FIXED |
+ BLE_DSTF_1_SRC_A);
+
+ if (sdev->dflags & DSDRAW_XOR)
+ prep[9] |= BLE_ROP_XOR;
+
+ prep[10] = BEM_WR_CTRL;
+ prep[11] = WR_CTRL_LINE | WR_CTRL_ENDPOINT | WR_CTRL_ANTIALIAS;
+
+
+
+ prep[12] = BEM_WR_FGC;
+ prep[13] = PIXEL_ARGB( sdev->color.a,
+ sdev->color.r,
+ sdev->color.g,
+ sdev->color.b );
+
+ prep[14] = BEM_PE_FIXEDALPHA;
+ prep[15] = (sdev->color.a << 24) | (sdev->color.a << 16);
+
+ prep[16] = BEM_WR_V1;
+ prep[17] = SH7722_XY( x1, y1 );
+
+ prep[18] = BEM_WR_V2;
+ prep[19] = SH7722_XY( x2, y2 );
+
+ prep[20] = BEM_PE_OPERATION;
+ prep[21] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
+ sdev->ble_srcf |
+ BLE_SRCA_FIXED |
+ sdev->ble_dstf) : BLE_FUNC_NONE;
+
+ if (sdev->dflags & DSDRAW_XOR)
+ prep[21] |= BLE_ROP_XOR;
+
+ prep[22] = BEM_WR_CTRL;
+ prep[23] = WR_CTRL_LINE | WR_CTRL_ENDPOINT;
+
+
+ submit_buffer( sdrv, 24 );
+
+ return true;
+}
+
+/*
+ * Common implementation for Blit() and StretchBlit().
+ */
+static inline bool
+sh7722DoBlit( SH7722DriverData *sdrv, SH7722DeviceData *sdev,
+ DFBRectangle *rect, int x, int y, int w, int h )
+{
+ int num = 8;
+ __u32 *prep = start_buffer( sdrv, 12 );
+
+ D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d -> %d, %d - %dx%d )\n", __FUNCTION__,
+ DFB_RECTANGLE_VALS( rect ), x, y, w, h );
+ DUMP_INFO();
+
+ prep[0] = BEM_BE_SRC_LOC;
+
+ /* Stencil mode needs a workaround, because the hardware always adds the source location. */
+ if (sdev->bflags & DSBLIT_SRC_MASK_ALPHA && sdev->mask_flags & DSMF_STENCIL)
+ prep[1] = SH7722_XY( 0, 0 );
+ else
+ prep[1] = SH7722_XY( rect->x, rect->y );
+
+ prep[2] = BEM_BE_SRC_SIZE;
+ prep[3] = SH7722_XY( rect->w, rect->h );
+
+ prep[4] = BEM_BE_V1;
+ prep[5] = SH7722_XY( x, y );
+
+ prep[6] = BEM_BE_V2;
+ prep[7] = SH7722_XY( w, h );
+
+ /* Stencil mode needs a workaround, because the hardware always adds the source location. */
+ if (sdev->bflags & DSBLIT_SRC_MASK_ALPHA && sdev->mask_flags & DSMF_STENCIL) {
+ prep[num++] = BEM_TE_SRC_BASE;
+ prep[num++] = sdev->src_phys + sdev->src_pitch * rect->y + sdev->src_bpp * rect->x;
+
+ SH7722_INVALIDATE( SOURCE );
+ }
+
+ prep[num++] = BEM_BE_CTRL;
+ prep[num++] = BE_CTRL_RECTANGLE | BE_CTRL_TEXTURE | BE_CTRL_SCANMODE_LINE;
+
+ if (sdev->bflags & DSBLIT_ROTATE180)
+ prep[num-1] |= BE_FLIP_BOTH;
+ else if (rect->w == w && rect->h == h) /* No blit direction handling for StretchBlit(). */
+ prep[num-1] |= BE_CTRL_BLTDIR_AUTOMATIC;
+
+ submit_buffer( sdrv, num );
+
+ return true;
+}
+
+/*
+ * This version sends a quadrangle to have all four edges transformed.
+ */
+__attribute__((noinline))
+static bool
+sh7722DoBlitM( SH7722DriverData *sdrv, SH7722DeviceData *sdev,
+ DFBRectangle *rect, int x1, int y1, int x2, int y2 )
+{
+ int num = 12;
+ __u32 *prep = start_buffer( sdrv, 16 );
+
+ D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d -> %d, %d - %d, %d )\n", __FUNCTION__,
+ DFB_RECTANGLE_VALS( rect ), x1, y1, x2, y2 );
+ DUMP_INFO();
+
+ prep[0] = BEM_BE_SRC_LOC;
+
+ /* Stencil mode needs a workaround, because the hardware always adds the source location. */
+ if (sdev->bflags & DSBLIT_SRC_MASK_ALPHA && sdev->mask_flags & DSMF_STENCIL)
+ prep[1] = SH7722_XY( 0, 0 );
+ else
+ prep[1] = SH7722_XY( rect->x, rect->y );
+
+ prep[2] = BEM_BE_SRC_SIZE;
+ prep[3] = SH7722_XY( rect->w, rect->h );
+
+ prep[4] = BEM_BE_V1;
+ prep[5] = SH7722_XY( x1, y1 );
+
+ prep[6] = BEM_BE_V2;
+ prep[7] = SH7722_XY( x1, y2 );
+
+ prep[8] = BEM_BE_V3;
+ prep[9] = SH7722_XY( x2, y1 );
+
+ prep[10] = BEM_BE_V4;
+ prep[11] = SH7722_XY( x2, y2 );
+
+ /* Stencil mode needs a workaround, because the hardware always adds the source location. */
+ if (sdev->bflags & DSBLIT_SRC_MASK_ALPHA && sdev->mask_flags & DSMF_STENCIL) {
+ prep[num++] = BEM_TE_SRC_BASE;
+ prep[num++] = sdev->src_phys + sdev->src_pitch * rect->y + sdev->src_bpp * rect->x;
+
+ SH7722_INVALIDATE( SOURCE );
+ }
+
+ prep[num++] = BEM_BE_CTRL;
+ prep[num++] = BE_CTRL_QUADRANGLE | BE_CTRL_TEXTURE | BE_CTRL_SCANMODE_4x4 |
+ BE_CTRL_MATRIX | BE_CTRL_FIXMODE_16_16;// | BE_CTRL_ORIGIN;
+
+ if (sdev->bflags & DSBLIT_ROTATE180)
+ prep[num-1] |= BE_FLIP_BOTH;
+
+ submit_buffer( sdrv, num );
+
+ return true;
+}
+
+/*
+ * Blit a rectangle using the current hardware state.
+ */
+bool
+sh7722Blit( void *drv, void *dev, DFBRectangle *rect, int x, int y )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+
+ D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d -> %d, %d )\n",
+ __FUNCTION__, DFB_RECTANGLE_VALS( rect ), x, y );
+
+ if (sdev->render_options & DSRO_MATRIX)
+ return sh7722DoBlitM( sdrv, sdev, rect, DFB_REGION_VALS_FROM_RECTANGLE_VALS( x, y, rect->w, rect->h ) );
+
+ return sh7722DoBlit( sdrv, sdev, rect, x, y, rect->w, rect->h );
+}
+
+/*
+ * StretchBlit a rectangle using the current hardware state.
+ */
+bool
+sh7722StretchBlit( void *drv, void *dev, DFBRectangle *srect, DFBRectangle *drect )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+
+ D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d -> %d, %d - %dx%d )\n",
+ __FUNCTION__, DFB_RECTANGLE_VALS( srect ), DFB_RECTANGLE_VALS( drect ) );
+
+ if (sdev->render_options & DSRO_MATRIX)
+ return sh7722DoBlitM( sdrv, sdev, srect, DFB_REGION_VALS_FROM_RECTANGLE( drect ) );
+
+ return sh7722DoBlit( sdrv, sdev, srect, drect->x, drect->y, drect->w, drect->h );
+}
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_blt.h b/Source/DirectFB/gfxdrivers/sh772x/sh7722_blt.h
new file mode 100755
index 0000000..00934bf
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_blt.h
@@ -0,0 +1,214 @@
+#ifndef __SH7722_BLT_H__
+#define __SH7722_BLT_H__
+
+#include <sys/ioctl.h>
+
+#include "sh7722_types.h"
+
+
+
+#define SH7722_SUPPORTED_DRAWINGFLAGS (DSDRAW_BLEND | \
+ DSDRAW_XOR)
+
+#define SH7722_SUPPORTED_DRAWINGFUNCTIONS (DFXL_FILLRECTANGLE | \
+ DFXL_FILLTRIANGLE | \
+ DFXL_DRAWRECTANGLE | \
+ DFXL_DRAWLINE)
+
+#define SH7722_SUPPORTED_BLITTINGFLAGS (DSBLIT_BLEND_ALPHACHANNEL | \
+ DSBLIT_BLEND_COLORALPHA | \
+ DSBLIT_SRC_COLORKEY | \
+ DSBLIT_ROTATE180 | \
+ DSBLIT_COLORIZE | \
+ DSBLIT_XOR | \
+ DSBLIT_SRC_MASK_ALPHA)
+
+#define SH7722_SUPPORTED_BLITTINGFUNCTIONS (DFXL_BLIT | \
+ DFXL_STRETCHBLIT)
+
+
+DFBResult sh7722EngineSync ( void *drv, void *dev );
+
+void sh7722EngineReset ( void *drv, void *dev );
+void sh7722FlushTextureCache( void *drv, void *dev );
+
+void sh7722EmitCommands ( void *drv, void *dev );
+
+void sh7722CheckState ( void *drv, void *dev,
+ CardState *state, DFBAccelerationMask accel );
+
+void sh7722SetState ( void *drv, void *dev,
+ GraphicsDeviceFuncs *funcs,
+ CardState *state, DFBAccelerationMask accel );
+
+bool sh7722FillTriangle ( void *drv, void *dev, DFBTriangle *tri );
+bool sh7722Blit ( void *drv, void *dev, DFBRectangle *rect, int x, int y );
+bool sh7722StretchBlit ( void *drv, void *dev, DFBRectangle *srect, DFBRectangle *drect );
+
+
+
+#define SH7722_S16S16(h,l) ((u32)((((u16)(h)) << 16) | ((u16)(l))))
+
+#define SH7722_XY(x,y) SH7722_S16S16(y,x)
+
+#define SH7722_TDG_BASE 0xFD000000
+
+#define BEM_HC_DMA_ADR (SH7722_TDG_BASE + 0x00040)
+#define BEM_HC_DMA_START (SH7722_TDG_BASE + 0x00044)
+
+#define BEM_WR_CTRL (0x00400)
+#define BEM_WR_V1 (0x00410)
+#define BEM_WR_V2 (0x00414)
+#define BEM_WR_FGC (0x00420)
+
+#define BEM_BE_CTRL (0x00800)
+#define BEM_BE_V1 (0x00810)
+#define BEM_BE_V2 (0x00814)
+#define BEM_BE_V3 (0x00818)
+#define BEM_BE_V4 (0x0081C)
+#define BEM_BE_COLOR1 (0x00820)
+#define BEM_BE_SRC_LOC (0x00830)
+#define BEM_BE_SRC_SIZE (0x00834)
+#define BEM_BE_MATRIX_A (0x00850)
+#define BEM_BE_MATRIX_B (0x00854)
+#define BEM_BE_MATRIX_C (0x00858)
+#define BEM_BE_MATRIX_D (0x0085C)
+#define BEM_BE_MATRIX_E (0x00860)
+#define BEM_BE_MATRIX_F (0x00864)
+#define BEM_BE_ORIGIN (0x00870)
+#define BEM_BE_SC_MIN (0x00880)
+#define BEM_BE_SC_MAX (0x00884)
+
+#define BEM_TE_SRC (0x00C00)
+#define BEM_TE_SRC_BASE (0x00C04)
+#define BEM_TE_SRC_SIZE (0x00C08)
+#define BEM_TE_SRC_CNV (0x00C0C)
+#define BEM_TE_MASK (0x00C10)
+#define BEM_TE_MASK_BASE (0x00C14)
+#define BEM_TE_MASK_SIZE (0x00C18)
+#define BEM_TE_MASK_CNV (0x00C1C)
+#define BEM_TE_ALPHA (0x00C28)
+#define BEM_TE_FILTER (0x00C30)
+#define BEM_TE_INVALID (0x00C40)
+
+#define BEM_PE_DST (0x01000)
+#define BEM_PE_DST_BASE (0x01004)
+#define BEM_PE_DST_SIZE (0x01008)
+#define BEM_PE_SC (0x0100C)
+#define BEM_PE_SC0_MIN (0x01010)
+#define BEM_PE_SC0_MAX (0x01014)
+#define BEM_PE_CKEY (0x01040)
+#define BEM_PE_CKEY_B (0x01044)
+#define BEM_PE_CKEY_A (0x01048)
+#define BEM_PE_COLORCHANGE (0x01050)
+#define BEM_PE_ALPHA (0x01058)
+#define BEM_PE_COLORCHANGE_0 (0x01060)
+#define BEM_PE_COLORCHANGE_1 (0x01064)
+#define BEM_PE_OPERATION (0x01080)
+#define BEM_PE_FIXEDALPHA (0x01084)
+#define BEM_PE_OFFSET (0x01088)
+#define BEM_PE_MASK (0x01094)
+#define BEM_PE_CACHE (0x010B0)
+
+/*
+ * BEM_BE_CTRL
+ */
+#define BE_FLIP_NONE 0x00000000
+#define BE_FLIP_HORIZONTAL 0x01000000
+#define BE_FLIP_VERTICAL 0x02000000
+#define BE_FLIP_BOTH 0x03000000
+
+#define BE_CTRL_FIXMODE_20_12 0x00000000
+#define BE_CTRL_FIXMODE_16_16 0x00100000
+#define BE_CTRL_CLIP 0x00080000
+#define BE_CTRL_ORIGIN 0x00040000
+#define BE_CTRL_ZOOM 0x00020000
+#define BE_CTRL_MATRIX 0x00010000
+
+#define BE_CTRL_SCANMODE_LINE 0x00000000
+#define BE_CTRL_SCANMODE_4x4 0x00001000
+#define BE_CTRL_SCANMODE_8x4 0x00002000
+
+#define BE_CTRL_BLTDIR_FORWARD 0x00000000
+#define BE_CTRL_BLTDIR_BACKWARD 0x00000100
+#define BE_CTRL_BLTDIR_AUTOMATIC 0x00000200
+
+#define BE_CTRL_TEXTURE 0x00000020
+#define BE_CTRL_QUADRANGLE 0x00000002
+#define BE_CTRL_RECTANGLE 0x00000001
+
+/*
+ * BEM_PE_OPERATION
+ */
+#define BLE_FUNC_NONE 0x00000000
+#define BLE_FUNC_AxB_plus_CxD 0x10000000
+#define BLE_FUNC_CxD_minus_AxB 0x20000000
+#define BLE_FUNC_AxB_minus_CxD 0x30000000
+
+#define BLE_ROP_XOR 0x01660000
+
+#define BLE_SRCA_FIXED 0x00000000
+#define BLE_SRCA_SOURCE_ALPHA 0x00001000
+#define BLE_SRCA_ALPHA_CHANNEL 0x00002000
+
+#define BLE_DSTA_FIXED 0x00000000
+#define BLE_DSTA_DEST_ALPHA 0x00000100
+
+#define BLE_SRCF_ZERO 0x00000000
+#define BLE_SRCF_ONE 0x00000010
+#define BLE_SRCF_DST 0x00000020
+#define BLE_SRCF_1_DST 0x00000030
+#define BLE_SRCF_SRC_A 0x00000040
+#define BLE_SRCF_1_SRC_A 0x00000050
+#define BLE_SRCF_DST_A 0x00000060
+#define BLE_SRCF_1_DST_A 0x00000070
+
+#define BLE_DSTO_DST 0x00000000
+#define BLE_DSTO_OFFSET 0x00000008
+
+#define BLE_DSTF_ZERO 0x00000000
+#define BLE_DSTF_ONE 0x00000001
+#define BLE_DSTF_SRC 0x00000002
+#define BLE_DSTF_1_SRC 0x00000003
+#define BLE_DSTF_SRC_A 0x00000004
+#define BLE_DSTF_1_SRC_A 0x00000005
+#define BLE_DSTF_DST_A 0x00000006
+#define BLE_DSTF_1_DST_A 0x00000007
+
+/*
+ * BEM_PE_CKEY
+ */
+#define CKEY_EXCLUDE_UNUSED 0x00100000
+#define CKEY_EXCLUDE_ALPHA 0x00010000
+#define CKEY_A_ENABLE 0x00000100
+#define CKEY_B_ENABLE 0x00000001
+
+/*
+ * BEM_PE_COLORCHANGE
+ */
+#define COLORCHANGE_DISABLE 0x00000000
+#define COLORCHANGE_COMPARE_FIRST 0x0000000b
+#define COLORCHANGE_EXCLUDE_UNUSED 0x00010000
+
+/*
+ * BEM_PE_MASK
+ */
+#define PE_MASK_DISABLE 0x00000000
+#define PE_MASK_COLOR 0x00000001
+#define PE_MASK_ALPHA 0x00000080
+
+/*
+ * BEM_TE_MASK
+ */
+#define TE_MASK_DISABLE 0x00000000
+#define TE_MASK_ENABLE 0x00010000
+
+/*
+ * BEM_WR_CTRL
+ */
+#define WR_CTRL_LINE 0x00000002
+#define WR_CTRL_POLYLINE 0x00000003
+#define WR_CTRL_ANTIALIAS 0x00020100
+#define WR_CTRL_ENDPOINT 0x00001000
+
+#endif
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeg.c b/Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeg.c
new file mode 100755
index 0000000..9208890
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeg.c
@@ -0,0 +1,395 @@
+#ifdef SH7722_DEBUG_JPEG
+#define DIRECT_ENABLE_DEBUG
+#endif
+
+#include <stdio.h>
+#include <jpeglib.h>
+
+#undef HAVE_STDLIB_H
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdarg.h>
+#include <fcntl.h>
+
+#include <asm/types.h>
+
+#include <direct/debug.h>
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+
+#include <directfb.h>
+
+#include <core/layers.h>
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+#include <core/system.h>
+
+#include <display/idirectfbsurface.h>
+#include <media/idirectfbdatabuffer.h>
+#include <media/idirectfbimageprovider.h>
+
+#include "sh7722.h"
+#include "sh7722_jpeglib.h"
+
+D_DEBUG_DOMAIN( SH7722_JPEG, "SH7722/JPEG", "SH7722 JPEG Processing Unit" );
+
+/**********************************************************************************************************************/
+
+static DFBResult
+Probe( IDirectFBImageProvider_ProbeContext *ctx );
+
+static DFBResult
+Construct( IDirectFBImageProvider *thiz,
+ ... );
+
+#include <direct/interface_implementation.h>
+
+DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBImageProvider, SH7722_JPEG )
+
+/*
+ * private data struct of IDirectFBImageProvider_SH7722_JPEG
+ */
+typedef struct {
+ int ref; /* reference counter */
+
+ SH7722_JPEG_context info;
+
+ CoreDFB *core;
+
+ IDirectFBDataBuffer *buffer;
+ DirectStream *stream;
+
+ DIRenderCallback render_callback;
+ void *render_callback_context;
+} IDirectFBImageProvider_SH7722_JPEG_data;
+
+/**********************************************************************************************************************/
+
+static void
+IDirectFBImageProvider_SH7722_JPEG_Destruct( IDirectFBImageProvider *thiz )
+{
+ IDirectFBImageProvider_SH7722_JPEG_data *data = thiz->priv;
+
+ data->buffer->Release( data->buffer );
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+}
+
+static DirectResult
+IDirectFBImageProvider_SH7722_JPEG_AddRef( IDirectFBImageProvider *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_SH7722_JPEG)
+
+ data->ref++;
+
+ return DFB_OK;
+}
+
+static DirectResult
+IDirectFBImageProvider_SH7722_JPEG_Release( IDirectFBImageProvider *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_SH7722_JPEG)
+
+ if (--data->ref == 0)
+ IDirectFBImageProvider_SH7722_JPEG_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBImageProvider_SH7722_JPEG_RenderTo( IDirectFBImageProvider *thiz,
+ IDirectFBSurface *destination,
+ const DFBRectangle *dest_rect )
+{
+ DFBResult ret;
+ DFBRegion clip;
+ DFBRectangle rect;
+ IDirectFBSurface_data *dst_data;
+ CoreSurface *dst_surface;
+ CoreSurfaceBufferLock lock;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_SH7722_JPEG);
+
+ if (!data->buffer)
+ return DFB_BUFFEREMPTY;
+
+ DIRECT_INTERFACE_GET_DATA_FROM(destination, dst_data, IDirectFBSurface);
+
+ dst_surface = dst_data->surface;
+ if (!dst_surface)
+ return DFB_DESTROYED;
+
+ dfb_region_from_rectangle( &clip, &dst_data->area.current );
+
+ if (dest_rect) {
+ if (dest_rect->w < 1 || dest_rect->h < 1)
+ return DFB_INVARG;
+
+ rect.x = dest_rect->x + dst_data->area.wanted.x;
+ rect.y = dest_rect->y + dst_data->area.wanted.y;
+ rect.w = dest_rect->w;
+ rect.h = dest_rect->h;
+ }
+ else
+ rect = dst_data->area.wanted;
+
+ if (!dfb_rectangle_region_intersects( &rect, &clip ))
+ return DFB_OK;
+
+ ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAID_GPU, CSAF_WRITE, &lock );
+ if (ret)
+ return ret;
+
+ ret = SH7722_JPEG_Decode( &data->info, &rect, &clip, dst_surface->config.format,
+ lock.phys, lock.addr, lock.pitch, dst_surface->config.size.w, dst_surface->config.size.h );
+
+ dfb_surface_unlock_buffer( dst_surface, &lock );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBImageProvider_SH7722_JPEG_SetRenderCallback( IDirectFBImageProvider *thiz,
+ DIRenderCallback callback,
+ void *context )
+{
+ DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_SH7722_JPEG)
+
+ data->render_callback = callback;
+ data->render_callback_context = context;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBImageProvider_SH7722_JPEG_GetSurfaceDescription( IDirectFBImageProvider *thiz,
+ DFBSurfaceDescription *desc )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_SH7722_JPEG)
+
+ if (!data->buffer)
+ return DFB_BUFFEREMPTY;
+
+ desc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;
+ desc->height = data->info.height;
+ desc->width = data->info.width;
+ desc->pixelformat = data->info.mode420 ? DSPF_NV12 : DSPF_NV16;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBImageProvider_SH7722_JPEG_GetImageDescription( IDirectFBImageProvider *thiz,
+ DFBImageDescription *desc )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_SH7722_JPEG)
+
+ if (!desc)
+ return DFB_INVARG;
+
+ if (!data->buffer)
+ return DFB_BUFFEREMPTY;
+
+ desc->caps = DICAPS_NONE;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBImageProvider_SH7722_JPEG_WriteBack( IDirectFBImageProvider *thiz,
+ IDirectFBSurface *surface,
+ const DFBRectangle *src_rect,
+ const char *filename )
+{
+ DFBResult ret;
+ DFBRegion clip;
+ DFBRectangle rect;
+ IDirectFBSurface_data *src_data;
+ CoreSurface *src_surface;
+ CoreSurfaceBufferLock lock;
+ DFBDimension jpeg_size;
+
+ CoreSurface *tmp_surface;
+ CoreSurfaceBufferLock tmp_lock;
+ int tmp_pitch;
+ unsigned int tmp_phys;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_SH7722_JPEG)
+
+ if (!surface || !filename)
+ return DFB_INVARG;
+
+ DIRECT_INTERFACE_GET_DATA_FROM(surface, src_data, IDirectFBSurface);
+
+ D_DEBUG_AT( SH7722_JPEG, "%s - surface %p, rect %p to file %s\n",
+ __FUNCTION__, surface, src_rect, filename );
+
+ src_surface = src_data->surface;
+ if (!src_surface)
+ return DFB_DESTROYED;
+
+ switch (src_surface->config.format) {
+ case DSPF_NV12:
+ case DSPF_NV16:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_RGB24:
+ break;
+
+ default:
+ /* FIXME: implement fallback */
+ D_UNIMPLEMENTED();
+ return DFB_UNIMPLEMENTED;
+ }
+
+ dfb_region_from_rectangle( &clip, &src_data->area.current );
+
+ if (src_rect) {
+ if (src_rect->w < 1 || src_rect->h < 1)
+ return DFB_INVARG;
+
+ rect.x = src_rect->x + src_data->area.wanted.x;
+ rect.y = src_rect->y + src_data->area.wanted.y;
+ rect.w = src_rect->w;
+ rect.h = src_rect->h;
+ }
+ else
+ rect = src_data->area.wanted;
+
+ if (!dfb_rectangle_region_intersects( &rect, &clip ))
+ return DFB_INVAREA;
+
+ jpeg_size.w = src_surface->config.size.w;
+ jpeg_size.h = src_surface->config.size.h;
+
+ /* it would be great if we had intermediate storage, since
+ * this prevents handling the encoding in 16-line chunks,
+ * causing scaling artefacts at the border of these chunks */
+
+ tmp_pitch = (jpeg_size.w + 3) & ~3;
+ ret = dfb_surface_create_simple( data->core, tmp_pitch, jpeg_size.h,
+ DSPF_NV16, DSCAPS_VIDEOONLY,
+ CSTF_NONE, 0, 0, &tmp_surface );
+ if( ret ) {
+ /* too bad, we proceed without */
+ D_DEBUG_AT( SH7722_JPEG, "%s - failed to create intermediate storage: %d\n",
+ __FUNCTION__, ret );
+ tmp_surface = 0;
+ tmp_phys = 0;
+ }
+ else {
+ /* lock it to get the address */
+ ret = dfb_surface_lock_buffer( tmp_surface, CSBR_FRONT, CSAID_GPU, CSAF_READ | CSAF_WRITE, &tmp_lock );
+ if (ret) {
+ D_DEBUG_AT( SH7722_JPEG, "%s - failed to lock intermediate storage: %d\n",
+ __FUNCTION__, ret );
+ dfb_surface_unref( tmp_surface );
+ tmp_surface = 0;
+ tmp_phys = 0;
+ }
+ else {
+ tmp_phys = tmp_lock.phys;
+ D_DEBUG_AT( SH7722_JPEG, "%s - surface locked at %x\n", __FUNCTION__, tmp_phys );
+ }
+ }
+
+ ret = dfb_surface_lock_buffer( src_surface, CSBR_FRONT, CSAID_GPU, CSAF_READ, &lock );
+ if ( ret == DFB_OK ) {
+ ret = SH7722_JPEG_Encode( filename, &rect, src_surface->config.format, lock.phys, lock.pitch,
+ jpeg_size.w, jpeg_size.h, tmp_phys );
+
+ dfb_surface_unlock_buffer( src_surface, &lock );
+ }
+
+ if( tmp_surface ) {
+ /* unlock and release the created surface */
+ dfb_surface_unlock_buffer( tmp_surface, &tmp_lock );
+ dfb_surface_unref( tmp_surface );
+ }
+
+ return ret;
+}
+
+/**********************************************************************************************************************/
+
+static DFBResult
+Probe( IDirectFBImageProvider_ProbeContext *ctx )
+{
+ SH7722DeviceData *sdev = dfb_gfxcard_get_device_data();
+
+#ifndef JPU_SUPPORT
+ return DFB_UNSUPPORTED;
+#endif
+
+ if (sdev->sh772x != 7722)
+ return DFB_UNSUPPORTED;
+
+ /* Called with NULL when used for encoding. */
+ if (!ctx)
+ return DFB_OK;
+
+ if (ctx->header[0] == 0xff && ctx->header[1] == 0xd8 && ctx->filename)
+ return DFB_OK;
+
+ return DFB_UNSUPPORTED;
+}
+
+static DFBResult
+Construct( IDirectFBImageProvider *thiz,
+ ... )
+{
+ DFBResult ret;
+ IDirectFBDataBuffer *buffer;
+ CoreDFB *core;
+ va_list tag;
+
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_SH7722_JPEG);
+
+ va_start( tag, thiz );
+ buffer = va_arg( tag, IDirectFBDataBuffer * );
+ core = va_arg( tag, CoreDFB * );
+ va_end( tag );
+
+ data->ref = 1;
+ data->buffer = buffer;
+ data->core = core;
+
+ if (buffer) {
+ IDirectFBDataBuffer_File_data *file_data;
+
+ ret = buffer->AddRef( buffer );
+ if (ret) {
+ DIRECT_DEALLOCATE_INTERFACE(thiz);
+ return ret;
+ }
+
+ DIRECT_INTERFACE_GET_DATA_FROM( buffer, file_data, IDirectFBDataBuffer_File );
+
+ data->stream = file_data->stream;
+
+ ret = SH7722_JPEG_Open( file_data->stream, &data->info );
+ if (ret) {
+ buffer->Release( buffer );
+ DIRECT_DEALLOCATE_INTERFACE(thiz);
+ return ret;
+ }
+ }
+
+ thiz->AddRef = IDirectFBImageProvider_SH7722_JPEG_AddRef;
+ thiz->Release = IDirectFBImageProvider_SH7722_JPEG_Release;
+ thiz->RenderTo = IDirectFBImageProvider_SH7722_JPEG_RenderTo;
+ thiz->SetRenderCallback = IDirectFBImageProvider_SH7722_JPEG_SetRenderCallback;
+ thiz->GetImageDescription = IDirectFBImageProvider_SH7722_JPEG_GetImageDescription;
+ thiz->GetSurfaceDescription = IDirectFBImageProvider_SH7722_JPEG_GetSurfaceDescription;
+ thiz->WriteBack = IDirectFBImageProvider_SH7722_JPEG_WriteBack;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeglib.c b/Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeglib.c
new file mode 100755
index 0000000..6d88da8
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeglib.c
@@ -0,0 +1,1654 @@
+#ifdef SH7722_DEBUG_JPEG
+#define DIRECT_ENABLE_DEBUG
+#endif
+
+#include <stdio.h>
+#include <jpeglib.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include <asm/types.h>
+
+#ifdef STANDALONE
+#include "sh7722_jpeglib_standalone.h"
+#else
+#undef HAVE_STDLIB_H
+#include <config.h>
+
+#include <direct/conf.h>
+#include <direct/debug.h>
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/stream.h>
+#include <direct/util.h>
+
+#include <gfx/convert.h>
+
+#include <directfb.h>
+#include <directfb_util.h>
+#endif
+
+#include <jpeglib.h>
+#include <setjmp.h>
+
+#include <sh772x_gfx.h>
+
+#include "sh7722_jpeglib.h"
+#include "sh7722_regs.h"
+
+
+D_DEBUG_DOMAIN( SH7722_JPEG, "SH7722/JPEG", "SH7722 JPEG Processing Unit" );
+
+/**********************************************************************************************************************/
+
+/*
+ * private data struct of SH7722_JPEG
+ */
+typedef struct {
+ int ref_count;
+
+ int gfx_fd;
+ SH772xGfxSharedArea *gfx_shared;
+
+ unsigned long jpeg_phys;
+ unsigned long jpeg_lb1;
+ unsigned long jpeg_lb2;
+
+ volatile void *jpeg_virt;
+
+ unsigned long mmio_phys;
+ volatile void *mmio_base;
+} SH7722_JPEG_data;
+
+/**********************************************************************************************************************/
+
+#if 1
+static inline u32
+SH7722_GETREG32( SH7722_JPEG_data *data,
+ u32 address )
+{
+ SH772xRegister reg = { address, 0 };
+
+ if (ioctl( data->gfx_fd, SH772xGFX_IOCTL_GETREG32, &reg ) < 0)
+ D_PERROR( "SH772xGFX_IOCTL_GETREG32( 0x%08x )\n", reg.address );
+
+ return reg.value;
+}
+
+static inline void
+SH7722_SETREG32( SH7722_JPEG_data *data,
+ u32 address,
+ u32 value )
+{
+ SH772xRegister reg = { address, value };
+
+ if (ioctl( data->gfx_fd, SH772xGFX_IOCTL_SETREG32, &reg ) < 0)
+ D_PERROR( "SH772xGFX_IOCTL_SETREG32( 0x%08x, 0x%08x )\n", reg.address, reg.value );
+}
+#else
+static inline u32
+SH7722_GETREG32( SH7722_JPEG_data *data,
+ u32 address )
+{
+ D_ASSERT( address >= data->mmio_phys );
+ D_ASSERT( address < (data->mmio_phys + data->mmio_length) );
+
+ return *(volatile u32*)(data->mmio_base + (address - data->mmio_phys));
+}
+
+static inline void
+SH7722_SETREG32( SH7722_JPEG_data *data,
+ u32 address,
+ u32 value )
+{
+ D_ASSERT( address >= data->mmio_phys );
+ D_ASSERT( address < (data->mmio_phys + data->mmio_length) );
+
+ *(volatile u32*)(data->mmio_base + (address - data->mmio_phys)) = value;
+}
+#endif
+
+static inline int
+coded_data_amount( SH7722_JPEG_data *data )
+{
+ return (SH7722_GETREG32(data, JCDTCU) << 16) | (SH7722_GETREG32(data, JCDTCM) << 8) | SH7722_GETREG32(data, JCDTCD);
+}
+
+/**********************************************************************************************************************/
+
+static DirectResult
+DecodeHW( SH7722_JPEG_data *data,
+ SH7722_JPEG_context *info,
+ const DFBRectangle *rect,
+ const DFBRegion *clip,
+ DFBSurfacePixelFormat format,
+ unsigned long phys,
+ int pitch,
+ unsigned int width,
+ unsigned int height )
+{
+ DirectResult ret;
+ unsigned int len;
+ int i;
+ int cw, ch;
+ bool reload = false;
+ SH772xGfxSharedArea *shared = data->gfx_shared;
+ SH7722JPEG jpeg;
+ u32 vtrcr = 0;
+ u32 vswpout = 0;
+ DirectStream *stream = info->stream;
+
+ D_ASSERT( data != NULL );
+ DFB_RECTANGLE_ASSERT( rect );
+ DFB_REGION_ASSERT( clip );
+
+ cw = clip->x2 - clip->x1 + 1;
+ ch = clip->y2 - clip->y1 + 1;
+
+ if (cw < 1 || ch < 1)
+ return DR_INVAREA;
+
+ D_DEBUG_AT( SH7722_JPEG, "%s( %p, 0x%08lx|%d [%dx%d] %s )\n", __FUNCTION__,
+ data, phys, pitch, info->width, info->height,
+ dfb_pixelformat_name(format) );
+
+ D_DEBUG_AT( SH7722_JPEG, " -> %d,%d - %4dx%4d [clip %d,%d - %4dx%4d]\n",
+ DFB_RECTANGLE_VALS( rect ), DFB_RECTANGLE_VALS_FROM_REGION( clip ) );
+
+ /*
+ * Kernel based state machine
+ *
+ * Execution enters the kernel and only returns to user space for
+ * - end of decoding
+ * - error in decoding
+ * - reload requested
+ *
+ * TODO
+ * - finish clipping (maybe not all is possible without tricky code)
+ * - modify state machine to be used by Construct(), GetSurfaceDescription() and RenderTo() to avoid redundancy
+ * - check return code and length from GetData()
+ */
+
+ /* No cropping of top or left edge :( */
+ if (clip->x1 > rect->x || clip->y1 > rect->y) {
+ D_UNIMPLEMENTED();
+ return DR_UNIMPLEMENTED;
+ }
+
+ /* Init VEU transformation control (format conversion). */
+ if (!info->mode420)
+ vtrcr |= (1 << 14);
+
+ switch (format) {
+ case DSPF_NV12:
+ vswpout = 0x70;
+ break;
+
+ case DSPF_NV16:
+ vswpout = 0x70;
+ vtrcr |= (1 << 22);
+ break;
+
+ case DSPF_RGB16:
+ vswpout = 0x60;
+ vtrcr |= (6 << 16) | 2;
+ break;
+
+ case DSPF_RGB32:
+ vswpout = 0x40;
+ vtrcr |= (19 << 16) | 2;
+ break;
+
+ case DSPF_RGB24:
+ vswpout = 0x70;
+ vtrcr |= (21 << 16) | 2;
+ break;
+
+ default:
+ D_BUG( "unexpected format %s", dfb_pixelformat_name(format) );
+ return DR_BUG;
+ }
+
+ /* Calculate destination base address. */
+ phys += DFB_BYTES_PER_LINE(format, rect->x) + rect->y * pitch;
+ jpeg.phys = phys;
+
+ D_DEBUG_AT( SH7722_JPEG, " -> locking JPU...\n" );
+
+ if (ioctl( data->gfx_fd, SH7722GFX_IOCTL_LOCK_JPEG )) {
+ ret = errno2result( errno );
+ D_PERROR( "SH7722/JPEG: Could not lock JPEG engine!\n" );
+ return ret;
+ }
+
+ D_DEBUG_AT( SH7722_JPEG, " -> loading...\n" );
+
+ /* Fill first reload buffer. */
+ ret = direct_stream_read( stream, SH7722GFX_JPEG_RELOAD_SIZE, (void*) data->jpeg_virt, &len );
+ if (ret) {
+ ioctl( data->gfx_fd, SH7722GFX_IOCTL_UNLOCK_JPEG );
+ D_DERROR( ret, "SH7722/JPEG: Could not fill first reload buffer!\n" );
+ return DR_IO;
+ }
+
+ D_DEBUG_AT( SH7722_JPEG, " -> setting...\n" );
+
+ /* Initialize JPEG state. */
+ jpeg.state = SH7722_JPEG_START;
+ jpeg.flags = 0;
+ jpeg.buffers = 1;
+
+ /* Enable reload if buffer was filled completely (coded data length >= one reload buffer). */
+ if (len == SH7722GFX_JPEG_RELOAD_SIZE) {
+ jpeg.flags |= SH7722_JPEG_FLAG_RELOAD;
+
+ reload = true;
+ }
+
+ /* Program JPU from RESET. */
+ SH7722_SETREG32( data, JCCMD, JCCMD_RESET );
+ SH7722_SETREG32( data, JCMOD, JCMOD_INPUT_CTRL | JCMOD_DSP_DECODE );
+ SH7722_SETREG32( data, JIFCNT, JIFCNT_VJSEL_JPU );
+ SH7722_SETREG32( data, JIFECNT, JIFECNT_SWAP_4321 );
+ SH7722_SETREG32( data, JIFDSA1, data->jpeg_phys );
+ SH7722_SETREG32( data, JIFDSA2, data->jpeg_phys + SH7722GFX_JPEG_RELOAD_SIZE );
+ SH7722_SETREG32( data, JIFDDRSZ, len & 0x00FFFF00 );
+
+ if (info->width == cw && info->height == ch && rect->w == cw && rect->h == ch &&
+ (( info->mode420 && format == DSPF_NV12) ||
+ (!info->mode420 && format == DSPF_NV16)))
+ {
+ /* Setup JPU for decoding in frame mode (directly to surface). */
+ SH7722_SETREG32( data, JINTE, JINTS_INS5_ERROR | JINTS_INS6_DONE |
+ (reload ? JINTS_INS14_RELOAD : 0) );
+ SH7722_SETREG32( data, JIFDCNT, JIFDCNT_SWAP_4321 | (reload ? JIFDCNT_RELOAD_ENABLE : 0) );
+
+ SH7722_SETREG32( data, JIFDDYA1, phys );
+ SH7722_SETREG32( data, JIFDDCA1, phys + pitch * height );
+ SH7722_SETREG32( data, JIFDDMW, pitch );
+ }
+ else {
+ jpeg.flags |= SH7722_JPEG_FLAG_CONVERT;
+
+ /* Setup JPU for decoding in line buffer mode. */
+ SH7722_SETREG32( data, JINTE, JINTS_INS5_ERROR | JINTS_INS6_DONE |
+ JINTS_INS11_LINEBUF0 | JINTS_INS12_LINEBUF1 |
+ (reload ? JINTS_INS14_RELOAD : 0) );
+ SH7722_SETREG32( data, JIFDCNT, JIFDCNT_LINEBUF_MODE | (SH7722GFX_JPEG_LINEBUFFER_HEIGHT << 16) |
+ JIFDCNT_SWAP_4321 | (reload ? JIFDCNT_RELOAD_ENABLE : 0) );
+
+ SH7722_SETREG32( data, JIFDDYA1, data->jpeg_lb1 );
+ SH7722_SETREG32( data, JIFDDCA1, data->jpeg_lb1 + SH7722GFX_JPEG_LINEBUFFER_SIZE_Y );
+ SH7722_SETREG32( data, JIFDDYA2, data->jpeg_lb2 );
+ SH7722_SETREG32( data, JIFDDCA2, data->jpeg_lb2 + SH7722GFX_JPEG_LINEBUFFER_SIZE_Y );
+ SH7722_SETREG32( data, JIFDDMW, SH7722GFX_JPEG_LINEBUFFER_PITCH );
+
+ /* Setup VEU for conversion/scaling (from line buffer to surface). */
+ SH7722_SETREG32( data, VEU_VBSRR, 0x00000100 );
+ SH7722_SETREG32( data, VEU_VESTR, 0x00000000 );
+ SH7722_SETREG32( data, VEU_VESWR, SH7722GFX_JPEG_LINEBUFFER_PITCH );
+ SH7722_SETREG32( data, VEU_VESSR, (info->height << 16) | info->width );
+ SH7722_SETREG32( data, VEU_VBSSR, 16 );
+ SH7722_SETREG32( data, VEU_VEDWR, pitch );
+ SH7722_SETREG32( data, VEU_VDAYR, phys );
+ SH7722_SETREG32( data, VEU_VDACR, phys + pitch * height );
+ SH7722_SETREG32( data, VEU_VTRCR, vtrcr );
+
+ SH7722_SETREG32( data, VEU_VRFCR, (((info->height << 12) / rect->h) << 16) |
+ ((info->width << 12) / rect->w) );
+ SH7722_SETREG32( data, VEU_VRFSR, (ch << 16) | cw );
+
+ SH7722_SETREG32( data, VEU_VENHR, 0x00000000 );
+ SH7722_SETREG32( data, VEU_VFMCR, 0x00000000 );
+ SH7722_SETREG32( data, VEU_VAPCR, 0x00000000 );
+ SH7722_SETREG32( data, VEU_VSWPR, 0x00000007 | vswpout );
+ SH7722_SETREG32( data, VEU_VEIER, 0x00000101 );
+ }
+
+ D_DEBUG_AT( SH7722_JPEG, " -> starting...\n" );
+
+ /* Clear interrupts in shared flags. */
+ shared->jpeg_ints = 0;
+
+ /* State machine. */
+ while (true) {
+ /* Run the state machine. */
+ if (ioctl( data->gfx_fd, SH7722GFX_IOCTL_RUN_JPEG, &jpeg ) < 0) {
+ ret = errno2result( errno );
+
+ D_PERROR( "SH7722/JPEG: SH7722GFX_IOCTL_RUN_JPEG failed!\n" );
+ break;
+ }
+
+ D_ASSERT( jpeg.state != SH7722_JPEG_START );
+
+ /* Handle end (or error). */
+ if (jpeg.state == SH7722_JPEG_END) {
+ if (jpeg.error) {
+ D_ERROR( "SH7722/JPEG: ERROR 0x%x!\n", jpeg.error );
+ ret = DR_IO;
+ }
+
+ break;
+ }
+
+ /* Check for reload requests. */
+ for (i=1; i<=2; i++) {
+ if (jpeg.buffers & i) {
+ if (jpeg.flags & SH7722_JPEG_FLAG_RELOAD) {
+ D_ASSERT( reload );
+
+ ret = direct_stream_read( stream, SH7722GFX_JPEG_RELOAD_SIZE,
+ (void*) data->jpeg_virt +
+ SH7722GFX_JPEG_RELOAD_SIZE * (i-1), &len );
+ if (ret) {
+ D_DERROR( ret, "SH7722/JPEG: Could not refill %s reload buffer!\n",
+ i == 1 ? "first" : "second" );
+ jpeg.buffers &= ~i;
+ jpeg.flags &= ~SH7722_JPEG_FLAG_RELOAD;
+ }
+ else if (len < SH7722GFX_JPEG_RELOAD_SIZE)
+ jpeg.flags &= ~SH7722_JPEG_FLAG_RELOAD;
+ }
+ else
+ jpeg.buffers &= ~i;
+ }
+ }
+ }
+
+ ioctl( data->gfx_fd, SH7722GFX_IOCTL_UNLOCK_JPEG );
+
+ return ret;
+}
+
+static int calculate_scaling( int input, int output )
+{
+ int frac = 0;
+ int mant = 0;
+
+ if( input == output ) { /* no scaling, done */
+ return 0;
+ }
+
+ mant = input / output;
+ frac = ((input * 4096 / output) & ~7) - mant * 4096;
+
+ if( input < output ) { /* upscaling */
+ if( input*8 < output ) /* out-of-range */
+ return -1;
+
+ while( output > 1 + (int)((input-1)*4096/frac) ) {
+ frac -= 8;
+ }
+ }
+ else { /* downscaling */
+ int a,size,pmant;
+
+ if( output*16 < input ) /* out-of-range */
+ return -1;
+
+ while(1) {
+ pmant = "1122333344444444"[mant] - '0';
+ a = mant * 4096 + frac;
+ size = (2*(input-1)*pmant)/(2*pmant);
+ size = (((size-1) * 4096 * pmant) + a) / a;
+
+ if( output <= size )
+ break;
+
+ if( frac )
+ frac -= 8;
+ else {
+ mant--;
+ frac = 0xff8;
+ }
+ }
+ }
+
+ return (mant << 12) + frac;
+}
+
+static DirectResult
+EncodeHW( SH7722_JPEG_data *data,
+ const char *filename,
+ const DFBRectangle *rect,
+ DFBSurfacePixelFormat format,
+ unsigned long phys,
+ int pitch,
+ unsigned int width,
+ unsigned int height,
+ unsigned long tmpphys )
+{
+ DirectResult ret;
+ int i, fd;
+ int written = 0;
+ SH772xGfxSharedArea *shared = data->gfx_shared;
+ u32 vtrcr = 0;
+ u32 vswpin = 0;
+ bool mode420 = false;
+ SH7722JPEG jpeg;
+
+ int horizontalscaling = 0;
+ int verticalscaling = 0;
+
+ int clipwidth, clipheight;
+ DFBRectangle cliprect;
+
+ /* VEU has cliprequirement of 4 bytes, input and output must be 4 pixel aligned.
+ * We have to be careful with scaling: take clipped output and input */
+
+ cliprect.h = (rect->h + 0x3) & ~0x3;
+ cliprect.w = (rect->w + 0x3) & ~0x3;
+ clipheight = (height + 0x3) & ~0x3;
+ clipwidth = (width + 0x3) & ~0x3;
+
+ D_ASSERT( data != NULL );
+ DFB_RECTANGLE_ASSERT( rect );
+
+ D_DEBUG_AT( SH7722_JPEG, "%s( %p, 0x%08lx|%d [%dx%d] %s )\n", __FUNCTION__,
+ data, phys, pitch, width, height,
+ dfb_pixelformat_name(format) );
+
+ D_DEBUG_AT( SH7722_JPEG, " -> %d,%d - %4dx%4d (at %lx)\n",
+ DFB_RECTANGLE_VALS( rect ), tmpphys );
+
+ /* JPU input is 16x16 to 2560x1920 */
+ if (width < 16 || width > 2560 || height < 16 || height > 1920)
+ return DR_INVAREA;
+
+ if (rect->w < 1 || rect->h < 1)
+ return DR_INVAREA;
+
+ horizontalscaling = calculate_scaling( cliprect.w, clipwidth );
+ verticalscaling = calculate_scaling( cliprect.h, clipheight );
+ if( !tmpphys ) {
+ /* we don't have enough memory, so we do it in 16 pixel steps */
+ int h = ((rect->h * SH7722GFX_JPEG_LINEBUFFER_HEIGHT / height) + 0x3) & ~0x3;
+ verticalscaling = calculate_scaling( h, SH7722GFX_JPEG_LINEBUFFER_HEIGHT );
+ }
+
+ /* scaling out-of-range? */
+ if( horizontalscaling == -1 || verticalscaling == -1 )
+ return DR_INVAREA;
+
+ /*
+ * Kernel based state machine
+ *
+ * Execution enters the kernel and only returns to user space for
+ * - end of encoding
+ * - error in encoding
+ * - buffer loaded
+ *
+ * TODO
+ * - finish clipping (maybe not all is possible without tricky code)
+ */
+
+ /* Init VEU transformation control (format conversion). */
+ if (format == DSPF_NV12)
+ mode420 = true;
+ else
+ vtrcr |= (1 << 22);
+
+ switch (format) {
+ case DSPF_NV12:
+ vswpin = 0x07;
+ break;
+
+ case DSPF_NV16:
+ vswpin = 0x07;
+ vtrcr |= (1 << 14);
+ break;
+
+ case DSPF_RGB16:
+ vswpin = 0x06;
+ vtrcr |= (3 << 8) | 3;
+ break;
+
+ case DSPF_RGB32:
+ vswpin = 0x04;
+ vtrcr |= (0 << 8) | 3;
+ break;
+
+ case DSPF_RGB24:
+ vswpin = 0x07;
+ vtrcr |= (2 << 8) | 3;
+ break;
+
+ default:
+ D_BUG( "unexpected format %s", dfb_pixelformat_name(format) );
+ return DR_BUG;
+ }
+
+ /* Calculate source base address. */
+ /* TODO: NV12 input with offset. Colour will be off.. */
+ phys += DFB_BYTES_PER_LINE(format, rect->x) + rect->y * pitch;
+ jpeg.phys = phys;
+
+ D_DEBUG_AT( SH7722_JPEG, " -> locking JPU...\n" );
+
+ if (ioctl( data->gfx_fd, SH7722GFX_IOCTL_LOCK_JPEG )) {
+ ret = errno2result( errno );
+ D_PERROR( "SH7722/JPEG: Could not lock JPEG engine!\n" );
+ return ret;
+ }
+
+ D_DEBUG_AT( SH7722_JPEG, " -> opening '%s' for writing...\n", filename );
+
+ fd = open( filename, O_WRONLY | O_CREAT | O_TRUNC, 0644 );
+ if (fd < 0) {
+ ret = errno2result( errno );
+ ioctl( data->gfx_fd, SH7722GFX_IOCTL_UNLOCK_JPEG );
+ D_PERROR( "SH7722/JPEG: Failed to open '%s' for writing!\n", filename );
+ return ret;
+ }
+
+ D_DEBUG_AT( SH7722_JPEG, " -> setting...\n" );
+
+ /* Initialize JPEG state. */
+ jpeg.state = SH7722_JPEG_START;
+ jpeg.flags = SH7722_JPEG_FLAG_ENCODE;
+ jpeg.buffers = 3;
+
+ /* Always enable reload mode. */
+ jpeg.flags |= SH7722_JPEG_FLAG_RELOAD;
+
+ /* Program JPU from RESET. */
+ SH7722_SETREG32( data, JCCMD, JCCMD_RESET );
+ SH7722_SETREG32( data, JCMOD, JCMOD_INPUT_CTRL | JCMOD_DSP_ENCODE | (mode420 ? 2 : 1) );
+
+ SH7722_SETREG32( data, JCQTN, 0x14 );
+ SH7722_SETREG32( data, JCHTN, 0x3C );
+ SH7722_SETREG32( data, JCDRIU, 0x02 );
+ SH7722_SETREG32( data, JCDRID, 0x00 );
+ SH7722_SETREG32( data, JCHSZU, width >> 8 );
+ SH7722_SETREG32( data, JCHSZD, width & 0xff );
+ SH7722_SETREG32( data, JCVSZU, height >> 8 );
+ SH7722_SETREG32( data, JCVSZD, height & 0xff );
+ SH7722_SETREG32( data, JIFCNT, JIFCNT_VJSEL_JPU );
+ SH7722_SETREG32( data, JIFDCNT, JIFDCNT_SWAP_4321 );
+ SH7722_SETREG32( data, JIFEDA1, data->jpeg_phys );
+ SH7722_SETREG32( data, JIFEDA2, data->jpeg_phys + SH7722GFX_JPEG_RELOAD_SIZE );
+ SH7722_SETREG32( data, JIFEDRSZ, SH7722GFX_JPEG_RELOAD_SIZE );
+ SH7722_SETREG32( data, JIFESHSZ, clipwidth );
+ SH7722_SETREG32( data, JIFESVSZ, clipheight );
+
+ if (width == rect->w && height == rect->h && (format == DSPF_NV12 || format == DSPF_NV16))
+ {
+ D_DEBUG_AT( SH7722_JPEG, " -> no VEU needed\n" );
+
+ /* no scaling, and supported format - so no VEU needed */
+ /* Setup JPU for encoding in frame mode (directly from surface). */
+ SH7722_SETREG32( data, JINTE, JINTS_INS10_XFER_DONE | JINTS_INS13_LOADED );
+ SH7722_SETREG32( data, JIFECNT, JIFECNT_SWAP_4321 | JIFECNT_RELOAD_ENABLE | (mode420 ? 1 : 0) );
+
+ SH7722_SETREG32( data, JIFESYA1, phys );
+ SH7722_SETREG32( data, JIFESCA1, phys + pitch * height );
+ SH7722_SETREG32( data, JIFESMW, pitch );
+ }
+ else {
+ /* Setup JPU for encoding in line buffer mode. */
+ jpeg.flags |= SH7722_JPEG_FLAG_CONVERT;
+ jpeg.height = height;
+ jpeg.inputheight = rect->h;
+
+ SH7722_SETREG32( data, JINTE, JINTS_INS11_LINEBUF0 | JINTS_INS12_LINEBUF1 |
+ JINTS_INS10_XFER_DONE | JINTS_INS13_LOADED );
+
+ if( tmpphys ) {
+ /* we have enough memory, so we just read one big "line" */
+ SH7722_SETREG32( data, JIFECNT, JIFECNT_LINEBUF_MODE | (height << 16) |
+ JIFECNT_SWAP_4321 | JIFECNT_RELOAD_ENABLE | (mode420 ? 1 : 0) );
+ SH7722_SETREG32( data, JIFESYA1, tmpphys );
+ SH7722_SETREG32( data, JIFESCA1, tmpphys + clipwidth * height ); /* Y is 8bpp */
+ SH7722_SETREG32( data, JIFESMW, clipwidth );
+ }
+ else {
+ SH7722_SETREG32( data, JIFECNT, JIFECNT_LINEBUF_MODE | (SH7722GFX_JPEG_LINEBUFFER_HEIGHT << 16) |
+ JIFECNT_SWAP_4321 | JIFECNT_RELOAD_ENABLE | (mode420 ? 1 : 0) );
+
+ SH7722_SETREG32( data, JIFESYA1, data->jpeg_lb1 );
+ SH7722_SETREG32( data, JIFESCA1, data->jpeg_lb1 + SH7722GFX_JPEG_LINEBUFFER_SIZE_Y );
+ SH7722_SETREG32( data, JIFESMW, SH7722GFX_JPEG_LINEBUFFER_PITCH );
+ }
+ SH7722_SETREG32( data, JIFESYA2, data->jpeg_lb2 );
+ SH7722_SETREG32( data, JIFESCA2, data->jpeg_lb2 + SH7722GFX_JPEG_LINEBUFFER_SIZE_Y );
+
+ /* we will not use the VEU in burst mode since we cannot program the
+ * destination addresses intermediately in line mode. */
+ SH7722_SETREG32( data, VEU_VBSRR, 0x00000100 );
+ SH7722_SETREG32( data, VEU_VESTR, 0x00000000 );
+ SH7722_SETREG32( data, VEU_VSAYR, phys );
+ SH7722_SETREG32( data, VEU_VSACR, phys + pitch * height );
+ SH7722_SETREG32( data, VEU_VESWR, pitch );
+
+ if( tmpphys ) {
+ SH7722_SETREG32( data, VEU_VESSR, (cliprect.h << 16) | cliprect.w );
+ SH7722_SETREG32( data, VEU_VEDWR, clipwidth );
+ SH7722_SETREG32( data, VEU_VDAYR, tmpphys );
+ SH7722_SETREG32( data, VEU_VDACR, tmpphys + clipwidth * height );
+ SH7722_SETREG32( data, VEU_VRFSR, (clipheight << 16) | clipwidth );
+ }
+ else {
+ int h = ((rect->h * SH7722GFX_JPEG_LINEBUFFER_HEIGHT / height) + 0x3) & ~0x3;
+ SH7722_SETREG32( data, VEU_VESSR, (h << 16) | cliprect.w );
+ SH7722_SETREG32( data, VEU_VEDWR, SH7722GFX_JPEG_LINEBUFFER_PITCH );
+ SH7722_SETREG32( data, VEU_VDAYR, data->jpeg_lb1 );
+ SH7722_SETREG32( data, VEU_VDACR, data->jpeg_lb1 + SH7722GFX_JPEG_LINEBUFFER_SIZE_Y );
+ SH7722_SETREG32( data, VEU_VRFSR, (SH7722GFX_JPEG_LINEBUFFER_HEIGHT << 16) | clipwidth );
+ }
+ SH7722_SETREG32( data, VEU_VRFCR, (verticalscaling << 16) | horizontalscaling );
+ SH7722_SETREG32( data, VEU_VTRCR, vtrcr );
+ SH7722_SETREG32( data, VEU_VENHR, 0x00000000 );
+ SH7722_SETREG32( data, VEU_VFMCR, 0x00000000 );
+ SH7722_SETREG32( data, VEU_VAPCR, 0x00000000 );
+ SH7722_SETREG32( data, VEU_VSWPR, 0x00000070 | vswpin );
+ SH7722_SETREG32( data, VEU_VEIER, 0x00000101 );
+ }
+
+ /* Init quantization tables. */
+ SH7722_SETREG32( data, JCQTBL0( 0), 0x100B0B0E );
+ SH7722_SETREG32( data, JCQTBL0( 1), 0x0C0A100E );
+ SH7722_SETREG32( data, JCQTBL0( 2), 0x0D0E1211 );
+ SH7722_SETREG32( data, JCQTBL0( 3), 0x10131828 );
+ SH7722_SETREG32( data, JCQTBL0( 4), 0x1A181616 );
+ SH7722_SETREG32( data, JCQTBL0( 5), 0x18312325 );
+ SH7722_SETREG32( data, JCQTBL0( 6), 0x1D283A33 );
+ SH7722_SETREG32( data, JCQTBL0( 7), 0x3D3C3933 );
+ SH7722_SETREG32( data, JCQTBL0( 8), 0x38374048 );
+ SH7722_SETREG32( data, JCQTBL0( 9), 0x5C4E4044 );
+ SH7722_SETREG32( data, JCQTBL0(10), 0x57453738 );
+ SH7722_SETREG32( data, JCQTBL0(11), 0x506D5157 );
+ SH7722_SETREG32( data, JCQTBL0(12), 0x5F626768 );
+ SH7722_SETREG32( data, JCQTBL0(13), 0x673E4D71 );
+ SH7722_SETREG32( data, JCQTBL0(14), 0x79706478 );
+ SH7722_SETREG32( data, JCQTBL0(15), 0x5C656763 );
+
+ SH7722_SETREG32( data, JCQTBL1( 0), 0x11121218 );
+ SH7722_SETREG32( data, JCQTBL1( 1), 0x15182F1A );
+ SH7722_SETREG32( data, JCQTBL1( 2), 0x1A2F6342 );
+ SH7722_SETREG32( data, JCQTBL1( 3), 0x38426363 );
+ SH7722_SETREG32( data, JCQTBL1( 4), 0x63636363 );
+ SH7722_SETREG32( data, JCQTBL1( 5), 0x63636363 );
+ SH7722_SETREG32( data, JCQTBL1( 6), 0x63636363 );
+ SH7722_SETREG32( data, JCQTBL1( 7), 0x63636363 );
+ SH7722_SETREG32( data, JCQTBL1( 8), 0x63636363 );
+ SH7722_SETREG32( data, JCQTBL1( 9), 0x63636363 );
+ SH7722_SETREG32( data, JCQTBL1(10), 0x63636363 );
+ SH7722_SETREG32( data, JCQTBL1(11), 0x63636363 );
+ SH7722_SETREG32( data, JCQTBL1(12), 0x63636363 );
+ SH7722_SETREG32( data, JCQTBL1(13), 0x63636363 );
+ SH7722_SETREG32( data, JCQTBL1(14), 0x63636363 );
+ SH7722_SETREG32( data, JCQTBL1(15), 0x63636363 );
+
+ /* Init huffman tables. */
+ SH7722_SETREG32( data, JCHTBD0(0), 0x00010501 );
+ SH7722_SETREG32( data, JCHTBD0(1), 0x01010101 );
+ SH7722_SETREG32( data, JCHTBD0(2), 0x01000000 );
+ SH7722_SETREG32( data, JCHTBD0(3), 0x00000000 );
+ SH7722_SETREG32( data, JCHTBD0(4), 0x00010203 );
+ SH7722_SETREG32( data, JCHTBD0(5), 0x04050607 );
+ SH7722_SETREG32( data, JCHTBD0(6), 0x08090A0B );
+
+ SH7722_SETREG32( data, JCHTBD1(0), 0x00030101 );
+ SH7722_SETREG32( data, JCHTBD1(1), 0x01010101 );
+ SH7722_SETREG32( data, JCHTBD1(2), 0x01010100 );
+ SH7722_SETREG32( data, JCHTBD1(3), 0x00000000 );
+ SH7722_SETREG32( data, JCHTBD1(4), 0x00010203 );
+ SH7722_SETREG32( data, JCHTBD1(5), 0x04050607 );
+ SH7722_SETREG32( data, JCHTBD1(6), 0x08090A0B );
+
+ SH7722_SETREG32( data, JCHTBA0( 0), 0x00020103 );
+ SH7722_SETREG32( data, JCHTBA0( 1), 0x03020403 );
+ SH7722_SETREG32( data, JCHTBA0( 2), 0x05050404 );
+ SH7722_SETREG32( data, JCHTBA0( 3), 0x0000017D );
+ SH7722_SETREG32( data, JCHTBA0( 4), 0x01020300 );
+ SH7722_SETREG32( data, JCHTBA0( 5), 0x04110512 );
+ SH7722_SETREG32( data, JCHTBA0( 6), 0x21314106 );
+ SH7722_SETREG32( data, JCHTBA0( 7), 0x13516107 );
+ SH7722_SETREG32( data, JCHTBA0( 8), 0x22711432 );
+ SH7722_SETREG32( data, JCHTBA0( 9), 0x8191A108 );
+ SH7722_SETREG32( data, JCHTBA0(10), 0x2342B1C1 );
+ SH7722_SETREG32( data, JCHTBA0(11), 0x1552D1F0 );
+ SH7722_SETREG32( data, JCHTBA0(12), 0x24336272 );
+ SH7722_SETREG32( data, JCHTBA0(13), 0x82090A16 );
+ SH7722_SETREG32( data, JCHTBA0(14), 0x1718191A );
+ SH7722_SETREG32( data, JCHTBA0(15), 0x25262728 );
+ SH7722_SETREG32( data, JCHTBA0(16), 0x292A3435 );
+ SH7722_SETREG32( data, JCHTBA0(17), 0x36373839 );
+ SH7722_SETREG32( data, JCHTBA0(18), 0x3A434445 );
+ SH7722_SETREG32( data, JCHTBA0(19), 0x46474849 );
+ SH7722_SETREG32( data, JCHTBA0(20), 0x4A535455 );
+ SH7722_SETREG32( data, JCHTBA0(21), 0x56575859 );
+ SH7722_SETREG32( data, JCHTBA0(22), 0x5A636465 );
+ SH7722_SETREG32( data, JCHTBA0(23), 0x66676869 );
+ SH7722_SETREG32( data, JCHTBA0(24), 0x6A737475 );
+ SH7722_SETREG32( data, JCHTBA0(25), 0x76777879 );
+ SH7722_SETREG32( data, JCHTBA0(26), 0x7A838485 );
+ SH7722_SETREG32( data, JCHTBA0(27), 0x86878889 );
+ SH7722_SETREG32( data, JCHTBA0(28), 0x8A929394 );
+ SH7722_SETREG32( data, JCHTBA0(29), 0x95969798 );
+ SH7722_SETREG32( data, JCHTBA0(30), 0x999AA2A3 );
+ SH7722_SETREG32( data, JCHTBA0(31), 0xA4A5A6A7 );
+ SH7722_SETREG32( data, JCHTBA0(32), 0xA8A9AAB2 );
+ SH7722_SETREG32( data, JCHTBA0(33), 0xB3B4B5B6 );
+ SH7722_SETREG32( data, JCHTBA0(34), 0xB7B8B9BA );
+ SH7722_SETREG32( data, JCHTBA0(35), 0xC2C3C4C5 );
+ SH7722_SETREG32( data, JCHTBA0(36), 0xC6C7C8C9 );
+ SH7722_SETREG32( data, JCHTBA0(37), 0xCAD2D3D4 );
+ SH7722_SETREG32( data, JCHTBA0(38), 0xD5D6D7D8 );
+ SH7722_SETREG32( data, JCHTBA0(39), 0xD9DAE1E2 );
+ SH7722_SETREG32( data, JCHTBA0(40), 0xE3E4E5E6 );
+ SH7722_SETREG32( data, JCHTBA0(41), 0xE7E8E9EA );
+ SH7722_SETREG32( data, JCHTBA0(42), 0xF1F2F3F4 );
+ SH7722_SETREG32( data, JCHTBA0(43), 0xF5F6F7F8 );
+ SH7722_SETREG32( data, JCHTBA0(44), 0xF9FA0000 );
+
+ SH7722_SETREG32( data, JCHTBA1( 0), 0x00020102 );
+ SH7722_SETREG32( data, JCHTBA1( 1), 0x04040304 );
+ SH7722_SETREG32( data, JCHTBA1( 2), 0x07050404 );
+ SH7722_SETREG32( data, JCHTBA1( 3), 0x00010277 );
+ SH7722_SETREG32( data, JCHTBA1( 4), 0x00010203 );
+ SH7722_SETREG32( data, JCHTBA1( 5), 0x11040521 );
+ SH7722_SETREG32( data, JCHTBA1( 6), 0x31061241 );
+ SH7722_SETREG32( data, JCHTBA1( 7), 0x51076171 );
+ SH7722_SETREG32( data, JCHTBA1( 8), 0x13223281 );
+ SH7722_SETREG32( data, JCHTBA1( 9), 0x08144291 );
+ SH7722_SETREG32( data, JCHTBA1(10), 0xA1B1C109 );
+ SH7722_SETREG32( data, JCHTBA1(11), 0x233352F0 );
+ SH7722_SETREG32( data, JCHTBA1(12), 0x156272D1 );
+ SH7722_SETREG32( data, JCHTBA1(13), 0x0A162434 );
+ SH7722_SETREG32( data, JCHTBA1(14), 0xE125F117 );
+ SH7722_SETREG32( data, JCHTBA1(15), 0x18191A26 );
+ SH7722_SETREG32( data, JCHTBA1(16), 0x2728292A );
+ SH7722_SETREG32( data, JCHTBA1(17), 0x35363738 );
+ SH7722_SETREG32( data, JCHTBA1(18), 0x393A4344 );
+ SH7722_SETREG32( data, JCHTBA1(19), 0x45464748 );
+ SH7722_SETREG32( data, JCHTBA1(20), 0x494A5354 );
+ SH7722_SETREG32( data, JCHTBA1(21), 0x55565758 );
+ SH7722_SETREG32( data, JCHTBA1(22), 0x595A6364 );
+ SH7722_SETREG32( data, JCHTBA1(23), 0x65666768 );
+ SH7722_SETREG32( data, JCHTBA1(24), 0x696A7374 );
+ SH7722_SETREG32( data, JCHTBA1(25), 0x75767778 );
+ SH7722_SETREG32( data, JCHTBA1(26), 0x797A8283 );
+ SH7722_SETREG32( data, JCHTBA1(27), 0x84858687 );
+ SH7722_SETREG32( data, JCHTBA1(28), 0x88898A92 );
+ SH7722_SETREG32( data, JCHTBA1(29), 0x93949596 );
+ SH7722_SETREG32( data, JCHTBA1(30), 0x9798999A );
+ SH7722_SETREG32( data, JCHTBA1(31), 0xA2A3A4A5 );
+ SH7722_SETREG32( data, JCHTBA1(32), 0xA6A7A8A9 );
+ SH7722_SETREG32( data, JCHTBA1(33), 0xAAB2B3B4 );
+ SH7722_SETREG32( data, JCHTBA1(34), 0xB5B6B7B8 );
+ SH7722_SETREG32( data, JCHTBA1(35), 0xB9BAC2C3 );
+ SH7722_SETREG32( data, JCHTBA1(36), 0xC4C5C6C7 );
+ SH7722_SETREG32( data, JCHTBA1(37), 0xC8C9CAD2 );
+ SH7722_SETREG32( data, JCHTBA1(38), 0xD3D4D5D6 );
+ SH7722_SETREG32( data, JCHTBA1(39), 0xD7D8D9DA );
+ SH7722_SETREG32( data, JCHTBA1(40), 0xE2E3E4E5 );
+ SH7722_SETREG32( data, JCHTBA1(41), 0xE6E7E8E9 );
+ SH7722_SETREG32( data, JCHTBA1(42), 0xEAF2F3F4 );
+ SH7722_SETREG32( data, JCHTBA1(43), 0xF5F6F7F8 );
+ SH7722_SETREG32( data, JCHTBA1(44), 0xF9FA0000 );
+
+ /* Clear interrupts in shared flags. */
+ shared->jpeg_ints = 0;
+
+ D_DEBUG_AT( SH7722_JPEG, " -> starting...\n" );
+
+ /* State machine. */
+ while (true) {
+ /* Run the state machine. */
+ if (ioctl( data->gfx_fd, SH7722GFX_IOCTL_RUN_JPEG, &jpeg ) < 0) {
+ ret = errno2result( errno );
+
+ D_PERROR( "SH7722/JPEG: SH7722GFX_IOCTL_RUN_JPEG failed!\n" );
+ break;
+ }
+
+ D_ASSERT( jpeg.state != SH7722_JPEG_START );
+
+ /* Check for loaded buffers. */
+ for (i=1; i<=2; i++) {
+ if (jpeg.buffers & i) {
+ int amount = coded_data_amount( data ) - written;
+
+ if (amount > SH7722GFX_JPEG_RELOAD_SIZE)
+ amount = SH7722GFX_JPEG_RELOAD_SIZE;
+
+ D_INFO( "SH7722/JPEG: Coded data amount: + %5d (buffer %d)\n", amount, i );
+
+ written += write( fd, (void*) data->jpeg_virt + SH7722GFX_JPEG_RELOAD_SIZE * (i-1), amount );
+ }
+ }
+
+ /* Handle end (or error). */
+ if (jpeg.state == SH7722_JPEG_END) {
+ if (jpeg.error) {
+ D_ERROR( "SH7722/JPEG: ERROR 0x%x!\n", jpeg.error );
+ ret = DR_IO;
+ }
+
+ break;
+ }
+ }
+
+ D_INFO( "SH7722/JPEG: Coded data amount: = %5d (written: %d, buffers: %d)\n",
+ coded_data_amount( data ), written, jpeg.buffers );
+
+ ioctl( data->gfx_fd, SH7722GFX_IOCTL_UNLOCK_JPEG );
+
+ close( fd );
+
+ return DR_OK;
+}
+
+#if 0
+static DirectResult
+DecodeHeader( SH7722_JPEG_data *data,
+ DirectStream *stream,
+ SH7722_JPEG_context *info )
+{
+ DirectResult ret;
+ unsigned int len;
+ SH772xGfxSharedArea *shared;
+
+ D_DEBUG_AT( SH7722_JPEG, "%s( %p )\n", __FUNCTION__, data );
+
+ D_ASSERT( data != NULL );
+
+ shared = data->gfx_shared;
+
+ /*
+ * Do minimal stuff to decode the image header, serving as a good probe mechanism as well.
+ */
+
+ D_DEBUG_AT( SH7722_JPEG, " -> locking JPU...\n" );
+
+ if (ioctl( data->gfx_fd, SH7722GFX_IOCTL_LOCK_JPEG )) {
+ ret = errno2result( errno );
+ D_PERROR( "SH7722/JPEG: Could not lock JPEG engine!\n" );
+ return ret;
+ }
+
+ D_DEBUG_AT( SH7722_JPEG, " -> loading 32k...\n" );
+
+ /* Prefill reload buffer with 32k. */
+ ret = direct_stream_peek( stream, 32*1024, 0, (void*) data->jpeg_virt, &len );
+ if (ret) {
+ ioctl( data->gfx_fd, SH7722GFX_IOCTL_UNLOCK_JPEG );
+ D_DEBUG_AT( SH7722_JPEG, " -> ERROR from PeekData(): %s\n", DirectResultString(ret) );
+ return DR_IO;
+ }
+
+ D_DEBUG_AT( SH7722_JPEG, " -> %u bytes loaded, setting...\n", len );
+
+ /* Program JPU from RESET. */
+ SH7722_SETREG32( data, JCCMD, JCCMD_RESET );
+ SH7722_SETREG32( data, JCMOD, JCMOD_INPUT_CTRL | JCMOD_DSP_DECODE );
+ SH7722_SETREG32( data, JINTE, JINTS_INS3_HEADER | JINTS_INS5_ERROR );
+ SH7722_SETREG32( data, JIFCNT, JIFCNT_VJSEL_JPU );
+ SH7722_SETREG32( data, JIFECNT, JIFECNT_SWAP_4321 );
+ SH7722_SETREG32( data, JIFDCNT, JIFDCNT_SWAP_4321 );
+ SH7722_SETREG32( data, JIFDSA1, data->jpeg_phys );
+ SH7722_SETREG32( data, JIFDDRSZ, len );
+
+ D_DEBUG_AT( SH7722_JPEG, " -> starting...\n" );
+
+ /* Clear interrupts in shared flags. */
+ shared->jpeg_ints = 0;
+
+ /* Start decoder and begin reading from buffer. */
+ SH7722_SETREG32( data, JCCMD, JCCMD_START );
+
+ /* Stall machine. */
+ while (true) {
+ /* Check for new interrupts in shared flags... */
+ u32 ints = shared->jpeg_ints;
+ if (ints) {
+ /* ...and clear them (FIXME: race condition in case of multiple IRQs per command!). */
+ shared->jpeg_ints &= ~ints;
+
+ D_DEBUG_AT( SH7722_JPEG, " -> JCSTS 0x%08x, JINTS 0x%08x\n", SH7722_GETREG32( data, JCSTS ), ints );
+
+ /* Check for errors! */
+ if (ints & JINTS_INS5_ERROR) {
+ D_ERROR( "SH7722/JPEG: ERROR 0x%x!\n", SH7722_GETREG32( data, JCDERR ) );
+ ioctl( data->gfx_fd, SH7722GFX_IOCTL_UNLOCK_JPEG );
+ return DR_IO;
+ }
+
+ /* Check for header interception... */
+ if (ints & JINTS_INS3_HEADER) {
+ /* ...remember image information... */
+ info->width = SH7722_GETREG32( data, JIFDDHSZ );
+ info->height = SH7722_GETREG32( data, JIFDDVSZ );
+ info->mode420 = (SH7722_GETREG32( data, JCMOD ) & 2) ? true : false;
+
+ D_DEBUG_AT( SH7722_JPEG, " -> %dx%d (4:2:%c)\n",
+ info->width, info->height, info->mode420 ? '0' : '2' );
+
+ break;
+ }
+ }
+ else {
+ D_DEBUG_AT( SH7722_JPEG, " -> waiting...\n" );
+
+ /* ...otherwise wait for the arrival of new interrupt(s). */
+ if (ioctl( data->gfx_fd, SH7722GFX_IOCTL_WAIT_JPEG ) < 0) {
+ D_PERROR( "SH7722/JPEG: Waiting for IRQ failed! (ints: 0x%x - JINTS 0x%x, JCSTS 0x%x)\n",
+ ints, SH7722_GETREG32( data, JINTS ), SH7722_GETREG32( data, JCSTS ) );
+ ioctl( data->gfx_fd, SH7722GFX_IOCTL_UNLOCK_JPEG );
+ return DR_FAILURE;
+ }
+ }
+ }
+
+ ioctl( data->gfx_fd, SH7722GFX_IOCTL_UNLOCK_JPEG );
+
+ if (info->width < 16 || info->width > 2560)
+ return DR_UNSUPPORTED;
+
+ if (info->height < 16 || info->height > 1920)
+ return DR_UNSUPPORTED;
+
+ return DR_OK;
+}
+#endif
+
+/**********************************************************************************************************************/
+
+static void write_rgb_span( u8 *src, void *dst, int len, DFBSurfacePixelFormat format )
+{
+ int i;
+
+ switch (format) {
+ case DSPF_RGB332:
+ for (i = 0; i < len; i++)
+ ((u8*)dst)[i] = PIXEL_RGB332( src[i*3+0], src[i*3+1], src[i*3+2] );
+ break;
+
+ case DSPF_ARGB1555:
+ for (i = 0; i < len; i++)
+ ((u16*)dst)[i] = PIXEL_ARGB1555( 0xff, src[i*3+0], src[i*3+1], src[i*3+2] );
+ break;
+
+ case DSPF_ARGB2554:
+ for (i = 0; i < len; i++)
+ ((u16*)dst)[i] = PIXEL_ARGB2554( 0xff, src[i*3+0], src[i*3+1], src[i*3+2] );
+ break;
+
+ case DSPF_ARGB4444:
+ for (i = 0; i < len; i++)
+ ((u16*)dst)[i] = PIXEL_ARGB4444( 0xff, src[i*3+0], src[i*3+1], src[i*3+2] );
+ break;
+
+ case DSPF_RGB16:
+ for (i = 0; i < len; i++)
+ ((u16*)dst)[i] = PIXEL_RGB16( src[i*3+0], src[i*3+1], src[i*3+2] );
+ break;
+
+ case DSPF_RGB24:
+ direct_memcpy( dst, src, len*3 );
+ break;
+
+ case DSPF_RGB32:
+ for (i = 0; i < len; i++)
+ ((u32*)dst)[i] = PIXEL_RGB32( src[i*3+0], src[i*3+1], src[i*3+2] );
+ break;
+
+ case DSPF_ARGB:
+ for (i = 0; i < len; i++)
+ ((u32*)dst)[i] = PIXEL_ARGB( 0xff, src[i*3+0], src[i*3+1], src[i*3+2] );
+ break;
+
+ case DSPF_AiRGB:
+ for (i = 0; i < len; i++)
+ ((u32*)dst)[i] = PIXEL_AiRGB( 0xff, src[i*3+0], src[i*3+1], src[i*3+2] );
+ break;
+
+ case DSPF_RGB555:
+ for (i = 0; i < len; i++)
+ ((u16*)dst)[i] = PIXEL_RGB555( src[i*3+0], src[i*3+1], src[i*3+2] );
+ break;
+
+ case DSPF_BGR555:
+ for (i = 0; i < len; i++)
+ ((u16*)dst)[i] = PIXEL_BGR555( src[i*3+0], src[i*3+1], src[i*3+2] );
+ break;
+
+ case DSPF_RGB444:
+ for (i = 0; i < len; i++)
+ ((u16*)dst)[i] = PIXEL_RGB444( src[i*3+0], src[i*3+1], src[i*3+2] );
+ break;
+
+ default:
+ D_ONCE( "unimplemented destination format (0x%08x)", format );
+ break;
+ }
+}
+
+static inline void
+copy_line_nv16( u16 *yy, u16 *cbcr, const u8 *src_ycbcr, int width )
+{
+ int x;
+
+ D_ASSUME( !(width & 1) );
+
+ for (x=0; x<width/2; x++) {
+#ifdef WORDS_BIGENDIAN
+ yy[x] = (src_ycbcr[0] << 8) | src_ycbcr[3];
+#else
+ yy[x] = (src_ycbcr[3] << 8) | src_ycbcr[0];
+#endif
+
+ cbcr[x] = (((src_ycbcr[2] + src_ycbcr[5]) << 7) & 0xff00) |
+ ((src_ycbcr[1] + src_ycbcr[4]) >> 1);
+
+ src_ycbcr += 6;
+ }
+}
+
+static inline void
+copy_line_y( u16 *yy, const u8 *src_ycbcr, int width )
+{
+ int x;
+
+ D_ASSUME( !(width & 1) );
+
+ for (x=0; x<width/2; x++) {
+#ifdef WORDS_BIGENDIAN
+ yy[x] = (src_ycbcr[0] << 8) | src_ycbcr[3];
+#else
+ yy[x] = (src_ycbcr[3] << 8) | src_ycbcr[0];
+#endif
+
+ src_ycbcr += 6;
+ }
+}
+
+static DirectResult
+DecodeSW( SH7722_JPEG_context *info,
+ const DFBRectangle *rect,
+ const DFBRegion *clip,
+ DFBSurfacePixelFormat format,
+ void *addr,
+ int pitch,
+ unsigned int width,
+ unsigned int height )
+{
+ int cw, ch;
+ JSAMPARRAY buffer; /* Output row buffer */
+ int row_stride; /* physical row width in output buffer */
+ void *addr_uv = addr + height * pitch;
+
+ D_ASSERT( info != NULL );
+ DFB_RECTANGLE_ASSERT( rect );
+ DFB_REGION_ASSERT( clip );
+
+ cw = clip->x2 - clip->x1 + 1;
+ ch = clip->y2 - clip->y1 + 1;
+
+ if (cw < 1 || ch < 1)
+ return DR_INVAREA;
+
+ D_DEBUG_AT( SH7722_JPEG, "%s( %p, %p|%d [%dx%d] %s )\n", __FUNCTION__,
+ info, addr, pitch, info->width, info->height,
+ dfb_pixelformat_name(format) );
+
+ D_DEBUG_AT( SH7722_JPEG, " -> %d,%d - %4dx%4d [clip %d,%d - %4dx%4d]\n",
+ DFB_RECTANGLE_VALS( rect ), DFB_RECTANGLE_VALS_FROM_REGION( clip ) );
+
+ /* No cropping or clipping yet :( */
+ if (clip->x1 != 0 || clip->y1 != 0 ||
+ clip->x2 != rect->w - 1 || clip->y2 != rect->h - 1 || rect->w != width || rect->h != height)
+ {
+ D_UNIMPLEMENTED();
+ return DR_UNIMPLEMENTED;
+ }
+
+ info->cinfo.output_components = 3;
+
+ /* Calculate destination base address. */
+ addr += DFB_BYTES_PER_LINE( format, rect->x ) + rect->y * pitch;
+
+ /* Not all formats yet :( */
+ switch (format) {
+ case DSPF_RGB332:
+ case DSPF_ARGB1555:
+ case DSPF_ARGB2554:
+ case DSPF_ARGB4444:
+ case DSPF_RGB16:
+ case DSPF_RGB24:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ case DSPF_AiRGB:
+ case DSPF_RGB555:
+ case DSPF_BGR555:
+ case DSPF_RGB444:
+ info->cinfo.out_color_space = JCS_RGB;
+ break;
+
+ case DSPF_NV12:
+ if (rect->x & 1)
+ return DFB_INVARG;
+
+ if (rect->y & 1)
+ return DFB_INVARG;
+
+ addr_uv += rect->x + rect->y / 2 * pitch;
+
+ info->cinfo.out_color_space = JCS_YCbCr;
+ break;
+
+ case DSPF_NV16:
+ if (rect->x & 1)
+ return DFB_INVARG;
+
+ addr_uv += rect->x + rect->y * pitch;
+
+ info->cinfo.out_color_space = JCS_YCbCr;
+ break;
+
+ default:
+ D_UNIMPLEMENTED();
+ return DR_UNIMPLEMENTED;
+ }
+
+ D_DEBUG_AT( SH7722_JPEG, " -> decoding...\n" );
+
+ jpeg_start_decompress( &info->cinfo );
+
+ row_stride = ((info->cinfo.output_width + 1) & ~1) * 3;
+
+ buffer = (*info->cinfo.mem->alloc_sarray)((j_common_ptr) &info->cinfo, JPOOL_IMAGE, row_stride, 1);
+
+ while (info->cinfo.output_scanline < info->cinfo.output_height) {
+ jpeg_read_scanlines( &info->cinfo, buffer, 1 );
+
+ switch (format) {
+ case DSPF_NV12:
+ if (info->cinfo.output_scanline & 1) {
+ copy_line_nv16( addr, addr_uv, *buffer, (rect->w + 1) & ~1 );
+ addr_uv += pitch;
+ }
+ else
+ copy_line_y( addr, *buffer, (rect->w + 1) & ~1 );
+ break;
+
+ case DSPF_NV16:
+ copy_line_nv16( addr, addr_uv, *buffer, (rect->w + 1) & ~1 );
+ addr_uv += pitch;
+ break;
+
+ default:
+ write_rgb_span( *buffer, addr, rect->w, format );
+ break;
+ }
+
+ addr += pitch;
+ }
+
+ jpeg_finish_decompress( &info->cinfo );
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+static DirectResult
+Initialize_GFX( SH7722_JPEG_data *data )
+{
+ D_DEBUG_AT( SH7722_JPEG, "%s( %p )\n", __FUNCTION__, data );
+
+ /* Open the drawing engine device. */
+ data->gfx_fd = direct_try_open( "/dev/sh772x_gfx", "/dev/misc/sh772x_gfx", O_RDWR, true );
+ if (data->gfx_fd < 0)
+ return DR_INIT;
+
+ /* Map its shared data. */
+ data->gfx_shared = mmap( NULL, direct_page_align( sizeof(SH772xGfxSharedArea) ),
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED, data->gfx_fd, 0 );
+ if (data->gfx_shared == MAP_FAILED) {
+ D_PERROR( "SH7722/GFX: Could not map shared area!\n" );
+ close( data->gfx_fd );
+ return DR_INIT;
+ }
+
+ D_DEBUG_AT( SH7722_JPEG, " -> magic 0x%08x\n", data->gfx_shared->magic );
+ D_DEBUG_AT( SH7722_JPEG, " -> buffer 0x%08lx\n", data->gfx_shared->buffer_phys );
+ D_DEBUG_AT( SH7722_JPEG, " -> jpeg 0x%08lx\n", data->gfx_shared->jpeg_phys );
+
+ /* Check the magic value. */
+ if (data->gfx_shared->magic != SH7722GFX_SHARED_MAGIC) {
+ D_ERROR( "SH7722/GFX: Magic value 0x%08x doesn't match 0x%08x!\n",
+ data->gfx_shared->magic, SH7722GFX_SHARED_MAGIC );
+ munmap( (void*) data->gfx_shared, direct_page_align( sizeof(SH772xGfxSharedArea) ) );
+ close( data->gfx_fd );
+ return DR_INIT;
+ }
+
+ return DR_OK;
+}
+
+static DirectResult
+Shutdown_GFX( SH7722_JPEG_data *data )
+{
+ munmap( (void*) data->gfx_shared, direct_page_align( sizeof(SH772xGfxSharedArea) ) );
+
+ close( data->gfx_fd );
+
+ return DR_OK;
+}
+
+/**********************************************************************************************************************/
+
+static DirectResult
+Initialize_Mem( SH7722_JPEG_data *data,
+ unsigned long phys )
+{
+ int fd;
+
+ D_DEBUG_AT( SH7722_JPEG, "%s( %p, 0x%08lx )\n", __FUNCTION__, data, phys );
+
+ fd = open( "/dev/mem", O_RDWR | O_SYNC );
+ if (fd < 0) {
+ D_PERROR( "SH7722/JPEG: Could not open /dev/mem!\n" );
+ return DR_INIT;
+ }
+
+ data->jpeg_virt = mmap( NULL, direct_page_align( SH7722GFX_JPEG_SIZE ),
+ PROT_READ | PROT_WRITE, MAP_SHARED, fd, phys );
+ if (data->jpeg_virt == MAP_FAILED) {
+ D_PERROR( "SH7722/JPEG: Could not map /dev/mem at 0x%08lx (length %lu)!\n",
+ phys, direct_page_align( SH7722GFX_JPEG_SIZE ) );
+ close( fd );
+ return DR_INIT;
+ }
+
+ data->jpeg_phys = phys;
+ data->jpeg_lb1 = data->jpeg_phys + SH7722GFX_JPEG_RELOAD_SIZE * 2;
+ data->jpeg_lb2 = data->jpeg_lb1 + SH7722GFX_JPEG_LINEBUFFER_SIZE;
+
+ close( fd );
+
+ return DR_OK;
+}
+
+static DirectResult
+Shutdown_Mem( SH7722_JPEG_data *data )
+{
+ munmap( (void*) data->jpeg_virt, direct_page_align( SH7722GFX_JPEG_SIZE ) );
+
+ return DR_OK;
+}
+
+/**********************************************************************************************************************/
+
+#define JPEG_PROG_BUF_SIZE 0x10000
+
+typedef struct {
+ struct jpeg_source_mgr pub; /* public fields */
+
+ JOCTET *data; /* start of buffer */
+
+ DirectStream *stream;
+
+ int peekonly;
+ int peekoffset;
+} stream_source_mgr;
+
+typedef stream_source_mgr * stream_src_ptr;
+
+static void
+stream_init_source (j_decompress_ptr cinfo)
+{
+ stream_src_ptr src = (stream_src_ptr) cinfo->src;
+
+ direct_stream_seek( src->stream, 0 ); /* ignore return value */
+}
+
+static boolean
+stream_fill_input_buffer (j_decompress_ptr cinfo)
+{
+ DFBResult ret;
+ unsigned int nbytes = 0;
+ stream_src_ptr src = (stream_src_ptr) cinfo->src;
+
+ struct timeval tv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 50000;
+
+ direct_stream_wait( src->stream, JPEG_PROG_BUF_SIZE, &tv );
+
+ if (src->peekonly) {
+ ret = direct_stream_peek( src->stream, JPEG_PROG_BUF_SIZE, src->peekoffset, src->data, &nbytes );
+ if (ret && ret != DFB_EOF)
+ D_DERROR( ret, "SH7722/JPEG: direct_stream_peek() failed!\n" );
+
+ src->peekoffset += MAX( nbytes, 0 );
+ }
+ else {
+ ret = direct_stream_read( src->stream, JPEG_PROG_BUF_SIZE, src->data, &nbytes );
+ if (ret && ret != DFB_EOF)
+ D_DERROR( ret, "SH7722/JPEG: direct_stream_read() failed!\n" );
+ }
+
+ if (ret || nbytes <= 0) {
+ /* Insert a fake EOI marker */
+ src->data[0] = (JOCTET) 0xFF;
+ src->data[1] = (JOCTET) JPEG_EOI;
+ nbytes = 2;
+ }
+
+ src->pub.next_input_byte = src->data;
+ src->pub.bytes_in_buffer = nbytes;
+
+ return TRUE;
+}
+
+static void
+stream_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
+{
+ stream_src_ptr src = (stream_src_ptr) cinfo->src;
+
+ if (num_bytes > 0) {
+ while (num_bytes > (long) src->pub.bytes_in_buffer) {
+ num_bytes -= (long) src->pub.bytes_in_buffer;
+ (void)stream_fill_input_buffer(cinfo);
+ }
+ src->pub.next_input_byte += (size_t) num_bytes;
+ src->pub.bytes_in_buffer -= (size_t) num_bytes;
+ }
+}
+
+static void
+stream_term_source (j_decompress_ptr cinfo)
+{
+}
+
+static void
+jpeg_stream_src (j_decompress_ptr cinfo, DirectStream *stream, int peekonly)
+{
+ stream_src_ptr src;
+
+ cinfo->src = (struct jpeg_source_mgr *)
+ cinfo->mem->alloc_small ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ sizeof (stream_source_mgr));
+
+ src = (stream_src_ptr) cinfo->src;
+
+ src->data = (JOCTET *)
+ cinfo->mem->alloc_small ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ JPEG_PROG_BUF_SIZE * sizeof (JOCTET));
+
+ src->stream = stream;
+ src->peekonly = peekonly;
+ src->peekoffset = 0;
+
+ src->pub.init_source = stream_init_source;
+ src->pub.fill_input_buffer = stream_fill_input_buffer;
+ src->pub.skip_input_data = stream_skip_input_data;
+ src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
+ src->pub.term_source = stream_term_source;
+ src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
+ src->pub.next_input_byte = NULL; /* until buffer loaded */
+}
+
+struct my_error_mgr {
+ struct jpeg_error_mgr pub; /* "public" fields */
+ jmp_buf setjmp_buffer; /* for return to caller */
+};
+
+static void
+jpeglib_panic(j_common_ptr cinfo)
+{
+ struct my_error_mgr *myerr = (struct my_error_mgr*) cinfo->err;
+ longjmp(myerr->setjmp_buffer, 1);
+}
+
+/**********************************************************************************************************************/
+
+static SH7722_JPEG_data data;
+
+DirectResult
+SH7722_JPEG_Initialize( void )
+{
+ DirectResult ret;
+
+ if (data.ref_count) {
+ data.ref_count++;
+ return DR_OK;
+ }
+
+ ret = Initialize_GFX( &data );
+ if (ret)
+ return ret;
+
+ ret = Initialize_Mem( &data, data.gfx_shared->jpeg_phys );
+ if (ret) {
+ Shutdown_GFX( &data );
+ return ret;
+ }
+
+ data.ref_count = 1;
+
+ return DR_OK;
+}
+
+DirectResult
+SH7722_JPEG_Shutdown( void )
+{
+ if (!data.ref_count)
+ return DR_DEAD;
+
+ if (--data.ref_count)
+ return DR_OK;
+
+ Shutdown_Mem( &data );
+
+ Shutdown_GFX( &data );
+
+ return DR_OK;
+}
+
+DirectResult
+SH7722_JPEG_Open( DirectStream *stream,
+ SH7722_JPEG_context *context )
+{
+ struct my_error_mgr jerr;
+
+ if (!data.ref_count)
+ return DR_DEAD;
+
+ context->cinfo.err = jpeg_std_error( &jerr.pub );
+ jerr.pub.error_exit = jpeglib_panic;
+
+ if (setjmp( jerr.setjmp_buffer )) {
+ D_ERROR( "SH7722/JPEG: Error while reading headers!\n" );
+
+ jpeg_destroy_decompress( &context->cinfo );
+ return DFB_FAILURE;
+ }
+
+ jpeg_create_decompress( &context->cinfo );
+ jpeg_stream_src( &context->cinfo, stream, 1 );
+ jpeg_read_header( &context->cinfo, TRUE );
+ jpeg_calc_output_dimensions( &context->cinfo );
+
+ context->stream = stream;
+ context->width = context->cinfo.output_width;
+ context->height = context->cinfo.output_height;
+
+ context->mode420 = context->cinfo.comp_info[1].h_samp_factor == context->cinfo.comp_info[0].h_samp_factor / 2 &&
+ context->cinfo.comp_info[1].v_samp_factor == context->cinfo.comp_info[0].v_samp_factor / 2 &&
+ context->cinfo.comp_info[2].h_samp_factor == context->cinfo.comp_info[0].h_samp_factor / 2 &&
+ context->cinfo.comp_info[2].v_samp_factor == context->cinfo.comp_info[0].v_samp_factor / 2;
+
+ context->mode444 = context->cinfo.comp_info[1].h_samp_factor == context->cinfo.comp_info[0].h_samp_factor &&
+ context->cinfo.comp_info[1].v_samp_factor == context->cinfo.comp_info[0].v_samp_factor &&
+ context->cinfo.comp_info[2].h_samp_factor == context->cinfo.comp_info[0].h_samp_factor &&
+ context->cinfo.comp_info[2].v_samp_factor == context->cinfo.comp_info[0].v_samp_factor;
+
+ return DFB_OK;
+}
+
+DirectResult
+SH7722_JPEG_Decode( SH7722_JPEG_context *context,
+ const DFBRectangle *rect,
+ const DFBRegion *clip,
+ DFBSurfacePixelFormat format,
+ unsigned long phys,
+ void *addr,
+ int pitch,
+ unsigned int width,
+ unsigned int height )
+{
+ DFBResult ret = DFB_UNSUPPORTED;
+ DFBRectangle _rect;
+ DFBRegion _clip;
+ struct my_error_mgr jerr;
+ bool sw_only = false;
+
+ if (!data.ref_count)
+ return DR_DEAD;
+
+ context->cinfo.err = jpeg_std_error( &jerr.pub );
+ jerr.pub.error_exit = jpeglib_panic;
+
+ if (setjmp( jerr.setjmp_buffer )) {
+ D_ERROR( "SH7722/JPEG: Error while decoding image!\n" );
+ return DFB_FAILURE;
+ }
+
+ switch (format) {
+ case DSPF_NV12:
+ case DSPF_NV16:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_RGB24:
+ break;
+
+ case DSPF_RGB332:
+ case DSPF_ARGB1555:
+ case DSPF_ARGB2554:
+ case DSPF_ARGB4444:
+ case DSPF_ARGB:
+ case DSPF_AiRGB:
+ case DSPF_RGB555:
+ case DSPF_BGR555:
+ case DSPF_RGB444:
+ sw_only = true;
+ break;
+
+ default:
+ return DR_UNSUPPORTED;
+ }
+
+ if (!rect) {
+ _rect.x = 0;
+ _rect.y = 0;
+ _rect.w = width;
+ _rect.h = height;
+
+ rect = &_rect;
+ }
+
+ if (!clip) {
+ _clip.x1 = _rect.x;
+ _clip.y1 = _rect.y;
+ _clip.x2 = _rect.x + _rect.w - 1;
+ _clip.y2 = _rect.y + _rect.h - 1;
+
+ clip = &_clip;
+ }
+
+ if (!context->mode444 && !sw_only)
+ ret = DecodeHW( &data, context, rect, clip, format, phys, pitch, width, height );
+
+ if (ret) {
+ if (addr) {
+ ret = DecodeSW( context, rect, clip, format, addr, pitch, width, height );
+ }
+ else {
+ int fd, len = direct_page_align( DFB_PLANE_MULTIPLY( format, height ) * pitch );
+
+ fd = open( "/dev/mem", O_RDWR | O_SYNC );
+ if (fd < 0) {
+ D_PERROR( "SH7722/JPEG: Could not open /dev/mem!\n" );
+ return DR_INIT;
+ }
+
+ addr = mmap( NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, phys );
+ if (addr == MAP_FAILED) {
+ D_PERROR( "SH7722/JPEG: Could not map /dev/mem at 0x%08lx (length %d)!\n", phys, len );
+ close( fd );
+ return DR_INIT;
+ }
+
+ ret = DecodeSW( context, rect, clip, format, addr, pitch, width, height );
+
+ munmap( addr, len );
+ }
+ }
+
+ return ret;
+}
+
+
+DirectResult
+SH7722_JPEG_Close( SH7722_JPEG_context *context )
+{
+ jpeg_destroy_decompress( &context->cinfo );
+
+ return DFB_OK;
+}
+
+DirectResult
+SH7722_JPEG_Encode( const char *filename,
+ const DFBRectangle *srcrect,
+ DFBSurfacePixelFormat srcformat,
+ unsigned long srcphys,
+ int srcpitch,
+ unsigned int width,
+ unsigned int height,
+ unsigned int tmpphys )
+{
+ DFBRectangle _rect;
+
+ if (!data.ref_count)
+ return DR_DEAD;
+
+ switch (srcformat) {
+ case DSPF_NV12:
+ case DSPF_NV16:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_RGB24:
+ break;
+
+ default:
+ return DR_UNSUPPORTED;
+ }
+
+ if (!srcrect) {
+ _rect.x = 0;
+ _rect.y = 0;
+ _rect.w = width;
+ _rect.h = height;
+
+ srcrect = &_rect;
+ }
+
+ return EncodeHW( &data, filename, srcrect, srcformat, srcphys, srcpitch, width, height, tmpphys );
+}
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeglib.h b/Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeglib.h
new file mode 100755
index 0000000..506a422
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeglib.h
@@ -0,0 +1,47 @@
+#ifndef __SH7722__SH7722_JPEGLIB_H__
+#define __SH7722__SH7722_JPEGLIB_H__
+
+#include <jpeglib.h>
+
+typedef struct {
+ DirectStream *stream;
+
+ int width;
+ int height;
+ bool mode420;
+ bool mode444;
+
+ struct jpeg_decompress_struct cinfo;
+} SH7722_JPEG_context;
+
+
+DirectResult SH7722_JPEG_Initialize( void );
+
+DirectResult SH7722_JPEG_Shutdown( void );
+
+DirectResult SH7722_JPEG_Open ( DirectStream *stream,
+ SH7722_JPEG_context *context );
+
+DirectResult SH7722_JPEG_Decode( SH7722_JPEG_context *context,
+ const DFBRectangle *rect,
+ const DFBRegion *clip,
+ DFBSurfacePixelFormat format,
+ unsigned long phys,
+ void *addr,
+ int pitch,
+ unsigned int width,
+ unsigned int height );
+
+DirectResult SH7722_JPEG_Close ( SH7722_JPEG_context *context );
+
+DirectResult SH7722_JPEG_Encode( const char *filename,
+ const DFBRectangle *srcrect,
+ DFBSurfacePixelFormat srcformat,
+ unsigned long srcphys,
+ int srcpitch,
+ unsigned int width,
+ unsigned int height,
+ unsigned int tmpphys );
+
+
+#endif
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_jpegtool.c b/Source/DirectFB/gfxdrivers/sh772x/sh7722_jpegtool.c
new file mode 100755
index 0000000..5fd0fad
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_jpegtool.c
@@ -0,0 +1,142 @@
+#ifdef SH7722_DEBUG_JPEG
+#define DIRECT_ENABLE_DEBUG
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#ifdef STANDALONE
+#include "sh7722_jpeglib_standalone.h"
+#else
+#include <config.h>
+
+#include <direct/debug.h>
+#include <direct/direct.h>
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/stream.h>
+#include <direct/util.h>
+
+#include <directfb.h>
+#endif
+
+#include "sh7722_jpeglib.h"
+
+
+void
+write_ppm( const char *filename,
+ unsigned long phys,
+ int pitch,
+ unsigned int width,
+ unsigned int height )
+{
+ int i;
+ int fd;
+ int size;
+ void *mem;
+ FILE *file;
+
+ size = direct_page_align( pitch * height );
+
+ fd = open( "/dev/mem", O_RDWR );
+ if (fd < 0) {
+ D_PERROR( "SH7722/JPEG: Could not open /dev/mem!\n" );
+ return;
+ }
+
+ mem = mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, phys );
+ if (mem == MAP_FAILED) {
+ D_PERROR( "SH7722/JPEG: Could not map /dev/mem at 0x%08lx (length %d)!\n", phys, size );
+ close( fd );
+ return;
+ }
+
+ close( fd );
+
+ file = fopen( filename, "wb" );
+ if (!file) {
+ D_PERROR( "SH7722/JPEG: Could not open '%s' for writing!\n", filename );
+ munmap( mem, size );
+ return;
+ }
+
+ fprintf( file, "P6\n%d %d\n255\n", width, height );
+
+ for (i=0; i<height; i++) {
+ fwrite( mem, 3, width, file );
+
+ mem += pitch;
+ }
+
+ fclose( file );
+
+ munmap( mem, size );
+}
+
+
+int
+main( int argc, char *argv[] )
+{
+ DirectResult ret;
+ SH7722_JPEG_context info;
+ DFBSurfacePixelFormat format;
+ int pitch;
+ DirectStream *stream = NULL;
+
+ if (argc != 2) {
+ fprintf( stderr, "Usage: %s <filename>\n", argv[0] );
+ return -1;
+ }
+
+#ifndef STANDALONE
+ direct_initialize();
+
+ direct_config->debug = true;
+#endif
+
+ ret = SH7722_JPEG_Initialize();
+ if (ret)
+ return ret;
+
+ ret = direct_stream_create( argv[1], &stream );
+ if (ret)
+ goto out;
+
+ ret = SH7722_JPEG_Open( stream, &info );
+ if (ret)
+ goto out;
+
+ D_INFO( "SH7722/JPEGTool: Opened %dx%d image (4:%s)\n", info.width, info.height,
+ info.mode420 ? "2:0" : info.mode444 ? "4:4" : "2:2?" );
+
+ format = DSPF_RGB24;// info.mode444 ? DSPF_NV16 : DSPF_NV12;
+ pitch = (DFB_BYTES_PER_LINE( format, info.width ) + 31) & ~31;
+
+ ret = SH7722_JPEG_Decode( &info, NULL, NULL, format, 0x0f800000, NULL, pitch, info.width, info.height );
+ if (ret)
+ goto out;
+
+
+// Use RGB24 format for this
+// write_ppm( "test.ppm", 0x0f800000, pitch, info.width, info.height );
+
+ ret = SH7722_JPEG_Encode( "test.jpg", NULL, format, 0x0f800000, pitch, info.width, info.height, 0 );
+ if (ret)
+ goto out;
+
+
+out:
+ if (stream)
+ direct_stream_destroy( stream );
+
+ SH7722_JPEG_Shutdown();
+
+ return ret;
+}
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_layer.c b/Source/DirectFB/gfxdrivers/sh772x/sh7722_layer.c
new file mode 100755
index 0000000..8628ee8
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_layer.c
@@ -0,0 +1,529 @@
+#ifdef SH7722_DEBUG_LAYER
+#define DIRECT_ENABLE_DEBUG
+#endif
+
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <sys/mman.h>
+
+#include <asm/types.h>
+
+#include <directfb.h>
+
+#include <fusion/fusion.h>
+#include <fusion/shmalloc.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+#include <core/layers.h>
+#include <core/palette.h>
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+#include <core/system.h>
+
+#include <gfx/convert.h>
+
+#include <misc/conf.h>
+
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+
+#include "sh7722.h"
+#include "sh7722_types.h"
+#include "sh7722_layer.h"
+#include "sh7722_lcd.h"
+
+
+D_DEBUG_DOMAIN( SH7722_Layer, "SH7722/Layer", "Renesas SH7722 Layers" );
+
+/**********************************************************************************************************************/
+
+static int
+sh7722LayerDataSize( void )
+{
+ return sizeof(SH7722LayerData);
+}
+
+static int
+sh7722RegionDataSize( void )
+{
+ return sizeof(SH7722RegionData);
+}
+
+static DFBResult
+sh7722InitLayer( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ DFBDisplayLayerDescription *description,
+ DFBDisplayLayerConfig *config,
+ DFBColorAdjustment *adjustment )
+{
+ SH7722DriverData *sdrv = driver_data;
+ SH7722DeviceData *sdev = sdrv->dev;
+ SH7722LayerData *data = layer_data;
+
+ D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
+
+ /* initialize layer data */
+ data->layer = SH7722_LAYER_INPUT1 + sdrv->num_inputs++;
+
+ /* set capabilities and type */
+ description->caps = DLCAPS_SURFACE | DLCAPS_ALPHACHANNEL | DLCAPS_OPACITY |
+ DLCAPS_SCREEN_POSITION | DLCAPS_SRC_COLORKEY;
+
+ description->type = DLTF_STILL_PICTURE | DLTF_GRAPHICS | DLTF_VIDEO;
+
+ /* set name */
+ snprintf( description->name, DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "Input %d", sdrv->num_inputs );
+
+ /* fill out the default configuration */
+ config->flags = DLCONF_WIDTH | DLCONF_HEIGHT |
+ DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | DLCONF_OPTIONS;
+ config->width = sdev->lcd_width;;
+ config->height = sdev->lcd_height;
+ config->pixelformat = DSPF_RGB16;
+ config->buffermode = DLBM_FRONTONLY;
+ config->options = DLOP_ALPHACHANNEL;
+
+ return DFB_OK;
+}
+
+static DFBResult
+sh7722TestRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags *failed )
+{
+ SH7722DriverData *sdrv = driver_data;
+ SH7722DeviceData *sdev = sdrv->dev;
+ SH7722LayerData *slay = layer_data;
+ CoreLayerRegionConfigFlags fail = 0;
+
+ D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
+
+ if (config->options & ~SH7722_LAYER_SUPPORTED_OPTIONS)
+ fail |= CLRCF_OPTIONS;
+
+ switch (config->format) {
+ case DSPF_LUT8:
+ /* Indexed only for third input */
+ if (slay->layer != SH7722_LAYER_INPUT3)
+ fail |= CLRCF_FORMAT;
+ break;
+
+ case DSPF_ARGB:
+ case DSPF_RGB32:
+ case DSPF_RGB24:
+ case DSPF_RGB16:
+ break;
+
+ case DSPF_NV12:
+ case DSPF_NV16:
+ /* YUV only for first input */
+ if (slay->layer != SH7722_LAYER_INPUT1)
+ fail |= CLRCF_FORMAT;
+ break;
+
+ default:
+ fail |= CLRCF_FORMAT;
+ }
+
+ if (config->width < 32 || config->width > sdev->lcd_width)
+ fail |= CLRCF_WIDTH;
+
+ if (config->height < 32 || config->height > sdev->lcd_height)
+ fail |= CLRCF_HEIGHT;
+
+ if (config->dest.x >= sdev->lcd_width || config->dest.y >= sdev->lcd_height)
+ fail |= CLRCF_DEST;
+
+ if (config->dest.x < 0) {
+ config->dest.x = 0;
+// FIXME
+// fail |= CLRCF_DEST;
+ }
+
+ if (config->dest.y < 0) {
+ config->dest.y = 0;
+// FIXME
+// fail |= CLRCF_DEST;
+ }
+
+ if (failed)
+ *failed = fail;
+
+ if (fail)
+ return DFB_UNSUPPORTED;
+
+ return DFB_OK;
+}
+
+static DFBResult
+sh7722AddRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config )
+{
+ SH7722RegionData *sreg = region_data;
+
+ D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
+
+ sreg->config = *config;
+
+ D_MAGIC_SET( sreg, SH7722RegionData );
+
+ return DFB_OK;
+}
+
+static DFBResult
+sh7722SetRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags updated,
+ CoreSurface *surface,
+ CorePalette *palette,
+ CoreSurfaceBufferLock *lock )
+{
+ int i, n;
+ SH7722DriverData *sdrv = driver_data;
+ SH7722DeviceData *sdev = sdrv->dev;
+ SH7722RegionData *sreg = region_data;
+ SH7722LayerData *slay = layer_data;
+
+ D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( sreg, SH7722RegionData );
+
+ n = slay->layer - SH7722_LAYER_INPUT1;
+
+ D_ASSERT( n >= 0 );
+ D_ASSERT( n <= 2 );
+
+ fusion_skirmish_prevail( &sdev->beu_lock );
+
+ /* Wait for idle BEU. */
+ BEU_Wait( sdrv, sdev );
+
+ /* Update position? */
+ if (updated & CLRCF_DEST) {
+ /* Set horizontal and vertical offset. */
+ SH7722_SETREG32( sdrv, BLOCR(n), (config->dest.y << 16) | config->dest.x );
+ }
+
+ /* Update size? */
+ if (updated & (CLRCF_WIDTH | CLRCF_HEIGHT)) {
+ int cw = config->width;
+ int ch = config->height;
+
+ if (config->dest.x + cw > sdev->lcd_width)
+ cw = sdev->lcd_width - config->dest.x;
+
+ if (config->dest.y + ch > sdev->lcd_height)
+ ch = sdev->lcd_height - config->dest.y;
+
+ /* Set width and height. */
+ SH7722_SETREG32( sdrv, BSSZR(n), (ch << 16) | cw );
+ SH7722_SETREG32( sdrv, BTPSR, (ch << 16) | cw );
+ }
+
+ /* Update surface? */
+ if (updated & CLRCF_SURFACE) {
+ CoreSurfaceBuffer *buffer = lock->buffer;
+
+ /* Set buffer pitch. */
+ SH7722_SETREG32( sdrv, BSMWR(n), lock->pitch );
+
+ /* Set buffer offset (Y plane or RGB packed). */
+ SH7722_SETREG32( sdrv, BSAYR(n), lock->phys );
+
+ /* Set buffer offset (UV plane). */
+ if (DFB_PLANAR_PIXELFORMAT(buffer->format)) {
+ D_ASSUME( buffer->format == DSPF_NV12 || buffer->format == DSPF_NV16 );
+
+ SH7722_SETREG32( sdrv, BSACR(n), lock->phys + lock->pitch * surface->config.size.h );
+ }
+
+ sreg->surface = surface;
+ }
+
+ /* Update format? */
+ if (updated & CLRCF_FORMAT) {
+ unsigned long tBSIFR = 0;
+ unsigned long tBSWPR = BSWPR_MODSEL_EACH | (SH7722_GETREG32( sdrv, BSWPR ) & ~(7 << (n*8)));
+
+ /* Set pixel format. */
+ switch (config->format) {
+ case DSPF_NV12:
+ tBSIFR |= CHRR_YCBCR_420 | BSIFR1_IN1TE_RGBYUV;
+ break;
+
+ case DSPF_NV16:
+ tBSIFR |= CHRR_YCBCR_422 | BSIFR1_IN1TE_RGBYUV;
+ break;
+
+ case DSPF_ARGB:
+ tBSIFR |= RPKF_ARGB;
+ break;
+
+ case DSPF_RGB32:
+ tBSIFR |= RPKF_RGB32;
+ break;
+
+ case DSPF_RGB24:
+ tBSIFR |= RPKF_RGB24;
+ break;
+
+ case DSPF_RGB16:
+ tBSIFR |= RPKF_RGB16;
+ break;
+
+ case DSPF_LUT8:
+ tBSIFR |= BSIFR3_MOD0_OSD | BSIFR3_MOD1_LUT;
+ break;
+
+ default:
+ break;
+ }
+
+#if 0
+ /* Set swapping. */
+ switch (config->format) {
+ case DSPF_LUT8:
+ case DSPF_NV12:
+ case DSPF_NV16:
+ tBSWPR |= (BSWPR_INPUT_BYTESWAP |
+ BSWPR_INPUT_WORDSWAP |
+ BSWPR_INPUT_LONGSWAP) << (n*8);
+ break;
+
+ case DSPF_RGB16:
+ tBSWPR |= (BSWPR_INPUT_WORDSWAP |
+ BSWPR_INPUT_LONGSWAP) << (n*8);
+ break;
+
+ case DSPF_ARGB:
+ case DSPF_RGB32:
+ case DSPF_RGB24:
+ tBSWPR |= (BSWPR_INPUT_LONGSWAP) << (n*8);
+ break;
+
+ default:
+ break;
+ }
+#endif
+
+ SH7722_SETREG32( sdrv, BSIFR(n), tBSIFR );
+ SH7722_SETREG32( sdrv, BSWPR, tBSWPR );
+ }
+
+ /* Update options or opacity? */
+ if (updated & (CLRCF_OPTIONS | CLRCF_OPACITY | CLRCF_FORMAT)) {
+ unsigned long tBBLCR0 = BBLCR0_LAY_123;
+
+ /* Set opacity value. */
+ tBBLCR0 &= ~(0xff << (n*8));
+ tBBLCR0 |= ((config->options & CLRCF_OPACITY) ? config->opacity : 0xff) << (n*8);
+
+ /* Enable/disable alpha channel. */
+ if ((config->options & DLOP_ALPHACHANNEL) && DFB_PIXELFORMAT_HAS_ALPHA(config->format))
+ tBBLCR0 |= BBLCR0_AMUX_BLENDPIXEL(n);
+ else
+ tBBLCR0 &= ~BBLCR0_AMUX_BLENDPIXEL(n);
+
+ SH7722_SETREG32( sdrv, BBLCR0, tBBLCR0 );
+ }
+
+ /* Update CLUT? */
+ if (updated & CLRCF_PALETTE && palette) {
+ const DFBColor *entries = palette->entries;
+
+ for (i=0; i<256; i++) {
+ SH7722_SETREG32( sdrv, BCLUT(i), PIXEL_ARGB( entries[i].a,
+ entries[i].r,
+ entries[i].g,
+ entries[i].b ) );
+ }
+ }
+
+
+ /* Enable or disable input. */
+ if ((config->options & DLOP_OPACITY) && !config->opacity)
+ sdev->input_mask &= ~(1 << n);
+ else
+ sdev->input_mask |= (1 << n);
+
+ /* Choose parent input. */
+ if (sdev->input_mask) {
+ unsigned long tBBLCR1 = SH7722_GETREG32( sdrv, BBLCR1 ) & ~BBLCR1_PWD_INPUT_MASK;
+
+ if (sdev->input_mask & 4)
+ tBBLCR1 |= BBLCR1_PWD_INPUT3;
+ else if (sdev->input_mask & 2)
+ tBBLCR1 |= BBLCR1_PWD_INPUT2;
+ else
+ tBBLCR1 |= BBLCR1_PWD_INPUT1;
+
+ SH7722_SETREG32( sdrv, BBLCR1, tBBLCR1 );
+ }
+
+ fusion_skirmish_dismiss( &sdev->beu_lock );
+
+ sreg->config = *config;
+
+ return DFB_OK;
+}
+
+static DFBResult
+sh7722RemoveRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data )
+{
+ int n;
+ SH7722DriverData *sdrv = driver_data;
+ SH7722DeviceData *sdev = sdrv->dev;
+ SH7722LayerData *slay = layer_data;
+
+ D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
+
+ D_ASSERT( sdev != NULL );
+ D_ASSERT( slay != NULL );
+
+ n = slay->layer - SH7722_LAYER_INPUT1;
+
+ D_ASSERT( n >= 0 );
+ D_ASSERT( n <= 2 );
+
+ fusion_skirmish_prevail( &sdev->beu_lock );
+
+ /* Wait for idle BEU. */
+ BEU_Wait( sdrv, sdev );
+
+ sdev->input_mask &= ~(1 << n);
+
+ /* Choose parent input. */
+ if (sdev->input_mask) {
+ unsigned long tBBLCR1 = SH7722_GETREG32( sdrv, BBLCR1 ) & ~BBLCR1_PWD_INPUT_MASK;
+
+ if (sdev->input_mask & 4)
+ tBBLCR1 |= BBLCR1_PWD_INPUT3;
+ else if (sdev->input_mask & 2)
+ tBBLCR1 |= BBLCR1_PWD_INPUT2;
+ else
+ tBBLCR1 |= BBLCR1_PWD_INPUT1;
+
+ SH7722_SETREG32( sdrv, BBLCR1, tBBLCR1 );
+ }
+
+ /* Start operation! */
+ BEU_Start( sdrv, sdev );
+
+ fusion_skirmish_dismiss( &sdev->beu_lock );
+
+ return DFB_OK;
+}
+
+static DFBResult
+sh7722FlipRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreSurface *surface,
+ DFBSurfaceFlipFlags flags,
+ CoreSurfaceBufferLock *lock )
+{
+ int n;
+ CoreSurfaceBuffer *buffer;
+ SH7722DriverData *sdrv = driver_data;
+ SH7722DeviceData *sdev = sdrv->dev;
+ SH7722LayerData *slay = layer_data;
+
+ D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
+
+ D_ASSERT( surface != NULL );
+ D_ASSERT( sdrv != NULL );
+ D_ASSERT( sdev != NULL );
+ D_ASSERT( slay != NULL );
+
+ n = slay->layer - SH7722_LAYER_INPUT1;
+
+ D_ASSERT( n >= 0 );
+ D_ASSERT( n <= 2 );
+
+ buffer = lock->buffer;
+ D_ASSERT( buffer != NULL );
+
+ fusion_skirmish_prevail( &sdev->beu_lock );
+
+ /* Set buffer offset (Y plane or RGB packed). */
+ SH7722_SETREG32( sdrv, BSAYR(n), lock->phys );
+
+ /* Set buffer offset (UV plane). */
+ if (DFB_PLANAR_PIXELFORMAT(buffer->format)) {
+ D_ASSUME( buffer->format == DSPF_NV12 || buffer->format == DSPF_NV16 );
+
+ SH7722_SETREG32( sdrv, BSACR(n), lock->phys + lock->pitch * surface->config.size.h );
+ }
+
+ /* Start operation! */
+ BEU_Start( sdrv, sdev );
+
+ fusion_skirmish_dismiss( &sdev->beu_lock );
+
+ /* Wait for idle BEU? */
+ if (flags & DSFLIP_WAIT)
+ BEU_Wait( sdrv, sdev );
+
+ dfb_surface_flip( surface, false );
+
+ return DFB_OK;
+}
+
+static DFBResult
+sh7722UpdateRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreSurface *surface,
+ const DFBRegion *update,
+ CoreSurfaceBufferLock *lock )
+{
+ SH7722DriverData *sdrv = driver_data;
+ SH7722DeviceData *sdev = sdrv->dev;
+
+ D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
+
+ D_ASSERT( surface != NULL );
+ D_ASSERT( sdrv != NULL );
+ D_ASSERT( sdev != NULL );
+
+ /* Start operation! */
+ BEU_Start( sdrv, sdev );
+
+ if (!(surface->config.caps & DSCAPS_FLIPPING))
+ BEU_Wait( sdrv, sdev );
+
+ return DFB_OK;
+}
+
+DisplayLayerFuncs sh7722LayerFuncs = {
+ .LayerDataSize = sh7722LayerDataSize,
+ .RegionDataSize = sh7722RegionDataSize,
+ .InitLayer = sh7722InitLayer,
+
+ .TestRegion = sh7722TestRegion,
+ .AddRegion = sh7722AddRegion,
+ .SetRegion = sh7722SetRegion,
+ .RemoveRegion = sh7722RemoveRegion,
+ .FlipRegion = sh7722FlipRegion,
+ .UpdateRegion = sh7722UpdateRegion,
+};
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_layer.h b/Source/DirectFB/gfxdrivers/sh772x/sh7722_layer.h
new file mode 100755
index 0000000..b704214
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_layer.h
@@ -0,0 +1,11 @@
+#ifndef __SH7722__LAYER_H__
+#define __SH7722__LAYER_H__
+
+#include "sh7722_types.h"
+
+#define SH7722_LAYER_SUPPORTED_OPTIONS (DLOP_ALPHACHANNEL | DLOP_OPACITY | DLOP_SRC_COLORKEY)
+
+extern DisplayLayerFuncs sh7722LayerFuncs;
+
+#endif
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_lcd.c b/Source/DirectFB/gfxdrivers/sh772x/sh7722_lcd.c
new file mode 100755
index 0000000..47df333
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_lcd.c
@@ -0,0 +1,172 @@
+#ifdef SH7722_DEBUG_LCD
+#define DIRECT_ENABLE_DEBUG
+#endif
+
+
+#include <config.h>
+
+#include <asm/types.h>
+
+#include <direct/debug.h>
+
+#include <misc/conf.h>
+
+#include "sh7722.h"
+
+
+D_DEBUG_DOMAIN( SH7722_LCD, "SH7722/LCD", "Renesas SH7722 LCD" );
+
+/**********************************************************************************************************************/
+
+void
+sh7722_lcd_setup( void *drv,
+ int width,
+ int height,
+ ulong phys,
+ int pitch,
+ DFBSurfacePixelFormat format,
+ bool swap )
+{
+ u32 MLDDFR = 0;
+ u32 LDDDSR = 0;
+ u32 reg;
+
+ D_DEBUG_AT( SH7722_LCD, "%s( %dx%d @%lu:%d )\n", __FUNCTION__, width, height, phys, pitch );
+
+ D_ASSERT( width > 7 );
+ D_ASSERT( height > 0 );
+
+ D_ASSERT( (phys & 7) == 0 );
+
+ D_ASSERT( pitch > 0 );
+ D_ASSERT( pitch < 0x10000 );
+ D_ASSERT( (pitch & 3) == 0 );
+
+ /* Choose input format. */
+ switch (format) {
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ MLDDFR = 0;
+ break;
+
+ case DSPF_RGB16:
+ MLDDFR = 3;
+ break;
+
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ MLDDFR = 8;
+ break;
+
+ case DSPF_RGB24:
+ MLDDFR = 11;
+ break;
+
+ case DSPF_NV12:
+ MLDDFR = 0x10000;
+ break;
+
+ case DSPF_NV16:
+ MLDDFR = 0x10100;
+ break;
+
+ default:
+ D_BUG( "invalid format" );
+ return;
+ }
+
+ /* Setup swapping. */
+ switch (format) {
+ case DSPF_NV12: /* 1 byte */
+ case DSPF_NV16:
+ case DSPF_RGB24:
+ LDDDSR = 7;
+ break;
+
+ case DSPF_RGB16: /* 2 byte */
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ LDDDSR = 6;
+ break;
+
+ case DSPF_RGB32: /* 4 byte */
+ case DSPF_ARGB:
+ LDDDSR = 4;
+ break;
+
+ default:
+ D_BUG( "invalid format" );
+ return;
+ }
+
+ /* software reset of the LCD device */
+ reg = SH7722_GETREG32( drv, LCDC_LDCNT2R );
+ SH7722_SETREG32( drv, LCDC_LDCNT2R, reg | 0x100 );
+ while( SH7722_GETREG32( drv, LCDC_LDCNT2R ) & 0x100 );
+
+ /* stop the LCD while configuring */
+ SH7722_SETREG32( drv, LCDC_LDCNT2R, 0 );
+ SH7722_SETREG32( drv, LCDC_LDDCKSTPR, 1 );
+
+ SH7722_SETREG32( drv, LCDC_MLDDCKPAT1R, 0x05555555 );
+ SH7722_SETREG32( drv, LCDC_MLDDCKPAT2R, 0x55555555 );
+ SH7722_SETREG32( drv, LCDC_LDDCKR, 0x0000003c );
+ SH7722_SETREG32( drv, LCDC_MLDMT2R, 0x00000000 );
+ SH7722_SETREG32( drv, LCDC_MLDMT3R, 0x00000000 );
+ SH7722_SETREG32( drv, LCDC_MLDDFR, MLDDFR );
+ SH7722_SETREG32( drv, LCDC_MLDSM1R, 0x00000000 );
+ SH7722_SETREG32( drv, LCDC_MLDSM2R, 0x00000000 );
+ SH7722_SETREG32( drv, LCDC_MLDSA1R, phys );
+ SH7722_SETREG32( drv, LCDC_MLDSA2R, DFB_PLANAR_PIXELFORMAT( format ) ? (phys + pitch * height) : 0 );
+ SH7722_SETREG32( drv, LCDC_MLDMLSR, pitch );
+ SH7722_SETREG32( drv, LCDC_MLDWBCNTR, 0x00000000 );
+ SH7722_SETREG32( drv, LCDC_MLDWBAR, 0x00000000 );
+#if 0
+ SH7722_SETREG32( drv, LCDC_MLDMT1R, 0x18000006 );
+ SH7722_SETREG32( drv, LCDC_MLDHCNR, ((width / 8) << 16) | (1056 / 8) );
+ SH7722_SETREG32( drv, LCDC_MLDHSYNR, ((128 / 8) << 16) | (840 / 8) );
+ SH7722_SETREG32( drv, LCDC_MLDVLNR, (height << 16) | 525 );
+ SH7722_SETREG32( drv, LCDC_MLDVSYNR, (2 << 16) | 490 );
+ SH7722_SETREG32( drv, LCDC_MLDPMR, 0xf6000f00 );
+#elif 0
+ SH7722_SETREG32( drv, LCDC_MLDMT1R, 0x1c00000a );
+ SH7722_SETREG32( drv, LCDC_MLDHCNR, 0x00500060);
+ SH7722_SETREG32( drv, LCDC_MLDHSYNR, 0x00010052);
+ SH7722_SETREG32( drv, LCDC_MLDVLNR, 0x01e00200);
+ SH7722_SETREG32( drv, LCDC_MLDVSYNR, 0x000301f0);
+ SH7722_SETREG32( drv, LCDC_MLDPMR, 0x00000000 ); //igel
+#elif defined(SH7722_ALGO_PANEL)
+ SH7722_SETREG32( drv, LCDC_MLDMT1R, 0x1c00000a );
+ SH7722_SETREG32( drv, LCDC_MLDHCNR, 0x00500060);
+ SH7722_SETREG32( drv, LCDC_MLDHSYNR, 0x00010052);
+ SH7722_SETREG32( drv, LCDC_MLDVLNR, 0x01e0020e);
+ SH7722_SETREG32( drv, LCDC_MLDVSYNR, 0x000301f0);
+ SH7722_SETREG32( drv, LCDC_MLDPMR, 0x00000000 ); //igel
+#elif defined(ALGO_AP325)
+ SH7722_SETREG32( drv, LCDC_MLDMT1R, 0x1800000a );
+ SH7722_SETREG32( drv, LCDC_MLDHCNR, ((width / 8) << 16) | (1000 / 8) );
+ SH7722_SETREG32( drv, LCDC_MLDHSYNR, ((8 / 8) << 16) | (960 / 8) );
+ SH7722_SETREG32( drv, LCDC_MLDVLNR, (height << 16) | 624 );
+ SH7722_SETREG32( drv, LCDC_MLDVSYNR, (1 << 16) | 560 );
+ SH7722_SETREG32( drv, LCDC_MLDPMR, 0x00000000 );
+#endif
+ SH7722_SETREG32( drv, LCDC_LDINTR, 0x00000000 );
+ SH7722_SETREG32( drv, LCDC_LDRCNTR, 0x00000000 );
+ SH7722_SETREG32( drv, LCDC_LDDDSR, swap ? LDDDSR : 0 );
+ SH7722_SETREG32( drv, LCDC_LDRCR, 0x00000000 );
+ SH7722_SETREG32( drv, LCDC_LDPALCR, 0x00000000 );
+
+ /* enable and start displaying */
+ SH7722_SETREG32( drv, LCDC_LDCNT1R, 0x00000001 );
+ SH7722_SETREG32( drv, LCDC_LDCNT2R, 0x00000003 );
+ SH7722_SETREG32( drv, LCDC_LDDCKSTPR, 0 );
+ while( SH7722_GETREG32( drv, LCDC_LDDCKSTPR ) & 0x10000 );
+
+ /* finally, turn the display on */
+ {
+ SH7722DriverData *sdrv = drv;
+ if (ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_POWER_DISPLAY ) < 0)
+ D_PERROR( "SH772xGFX_IOCTL_POWER_DISPLAY\n" );
+ }
+}
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_lcd.h b/Source/DirectFB/gfxdrivers/sh772x/sh7722_lcd.h
new file mode 100755
index 0000000..4e0a12d
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_lcd.h
@@ -0,0 +1,17 @@
+#ifndef __SH7722__LCD_H__
+#define __SH7722__LCD_H__
+
+#include "sh7722_types.h"
+
+
+void sh7722_lcd_setup( void *drv,
+ int width,
+ int height,
+ ulong phys,
+ int pitch,
+ DFBSurfacePixelFormat format,
+ bool swap );
+
+
+#endif
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.c b/Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.c
new file mode 100755
index 0000000..d15871d
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.c
@@ -0,0 +1,412 @@
+#ifdef SH7722_DEBUG_LAYER
+#define DIRECT_ENABLE_DEBUG
+#endif
+
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <sys/mman.h>
+
+#include <asm/types.h>
+
+#include <directfb.h>
+
+#include <fusion/fusion.h>
+#include <fusion/shmalloc.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+#include <core/layers.h>
+#include <core/palette.h>
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+#include <core/system.h>
+
+#include <gfx/convert.h>
+
+#include <misc/conf.h>
+
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+
+#include "sh7722.h"
+#include "sh7722_types.h"
+#include "sh7722_multi.h"
+
+
+D_DEBUG_DOMAIN( SH7722_Layer, "SH7722/Layer", "Renesas SH7722 Layers" );
+
+/**********************************************************************************************************************/
+
+static int
+sh7722LayerDataSize( void )
+{
+ return sizeof(SH7722MultiLayerData);
+}
+
+static int
+sh7722RegionDataSize( void )
+{
+ return sizeof(SH7722MultiRegionData);
+}
+
+static DFBResult
+sh7722InitLayer( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ DFBDisplayLayerDescription *description,
+ DFBDisplayLayerConfig *config,
+ DFBColorAdjustment *adjustment )
+{
+ SH7722DriverData *sdrv = driver_data;
+ SH7722DeviceData *sdev = sdrv->dev;
+ D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
+
+ /* set capabilities and type */
+ description->caps = DLCAPS_SURFACE | DLCAPS_SCREEN_POSITION | DLCAPS_SRC_COLORKEY | DLCAPS_WINDOWS;
+ description->type = DLTF_GRAPHICS;
+ description->regions = 4;
+
+ /* set name */
+ snprintf( description->name, DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "Multi Window" );
+
+ /* fill out the default configuration */
+ config->flags = DLCONF_WIDTH | DLCONF_HEIGHT |
+ DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | DLCONF_OPTIONS;
+ config->width = sdev->lcd_width;
+ config->height = sdev->lcd_height;
+ config->pixelformat = DSPF_NV16;
+ config->buffermode = DLBM_FRONTONLY;
+ config->options = DLOP_NONE;
+
+ return DFB_OK;
+}
+
+static DFBResult
+sh7722TestRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags *failed )
+{
+ CoreLayerRegionConfigFlags fail = 0;
+
+ D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
+
+ if (config->options & ~SH7722_MULTI_SUPPORTED_OPTIONS)
+ fail |= CLRCF_OPTIONS;
+
+ switch (config->format) {
+ case DSPF_ARGB:
+ case DSPF_RGB32:
+ case DSPF_RGB24:
+ case DSPF_RGB16:
+ break;
+
+#if FIXME_MAKE_CONFIGURABLE_
+ case DSPF_NV12:
+ case DSPF_NV16:
+ break;
+#endif
+
+ default:
+ fail |= CLRCF_FORMAT;
+ }
+
+ if (config->width < 32 || config->width > 1280)
+ fail |= CLRCF_WIDTH;
+
+ if (config->height < 32 || config->height > 1024)
+ fail |= CLRCF_HEIGHT;
+
+
+ if (failed)
+ *failed = fail;
+
+ if (fail)
+ return DFB_UNSUPPORTED;
+
+ return DFB_OK;
+}
+
+static DFBResult
+sh7722AddRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config )
+{
+ int n;
+ SH7722MultiRegionData *sreg = region_data;
+ SH7722MultiLayerData *slay = layer_data;
+
+ D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
+
+ if (slay->added == 0xF)
+ return DFB_LIMITEXCEEDED;
+
+ for (n=0; n<4; n++)
+ if (! (slay->added & (1 << n)))
+ break;
+
+ D_ASSERT( n < 4 );
+
+ sreg->config = *config;
+
+
+ slay->added |= 1 << n;
+
+ D_MAGIC_SET( sreg, SH7722MultiRegionData );
+
+ return DFB_OK;
+}
+
+static DFBResult
+sh7722SetRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags updated,
+ CoreSurface *surface,
+ CorePalette *palette,
+ CoreSurfaceBufferLock *lock )
+{
+ int n;
+ SH7722DriverData *sdrv = driver_data;
+ SH7722DeviceData *sdev = sdrv->dev;
+ SH7722MultiRegionData *sreg = region_data;
+
+ D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( sreg, SH7722MultiRegionData );
+
+ fusion_skirmish_prevail( &sdev->beu_lock );
+
+ /* Wait for idle BEU. */
+ BEU_Wait( sdrv, sdev );
+
+ n = sreg->index;
+
+ D_ASSERT( n >= 0 );
+ D_ASSERT( n <= 3 );
+
+ /* Update position? */
+ if (updated & CLRCF_DEST) {
+ /* Set horizontal and vertical offset. */
+ SH7722_SETREG32( sdrv, BMLOCR(n), (config->dest.y << 16) | config->dest.x );
+ }
+
+ /* Update size? */
+ if (updated & (CLRCF_WIDTH | CLRCF_HEIGHT)) {
+ /* Set width and height. */
+ SH7722_SETREG32( sdrv, BMSSZR(n), (config->height << 16) | config->width );
+ }
+
+ /* Update surface? */
+ if (updated & CLRCF_SURFACE) {
+ CoreSurfaceBuffer *buffer;
+
+ D_ASSERT( surface != NULL );
+
+ buffer = lock->buffer;
+
+ D_ASSERT( buffer != NULL );
+
+ /* Set buffer pitch. */
+ SH7722_SETREG32( sdrv, BMSMWR(n), lock->pitch );
+
+ /* Set buffer offset (Y plane or RGB packed). */
+ SH7722_SETREG32( sdrv, BMSAYR(n), lock->phys );
+
+ /* Set buffer offset (UV plane). */
+ if (DFB_PLANAR_PIXELFORMAT(buffer->format)) {
+ D_ASSUME( buffer->format == DSPF_NV12 || buffer->format == DSPF_NV16 );
+
+ SH7722_SETREG32( sdrv, BMSACR(n), lock->phys + lock->pitch * surface->config.size.h );
+ }
+ }
+
+ /* Update format? */
+ if (updated & CLRCF_FORMAT) {
+ unsigned long tBMSIFR = 0;
+
+ /* Set pixel format. */
+ switch (config->format) {
+ case DSPF_NV12:
+ tBMSIFR |= CHRR_YCBCR_420;
+ break;
+
+ case DSPF_NV16:
+ tBMSIFR |= CHRR_YCBCR_422;
+ break;
+
+ case DSPF_ARGB:
+ tBMSIFR |= RPKF_ARGB;
+ break;
+
+ case DSPF_RGB32:
+ tBMSIFR |= RPKF_RGB32;
+ break;
+
+ case DSPF_RGB24:
+ tBMSIFR |= RPKF_RGB24;
+ break;
+
+ case DSPF_RGB16:
+ tBMSIFR |= RPKF_RGB16;
+ break;
+
+ default:
+ break;
+ }
+
+ /* FIXME: all regions need to have the same format! */
+ SH7722_SETREG32( sdrv, BMSIFR, tBMSIFR );
+ }
+
+ SH7722_SETREG32( sdrv, BMWCR0, SH7722_GETREG32( sdrv, BMWCR0 ) | (1 << n) );
+
+ fusion_skirmish_dismiss( &sdev->beu_lock );
+
+ return DFB_OK;
+}
+
+static DFBResult
+sh7722RemoveRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data )
+{
+ int n;
+ SH7722DriverData *sdrv = driver_data;
+ SH7722DeviceData *sdev = sdrv->dev;
+ SH7722MultiRegionData *sreg = region_data;
+
+ D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( sreg, SH7722MultiRegionData );
+
+ n = sreg->index;
+
+ D_ASSERT( n >= 0 );
+ D_ASSERT( n <= 3 );
+
+ fusion_skirmish_prevail( &sdev->beu_lock );
+
+ /* Wait for idle BEU. */
+ BEU_Wait( sdrv, sdev );
+
+ /* Disable multi window. */
+ SH7722_SETREG32( sdrv, BMWCR0, SH7722_GETREG32( sdrv, BMWCR0 ) & ~(1 << n) );
+
+ /* Start operation! */
+ BEU_Start( sdrv, sdev );
+
+ fusion_skirmish_dismiss( &sdev->beu_lock );
+
+ return DFB_OK;
+}
+
+static DFBResult
+sh7722FlipRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreSurface *surface,
+ DFBSurfaceFlipFlags flags,
+ CoreSurfaceBufferLock *lock )
+{
+ int n;
+ CoreSurfaceBuffer *buffer;
+ SH7722DriverData *sdrv = driver_data;
+ SH7722DeviceData *sdev = sdrv->dev;
+ SH7722MultiRegionData *sreg = region_data;
+
+ D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
+
+ D_ASSERT( surface != NULL );
+ D_ASSERT( sdrv != NULL );
+ D_ASSERT( sdev != NULL );
+ D_MAGIC_ASSERT( sreg, SH7722MultiRegionData );
+
+ n = sreg->index;
+
+ D_ASSERT( n >= 0 );
+ D_ASSERT( n <= 3 );
+
+ buffer = lock->buffer;
+ D_ASSERT( buffer != NULL );
+
+ fusion_skirmish_prevail( &sdev->beu_lock );
+
+ /* Wait for idle BEU. */
+ BEU_Wait( sdrv, sdev );
+
+ /* Set buffer pitch. */
+ SH7722_SETREG32( sdrv, BMSMWR(n), lock->pitch );
+
+ /* Set buffer offset (Y plane or RGB packed). */
+ SH7722_SETREG32( sdrv, BMSAYR(n), lock->phys );
+
+ /* Set buffer offset (UV plane). */
+ if (DFB_PLANAR_PIXELFORMAT(buffer->format)) {
+ D_ASSUME( buffer->format == DSPF_NV12 || buffer->format == DSPF_NV16 );
+
+ SH7722_SETREG32( sdrv, BMSACR(n), lock->phys + lock->pitch * surface->config.size.h );
+ }
+
+ /* Start operation! */
+ BEU_Start( sdrv, sdev );
+
+ fusion_skirmish_dismiss( &sdev->beu_lock );
+
+ /* Wait for idle BEU? */
+ if (flags & DSFLIP_WAIT)
+ BEU_Wait( sdrv, sdev );
+
+ dfb_surface_flip( surface, false );
+
+ return DFB_OK;
+}
+
+static DFBResult
+sh7722UpdateRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreSurface *surface,
+ const DFBRegion *update,
+ CoreSurfaceBufferLock *lock )
+{
+ SH7722DriverData *sdrv = driver_data;
+ SH7722DeviceData *sdev = sdrv->dev;
+
+ D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
+
+ D_ASSERT( surface != NULL );
+ D_ASSERT( sdrv != NULL );
+ D_ASSERT( sdev != NULL );
+
+ /* Start operation! */
+ BEU_Start( sdrv, sdev );
+
+ return DFB_OK;
+}
+
+DisplayLayerFuncs sh7722MultiLayerFuncs = {
+ .LayerDataSize = sh7722LayerDataSize,
+ .RegionDataSize = sh7722RegionDataSize,
+ .InitLayer = sh7722InitLayer,
+
+ .TestRegion = sh7722TestRegion,
+ .AddRegion = sh7722AddRegion,
+ .SetRegion = sh7722SetRegion,
+ .RemoveRegion = sh7722RemoveRegion,
+ .FlipRegion = sh7722FlipRegion,
+ .UpdateRegion = sh7722UpdateRegion,
+};
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.h b/Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.h
new file mode 100755
index 0000000..1a8008e
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.h
@@ -0,0 +1,11 @@
+#ifndef __SH7722__MULTI_H__
+#define __SH7722__MULTI_H__
+
+#include "sh7722_types.h"
+
+#define SH7722_MULTI_SUPPORTED_OPTIONS (DLOP_SRC_COLORKEY)
+
+extern DisplayLayerFuncs sh7722MultiLayerFuncs;
+
+#endif
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_regs.h b/Source/DirectFB/gfxdrivers/sh772x/sh7722_regs.h
new file mode 100755
index 0000000..c0ef019
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_regs.h
@@ -0,0 +1,624 @@
+#ifndef __SH7722__SH7722_REGS_H__
+#define __SH7722__SH7722_REGS_H__
+
+
+/******************************************************************************
+ * Register access
+ */
+
+#define VEU_REG_BASE 0xFE920000
+#define SH7722_BEU_BASE 0xFE930000
+#define LCDC_REG_BASE 0xFE940000
+#define JPEG_REG_BASE 0xFEA00000
+
+
+/******************************************************************************
+ * BEU
+ */
+
+/* BEU start register */
+#define BESTR (SH7722_BEU_BASE + 0x0000)
+
+/* BEU source memory width register 1 */
+#define BSMWR1 (SH7722_BEU_BASE + 0x0010)
+
+/* BEU source size register 1 */
+#define BSSZR1 (SH7722_BEU_BASE + 0x0014)
+
+/* BEU source address Y register 1 */
+#define BSAYR1 (SH7722_BEU_BASE + 0x0018)
+
+/* BEU source address C register 1 */
+#define BSACR1 (SH7722_BEU_BASE + 0x001C)
+
+/* BEU source address A register 1 */
+#define BSAAR1 (SH7722_BEU_BASE + 0x0020)
+
+/* BEU source image format register 1 */
+#define BSIFR1 (SH7722_BEU_BASE + 0x0024)
+
+/* BEU source memory width register 2 */
+#define BSMWR2 (SH7722_BEU_BASE + 0x0028)
+
+/* BEU source size register 2 */
+#define BSSZR2 (SH7722_BEU_BASE + 0x002C)
+
+/* BEU source address Y register 2 */
+#define BSAYR2 (SH7722_BEU_BASE + 0x0030)
+
+/* BEU source address C register 2 */
+#define BSACR2 (SH7722_BEU_BASE + 0x0034)
+
+/* BEU source address A register 2 */
+#define BSAAR2 (SH7722_BEU_BASE + 0x0038)
+
+/* BEU source image format register 2 */
+#define BSIFR2 (SH7722_BEU_BASE + 0x003C)
+
+/* BEU source memory width register 3 */
+#define BSMWR3 (SH7722_BEU_BASE + 0x0040)
+
+/* BEU source size register 3 */
+#define BSSZR3 (SH7722_BEU_BASE + 0x0044)
+
+/* BEU source address Y register 3 */
+#define BSAYR3 (SH7722_BEU_BASE + 0x0048)
+
+/* BEU source address C register 3 */
+#define BSACR3 (SH7722_BEU_BASE + 0x004C)
+
+/* BEU source address A register 3 */
+#define BSAAR3 (SH7722_BEU_BASE + 0x0050)
+
+/* BEU source image format register 3 */
+#define BSIFR3 (SH7722_BEU_BASE + 0x0054)
+
+/* BEU tile pattern size register */
+#define BTPSR (SH7722_BEU_BASE + 0x0058)
+
+/* BEU multidisplay source memory width register 1 */
+#define BMSMWR1 (SH7722_BEU_BASE + 0x0070)
+
+/* BEU multidisplay source size register 1 */
+#define BMSSZR1 (SH7722_BEU_BASE + 0x0074)
+
+/* BEU multidisplay source address Y register 1 */
+#define BMSAYR1 (SH7722_BEU_BASE + 0x0078)
+
+/* BEU multidisplay source address C register 1 */
+#define BMSACR1 (SH7722_BEU_BASE + 0x007C)
+
+/* BEU multidisplay source memory width register 2 */
+#define BMSMWR2 (SH7722_BEU_BASE + 0x0080)
+
+/* BEU multidisplay source size register 2 */
+#define BMSSZR2 (SH7722_BEU_BASE + 0x0084)
+
+/* BEU multidisplay source address Y register 2 */
+#define BMSAYR2 (SH7722_BEU_BASE + 0x0088)
+
+/* BEU multidisplay source address C register 2 */
+#define BMSACR2 (SH7722_BEU_BASE + 0x008C)
+
+/* BEU multidisplay source memory width register 3 */
+#define BMSMWR3 (SH7722_BEU_BASE + 0x0090)
+
+/* BEU multidisplay source size register 3 */
+#define BMSSZR3 (SH7722_BEU_BASE + 0x0094)
+
+/* BEU multidisplay source address Y register 3 */
+#define BMSAYR3 (SH7722_BEU_BASE + 0x0098)
+
+/* BEU multidisplay source address C register 3 */
+#define BMSACR3 (SH7722_BEU_BASE + 0x009C)
+
+/* BEU multidisplay source memory width register 4 */
+#define BMSMWR4 (SH7722_BEU_BASE + 0x00A0)
+
+/* BEU multidisplay source size register 4 */
+#define BMSSZR4 (SH7722_BEU_BASE + 0x00A4)
+
+/* BEU multidisplay source address Y register 4 */
+#define BMSAYR4 (SH7722_BEU_BASE + 0x00A8)
+
+/* BEU multidisplay source address C register 4 */
+#define BMSACR4 (SH7722_BEU_BASE + 0x00AC)
+
+/* BEU multidisplay source image format register */
+#define BMSIFR (SH7722_BEU_BASE + 0x00F0)
+
+/* BEU blend control register 0 */
+#define BBLCR0 (SH7722_BEU_BASE + 0x0100)
+
+/* BEU blend control register 1 */
+#define BBLCR1 (SH7722_BEU_BASE + 0x0104)
+
+/* BEU process control register */
+#define BPROCR (SH7722_BEU_BASE + 0x0108)
+
+/* BEU multiwindow control register 0 */
+#define BMWCR0 (SH7722_BEU_BASE + 0x010C)
+
+/* Blend location register 1 */
+#define BLOCR1 (SH7722_BEU_BASE + 0x0114)
+
+/* Blend location register 2 */
+#define BLOCR2 (SH7722_BEU_BASE + 0x0118)
+
+/* Blend location register 3 */
+#define BLOCR3 (SH7722_BEU_BASE + 0x011C)
+
+/* BEU multidisplay location register 1 */
+#define BMLOCR1 (SH7722_BEU_BASE + 0x0120)
+
+/* BEU multidisplay location register 2 */
+#define BMLOCR2 (SH7722_BEU_BASE + 0x0124)
+
+/* BEU multidisplay location register 3 */
+#define BMLOCR3 (SH7722_BEU_BASE + 0x0128)
+
+/* BEU multidisplay location register 4 */
+#define BMLOCR4 (SH7722_BEU_BASE + 0x012C)
+
+/* BEU multidisplay transparent color control register 1 */
+#define BMPCCR1 (SH7722_BEU_BASE + 0x0130)
+
+/* BEU multidisplay transparent color control register 2 */
+#define BMPCCR2 (SH7722_BEU_BASE + 0x0134)
+
+/* Blend pack form register */
+#define BPKFR (SH7722_BEU_BASE + 0x0140)
+
+/* BEU transparent color control register 0 */
+#define BPCCR0 (SH7722_BEU_BASE + 0x0144)
+
+/* BEU transparent color control register 11 */
+#define BPCCR11 (SH7722_BEU_BASE + 0x0148)
+
+/* BEU transparent color control register 12 */
+#define BPCCR12 (SH7722_BEU_BASE + 0x014C)
+
+/* BEU transparent color control register 21 */
+#define BPCCR21 (SH7722_BEU_BASE + 0x0150)
+
+/* BEU transparent color control register 22 */
+#define BPCCR22 (SH7722_BEU_BASE + 0x0154)
+
+/* BEU transparent color control register 31 */
+#define BPCCR31 (SH7722_BEU_BASE + 0x0158)
+
+/* BEU transparent color control register 32 */
+#define BPCCR32 (SH7722_BEU_BASE + 0x015C)
+
+/* BEU destination memory width register */
+#define BDMWR (SH7722_BEU_BASE + 0x0160)
+
+/* BEU destination address Y register */
+#define BDAYR (SH7722_BEU_BASE + 0x0164)
+
+/* BEU destination address C register */
+#define BDACR (SH7722_BEU_BASE + 0x0168)
+
+/* BEU address fixed register */
+#define BAFXR (SH7722_BEU_BASE + 0x0180)
+
+/* BEU swapping register */
+#define BSWPR (SH7722_BEU_BASE + 0x0184)
+
+/* BEU event interrupt enable register */
+#define BEIER (SH7722_BEU_BASE + 0x0188)
+
+/* BEU event register */
+#define BEVTR (SH7722_BEU_BASE + 0x018C)
+
+/* BEU register control register */
+#define BRCNTR (SH7722_BEU_BASE + 0x0194)
+
+/* BEU status register */
+#define BSTAR (SH7722_BEU_BASE + 0x0198)
+
+/* BEU module reset register */
+#define BBRSTR (SH7722_BEU_BASE + 0x019C)
+
+/* BEU register-plane forcible setting register */
+#define BRCHR (SH7722_BEU_BASE + 0x01A0)
+
+
+/* Color Lookup Table - CLUT registers (0-255) */
+#define BCLUT(n) (SH7722_BEU_BASE + 0x3000 + (n) * 0x04)
+
+
+
+/* BEU source memory width registers (0-2) */
+#define BSMWR(n) (SH7722_BEU_BASE + 0x0010 + (n) * 0x18)
+
+/* BEU source size registers (0-2) */
+#define BSSZR(n) (SH7722_BEU_BASE + 0x0014 + (n) * 0x18)
+
+/* BEU source address Y registers (0-2) */
+#define BSAYR(n) (SH7722_BEU_BASE + 0x0018 + (n) * 0x18)
+
+/* BEU source address C registers (0-2) */
+#define BSACR(n) (SH7722_BEU_BASE + 0x001C + (n) * 0x18)
+
+/* BEU source address A registers (0-2) */
+#define BSAAR(n) (SH7722_BEU_BASE + 0x0020 + (n) * 0x18)
+
+/* BEU source image format registers (0-2) */
+#define BSIFR(n) (SH7722_BEU_BASE + 0x0024 + (n) * 0x18)
+
+
+
+/* BEU multidisplay source memory width registers (0-3) */
+#define BMSMWR(n) (SH7722_BEU_BASE + 0x0070 + (n) * 0x10)
+
+/* BEU multidisplay source size registers (0-3) */
+#define BMSSZR(n) (SH7722_BEU_BASE + 0x0074 + (n) * 0x10)
+
+/* BEU multidisplay source address Y registers (0-3) */
+#define BMSAYR(n) (SH7722_BEU_BASE + 0x0078 + (n) * 0x10)
+
+/* BEU multidisplay source address C registers (0-3) */
+#define BMSACR(n) (SH7722_BEU_BASE + 0x007C + (n) * 0x10)
+
+
+
+/* Blend location registers (0-2) */
+#define BLOCR(n) (SH7722_BEU_BASE + 0x0114 + (n) * 0x04)
+
+/* BEU multidisplay location registers (0-3) */
+#define BMLOCR(n) (SH7722_BEU_BASE + 0x0120 + (n) * 0x04)
+
+
+/* BSIFR1-3 */
+#define CHRR_YCBCR_444 0x000
+#define CHRR_YCBCR_422 0x100
+#define CHRR_YCBCR_420 0x200
+#define CHRR_aYCBCR_444 0x300
+#define CHRR_aYCBCR_422 0x400
+#define CHRR_aYCBCR_420 0x500
+
+#define RPKF_ARGB 0x000
+#define RPKF_RGB32 0x000
+#define RPKF_RGB24 0x002
+#define RPKF_RGB16 0x003
+
+/* BSIFR1 */
+#define BSIFR1_IN1TE_RGBYUV 0x1000
+
+/* BSIFR3 */
+#define BSIFR3_MOD0_OSD 0x1000
+#define BSIFR3_MOD1_LUT 0x2000
+
+/* BPKFR */
+#define WPCK_RGB12 2
+#define WPCK_RGB16 6
+#define WPCK_RGB18 17
+#define WPCK_RGB32 19
+#define WPCK_RGB24 21
+
+#define CHDS_YCBCR444 0x000
+#define CHDS_YCBCR422 0x100
+#define CHDS_YCBCR420 0x200
+
+#define BPKFR_RY_YUV 0x000
+#define BPKFR_RY_RGB 0x800
+#define BPKFR_TE_DISABLED 0x000
+#define BPKFR_TE_ENABLED 0x400
+
+/* BBLCR0 */
+#define BBLCR0_LAY_123 0x05000000
+
+#define BBLCR0_AMUX_BLENDPIXEL(n) (0x10000000 << (n))
+
+/* BBLCR1 */
+#define MT_MEMORY 0x10000
+#define MT_VOU 0x20000
+#define MT_MEMORY_VOU 0x30000
+#define MT_LCDC 0x40000
+#define MT_LCDC_MEMORY 0x50000
+
+#define BBLCR1_PWD_INPUT1 0x00000000
+#define BBLCR1_PWD_INPUT2 0x01000000
+#define BBLCR1_PWD_INPUT3 0x02000000
+#define BBLCR1_PWD_INPUT_MASK 0x03000000
+
+/* BSWPR */
+#define BSWPR_MODSEL_GLOBAL 0x00000000
+#define BSWPR_MODSEL_EACH 0x80000000
+
+#define BSWPR_INPUT_BYTESWAP 0x00000001
+#define BSWPR_INPUT_WORDSWAP 0x00000002
+#define BSWPR_INPUT_LONGSWAP 0x00000004
+
+#define BSWPR_OUTPUT_BYTESWAP 0x00000010
+#define BSWPR_OUTPUT_WORDSWAP 0x00000020
+#define BSWPR_OUTPUT_LONGSWAP 0x00000040
+
+#define BSWPR_INPUT2_BYTESWAP 0x00000100
+#define BSWPR_INPUT2_WORDSWAP 0x00000200
+#define BSWPR_INPUT2_LONGSWAP 0x00000400
+
+#define BSWPR_INPUT3_BYTESWAP 0x00010000
+#define BSWPR_INPUT3_WORDSWAP 0x00020000
+#define BSWPR_INPUT3_LONGSWAP 0x00040000
+
+#define BSWPR_MULWIN_BYTESWAP 0x01000000
+#define BSWPR_MULWIN_WORDSWAP 0x02000000
+#define BSWPR_MULWIN_LONGSWAP 0x04000000
+
+
+/******************************************************************************
+ * VEU
+ */
+
+#define VEU_VESTR (VEU_REG_BASE + 0x0000)
+#define VEU_VESWR (VEU_REG_BASE + 0x0010)
+#define VEU_VESSR (VEU_REG_BASE + 0x0014)
+#define VEU_VSAYR (VEU_REG_BASE + 0x0018)
+#define VEU_VSACR (VEU_REG_BASE + 0x001c)
+#define VEU_VBSSR (VEU_REG_BASE + 0x0020)
+#define VEU_VEDWR (VEU_REG_BASE + 0x0030)
+#define VEU_VDAYR (VEU_REG_BASE + 0x0034)
+#define VEU_VDACR (VEU_REG_BASE + 0x0038)
+#define VEU_VTRCR (VEU_REG_BASE + 0x0050)
+#define VEU_VRFCR (VEU_REG_BASE + 0x0054)
+#define VEU_VRFSR (VEU_REG_BASE + 0x0058)
+#define VEU_VENHR (VEU_REG_BASE + 0x005c)
+#define VEU_VFMCR (VEU_REG_BASE + 0x0070)
+#define VEU_VVTCR (VEU_REG_BASE + 0x0074)
+#define VEU_VHTCR (VEU_REG_BASE + 0x0078)
+#define VEU_VAPCR (VEU_REG_BASE + 0x0080)
+#define VEU_VECCR (VEU_REG_BASE + 0x0084)
+#define VEU_VAFXR (VEU_REG_BASE + 0x0090)
+#define VEU_VSWPR (VEU_REG_BASE + 0x0094)
+#define VEU_VEIER (VEU_REG_BASE + 0x00a0)
+#define VEU_VEVTR (VEU_REG_BASE + 0x00a4)
+#define VEU_VSTAR (VEU_REG_BASE + 0x00b0)
+#define VEU_VBSRR (VEU_REG_BASE + 0x00b4)
+
+
+/******************************************************************************
+ * LCD
+ */
+
+#define LCDC_LUT(n) (LCDC_REG_BASE + (n) * 4)
+#define LCDC_MLDDCKPAT1R (LCDC_REG_BASE + 0x0400)
+#define LCDC_MLDDCKPAT2R (LCDC_REG_BASE + 0x0404)
+#define LCDC_SLDDCKPAT1R (LCDC_REG_BASE + 0x0408)
+#define LCDC_SLDDCKPAT2R (LCDC_REG_BASE + 0x040c)
+#define LCDC_LDDCKR (LCDC_REG_BASE + 0x0410)
+#define LCDC_LDDCKSTPR (LCDC_REG_BASE + 0x0414)
+#define LCDC_MLDMT1R (LCDC_REG_BASE + 0x0418)
+#define LCDC_MLDMT2R (LCDC_REG_BASE + 0x041c)
+#define LCDC_MLDMT3R (LCDC_REG_BASE + 0x0420)
+#define LCDC_MLDDFR (LCDC_REG_BASE + 0x0424)
+#define LCDC_MLDSM1R (LCDC_REG_BASE + 0x0428)
+#define LCDC_MLDSM2R (LCDC_REG_BASE + 0x042c)
+#define LCDC_MLDSA1R (LCDC_REG_BASE + 0x0430)
+#define LCDC_MLDSA2R (LCDC_REG_BASE + 0x0434)
+#define LCDC_MLDMLSR (LCDC_REG_BASE + 0x0438)
+#define LCDC_MLDWBFR (LCDC_REG_BASE + 0x043c)
+#define LCDC_MLDWBCNTR (LCDC_REG_BASE + 0x0440)
+#define LCDC_MLDWBAR (LCDC_REG_BASE + 0x0444)
+#define LCDC_MLDHCNR (LCDC_REG_BASE + 0x0448)
+#define LCDC_MLDHSYNR (LCDC_REG_BASE + 0x044c)
+#define LCDC_MLDVLNR (LCDC_REG_BASE + 0x0450)
+#define LCDC_MLDVSYNR (LCDC_REG_BASE + 0x0454)
+#define LCDC_MLDHPDR (LCDC_REG_BASE + 0x0458)
+#define LCDC_MLDVPDR (LCDC_REG_BASE + 0x045c)
+#define LCDC_MLDPMR (LCDC_REG_BASE + 0x0460)
+#define LCDC_LDPALCR (LCDC_REG_BASE + 0x0464)
+#define LCDC_LDINTR (LCDC_REG_BASE + 0x0468)
+#define LCDC_LDSR (LCDC_REG_BASE + 0x046c)
+#define LCDC_LDCNT1R (LCDC_REG_BASE + 0x0470)
+#define LCDC_LDCNT2R (LCDC_REG_BASE + 0x0474)
+#define LCDC_LDRCNTR (LCDC_REG_BASE + 0x0478)
+#define LCDC_LDDDSR (LCDC_REG_BASE + 0x047c)
+#define LCDC_LDRCR (LCDC_REG_BASE + 0x0484)
+
+
+/******************************************************************************
+ * JPEG
+ */
+
+/* JPEG code mode register */
+#define JCMOD (JPEG_REG_BASE + 0x0000)
+
+/* JPEG code command register */
+#define JCCMD (JPEG_REG_BASE + 0x0004)
+
+/* JPEG code status register */
+#define JCSTS (JPEG_REG_BASE + 0x0008)
+
+/* JPEG code quantization table number register */
+#define JCQTN (JPEG_REG_BASE + 0x000C)
+
+/* JPEG code Huffman table number register */
+#define JCHTN (JPEG_REG_BASE + 0x0010)
+
+/* JPEG code DRI upper register */
+#define JCDRIU (JPEG_REG_BASE + 0x0014)
+
+/* JPEG code DRI lower register */
+#define JCDRID (JPEG_REG_BASE + 0x0018)
+
+/* JPEG code vertical size upper register */
+#define JCVSZU (JPEG_REG_BASE + 0x001C)
+
+/* JPEG code vertical size lower register */
+#define JCVSZD (JPEG_REG_BASE + 0x0020)
+
+/* JPEG code horizontal size upper register */
+#define JCHSZU (JPEG_REG_BASE + 0x0024)
+
+/* JPEG code horizontal size lower register */
+#define JCHSZD (JPEG_REG_BASE + 0x0028)
+
+/* JPEG code data count upper register */
+#define JCDTCU (JPEG_REG_BASE + 0x002C)
+
+/* JPEG code data count middle register */
+#define JCDTCM (JPEG_REG_BASE + 0x0030)
+
+/* JPEG code data count lower register */
+#define JCDTCD (JPEG_REG_BASE + 0x0034)
+
+/* JPEG interrupt enable register */
+#define JINTE (JPEG_REG_BASE + 0x0038)
+
+/* JPEG interrupt status register */
+#define JINTS (JPEG_REG_BASE + 0x003C)
+
+/* JPEG code decode error register */
+#define JCDERR (JPEG_REG_BASE + 0x0040)
+
+/* JPEG code reset register */
+#define JCRST (JPEG_REG_BASE + 0x0044)
+
+/* JPEG interface control register */
+#define JIFCNT (JPEG_REG_BASE + 0x0060)
+
+/* JPEG interface encoding control register */
+#define JIFECNT (JPEG_REG_BASE + 0x0070)
+
+/* JPEG interface encode source Y address register 1 */
+#define JIFESYA1 (JPEG_REG_BASE + 0x0074)
+
+/* JPEG interface encode source C address register 1 */
+#define JIFESCA1 (JPEG_REG_BASE + 0x0078)
+
+/* JPEG interface encode source Y address register 2 */
+#define JIFESYA2 (JPEG_REG_BASE + 0x007C)
+
+/* JPEG interface encode source C address register 2 */
+#define JIFESCA2 (JPEG_REG_BASE + 0x0080)
+
+/* JPEG interface encode source memory width register */
+#define JIFESMW (JPEG_REG_BASE + 0x0084)
+
+/* JPEG interface encode source vertical size register */
+#define JIFESVSZ (JPEG_REG_BASE + 0x0088)
+
+/* JPEG interface encode source horizontal size register */
+#define JIFESHSZ (JPEG_REG_BASE + 0x008C)
+
+/* JPEG interface encode destination address register 1 */
+#define JIFEDA1 (JPEG_REG_BASE + 0x0090)
+
+/* JPEG interface encode destination address register 2 */
+#define JIFEDA2 (JPEG_REG_BASE + 0x0094)
+
+/* JPEG interface encode data reload size register */
+#define JIFEDRSZ (JPEG_REG_BASE + 0x0098)
+
+/* JPEG interface decoding control register */
+#define JIFDCNT (JPEG_REG_BASE + 0x00A0)
+
+/* JPEG interface decode source address register 1 */
+#define JIFDSA1 (JPEG_REG_BASE + 0x00A4)
+
+/* JPEG interface decode source address register 2 */
+#define JIFDSA2 (JPEG_REG_BASE + 0x00A8)
+
+/* JPEG interface decode data reload size register */
+#define JIFDDRSZ (JPEG_REG_BASE + 0x00AC)
+
+/* JPEG interface decode destination memory width register */
+#define JIFDDMW (JPEG_REG_BASE + 0x00B0)
+
+/* JPEG interface decode destination vertical size register */
+#define JIFDDVSZ (JPEG_REG_BASE + 0x00B4)
+
+/* JPEG interface decode destination horizontal size register */
+#define JIFDDHSZ (JPEG_REG_BASE + 0x00B8)
+
+/* JPEG interface decode destination Y address register 1 */
+#define JIFDDYA1 (JPEG_REG_BASE + 0x00BC)
+
+/* JPEG interface decode destination C address register 1 */
+#define JIFDDCA1 (JPEG_REG_BASE + 0x00C0)
+
+/* JPEG interface decode destination Y address register 2 */
+#define JIFDDYA2 (JPEG_REG_BASE + 0x00C4)
+
+/* JPEG interface decode destination C address register 2 */
+#define JIFDDCA2 (JPEG_REG_BASE + 0x00C8)
+
+
+/* JPEG code quantization table 0 register */
+#define JCQTBL0(n) (JPEG_REG_BASE + 0x10000 + (((n)*4) & 0x3C)) // to 0x1003C
+
+/* JPEG code quantization table 1 register */
+#define JCQTBL1(n) (JPEG_REG_BASE + 0x10040 + (((n)*4) & 0x3C)) // to 0x1007C
+
+/* JPEG code quantization table 2 register */
+#define JCQTBL2(n) (JPEG_REG_BASE + 0x10080 + (((n)*4) & 0x3C)) // to 0x100BC
+
+/* JPEG code quantization table 3 register */
+#define JCQTBL3(n) (JPEG_REG_BASE + 0x100C0 + (((n)*4) & 0x3C)) // to 0x100FC
+
+/* JPEG code Huffman table DC0 register */
+#define JCHTBD0(n) (JPEG_REG_BASE + 0x10100 + (((n)*4) & 0x1C)) // to 0x1010C
+
+/* JPEG code Huffman table DC0 register */
+//#define JCHTBD1(n) (JPEG_REG_BASE + 0x10110 + (((n)*4) & 0x0C)) // to 0x10118
+
+/* JPEG code Huffman table AC0 register */
+#define JCHTBA0(n) (JPEG_REG_BASE + 0x10120 + (((n)*4) & 0xFC)) // to 0x1012C
+
+/* JPEG code Huffman table AC0 register */
+//#define JCHTBA1(n) (JPEG_REG_BASE + 0x10130 + (((n)*4) & 0x0C)) // to 0x101D0
+
+/* JPEG code Huffman table DC1 register */
+#define JCHTBD1(n) (JPEG_REG_BASE + 0x10200 + (((n)*4) & 0x1C)) // to 0x1020C
+
+/* JPEG code Huffman table DC1 register */
+//#define JCHTBD3(n) (JPEG_REG_BASE + 0x10210 + (((n)*4) & 0x0C)) // to 0x10218
+
+/* JPEG code Huffman table AC1 register */
+#define JCHTBA1(n) (JPEG_REG_BASE + 0x10220 + (((n)*4) & 0xFC)) // to 0x1022C
+
+/* JPEG code Huffman table AC1 register */
+//#define JCHTBA3(n) (JPEG_REG_BASE + 0x10230 + (((n)*4) & 0xFC)) // to 0x102D0
+
+
+#define JCCMD_START 0x00000001
+#define JCCMD_RESTART 0x00000002
+#define JCCMD_END 0x00000004
+#define JCCMD_LCMD2 0x00000100
+#define JCCMD_LCMD1 0x00000200
+#define JCCMD_RESET 0x00000080
+#define JCCMD_READ_RESTART 0x00000400
+#define JCCMD_WRITE_RESTART 0x00000800
+#define JCMOD_DSP_ENCODE 0x00000000
+#define JCMOD_DSP_DECODE 0x00000008
+#define JCMOD_INPUT_CTRL 0x00000080 // must always be set
+#define JIFCNT_VJSEL_JPU 0x00000000
+#define JIFCNT_VJSEL_VPU 0x00000002
+
+#define JIFECNT_LINEBUF_MODE 0x00000002
+#define JIFECNT_SWAP_1234 0x00000000
+#define JIFECNT_SWAP_2143 0x00000010
+#define JIFECNT_SWAP_3412 0x00000020
+#define JIFECNT_SWAP_4321 0x00000030
+#define JIFECNT_RELOAD_ENABLE 0x00000040
+
+#define JIFDCNT_LINEBUF_MODE 0x00000001
+#define JIFDCNT_SWAP_1234 0x00000000
+#define JIFDCNT_SWAP_2143 0x00000002
+#define JIFDCNT_SWAP_3412 0x00000004
+#define JIFDCNT_SWAP_4321 0x00000006
+#define JIFDCNT_RELOAD_ENABLE 0x00000008
+
+#define JINTS_MASK 0x00007C68
+#define JINTS_INS3_HEADER 0x00000008
+#define JINTS_INS5_ERROR 0x00000020
+#define JINTS_INS6_DONE 0x00000040
+#define JINTS_INS10_XFER_DONE 0x00000400
+#define JINTS_INS11_LINEBUF0 0x00000800
+#define JINTS_INS12_LINEBUF1 0x00001000
+#define JINTS_INS13_LOADED 0x00002000
+#define JINTS_INS14_RELOAD 0x00004000
+
+#endif
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_screen.c b/Source/DirectFB/gfxdrivers/sh772x/sh7722_screen.c
new file mode 100755
index 0000000..2fe4d46
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_screen.c
@@ -0,0 +1,85 @@
+#ifdef SH7722_DEBUG_SCREEN
+#define DIRECT_ENABLE_DEBUG
+#endif
+
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <sys/mman.h>
+
+#include <asm/types.h>
+
+#include <directfb.h>
+
+#include <fusion/fusion.h>
+#include <fusion/shmalloc.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+#include <core/layers.h>
+#include <core/palette.h>
+#include <core/surface.h>
+#include <core/system.h>
+
+#include <gfx/convert.h>
+
+#include <misc/conf.h>
+
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+
+
+#include "sh7722.h"
+#include "sh7722_screen.h"
+
+
+D_DEBUG_DOMAIN( SH7722_Screen, "SH7722/Screen", "Renesas SH7722 Screen" );
+
+/**********************************************************************************************************************/
+
+static DFBResult
+sh7722InitScreen( CoreScreen *screen,
+ CoreGraphicsDevice *device,
+ void *driver_data,
+ void *screen_data,
+ DFBScreenDescription *description )
+{
+ D_DEBUG_AT( SH7722_Screen, "%s()\n", __FUNCTION__ );
+
+ /* Set the screen capabilities. */
+ description->caps = DSCCAPS_NONE;
+
+ /* Set the screen name. */
+ snprintf( description->name, DFB_SCREEN_DESC_NAME_LENGTH, "SH7722 Screen" );
+
+ return DFB_OK;
+}
+
+static DFBResult
+sh7722GetScreenSize( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int *ret_width,
+ int *ret_height )
+{
+ SH7722DriverData *sdrv = driver_data;
+ SH7722DeviceData *sdev = sdrv->dev;
+ D_DEBUG_AT( SH7722_Screen, "%s()\n", __FUNCTION__ );
+
+ D_ASSERT( ret_width != NULL );
+ D_ASSERT( ret_height != NULL );
+
+ *ret_width = sdev->lcd_width;
+ *ret_height = sdev->lcd_height;
+
+ return DFB_OK;
+}
+
+ScreenFuncs sh7722ScreenFuncs = {
+ .InitScreen = sh7722InitScreen,
+ .GetScreenSize = sh7722GetScreenSize,
+};
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_screen.h b/Source/DirectFB/gfxdrivers/sh772x/sh7722_screen.h
new file mode 100755
index 0000000..d545ed8
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_screen.h
@@ -0,0 +1,9 @@
+#ifndef __SH7722__SCREEN_H__
+#define __SH7722__SCREEN_H__
+
+#include <core/screens.h>
+
+extern ScreenFuncs sh7722ScreenFuncs;
+
+#endif
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_types.h b/Source/DirectFB/gfxdrivers/sh772x/sh7722_types.h
new file mode 100755
index 0000000..ea367da
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_types.h
@@ -0,0 +1,136 @@
+#ifndef __SH7722__TYPES_H__
+#define __SH7722__TYPES_H__
+
+#include <core/layers.h>
+
+#include <sh772x_gfx.h>
+
+
+#define SH7722GFX_MAX_PREPARE 8192
+
+
+typedef enum {
+ SH7722_LAYER_INPUT1,
+ SH7722_LAYER_INPUT2,
+ SH7722_LAYER_INPUT3,
+ SH7722_LAYER_MULTIWIN
+} SH7722LayerID;
+
+
+typedef struct {
+ SH7722LayerID layer;
+} SH7722LayerData;
+
+typedef struct {
+ int magic;
+
+ CoreLayerRegionConfig config;
+
+ CoreSurface *surface;
+ CorePalette *palette;
+} SH7722RegionData;
+
+
+typedef struct {
+ unsigned int added;
+ unsigned int visible;
+} SH7722MultiLayerData;
+
+typedef struct {
+ int magic;
+
+ int index;
+ CoreLayerRegionConfig config;
+
+ CoreSurface *surface;
+ CorePalette *palette;
+} SH7722MultiRegionData;
+
+
+typedef struct {
+ int sh772x;
+
+ int lcd_width;
+ int lcd_height;
+ int lcd_offset;
+ int lcd_pitch;
+ int lcd_size;
+ unsigned long lcd_phys;
+ DFBSurfacePixelFormat lcd_format;
+
+ /* state validation */
+ int v_flags;
+
+ /* prepared register values */
+ u32 ble_srcf;
+ u32 ble_dstf;
+
+ /* cached values */
+ unsigned long dst_phys;
+ int dst_pitch;
+ int dst_bpp;
+ int dst_index;
+
+ unsigned long src_phys;
+ int src_pitch;
+ int src_bpp;
+ int src_index;
+
+ unsigned long mask_phys;
+ int mask_pitch;
+ DFBSurfacePixelFormat mask_format;
+ int mask_index;
+ DFBPoint mask_offset;
+ DFBSurfaceMaskFlags mask_flags;
+
+ DFBSurfaceDrawingFlags dflags;
+ DFBSurfaceBlittingFlags bflags;
+ DFBSurfaceRenderOptions render_options;
+
+ bool ckey_b_enabled;
+ bool color_change_enabled;
+ bool mask_enabled;
+
+ unsigned int input_mask;
+
+ s32 matrix[6];
+ DFBColor color;
+
+ /* locking */
+ FusionSkirmish beu_lock;
+
+
+ /* sh7723 */
+ u32 rclr;
+ u32 color16;
+} SH7722DeviceData;
+
+
+typedef struct {
+ SH7722DeviceData *dev;
+
+ CoreDFB *core;
+ CoreGraphicsDevice *device;
+
+ CoreScreen *screen;
+
+ CoreLayer *multi;
+ CoreLayer *input1;
+ CoreLayer *input2;
+ CoreLayer *input3;
+
+ int gfx_fd;
+ SH772xGfxSharedArea *gfx_shared;
+
+ int prep_num;
+ __u32 prep_buf[SH7722GFX_MAX_PREPARE];
+
+ volatile void *mmio_base;
+
+ int num_inputs;
+
+ volatile void *lcd_virt;
+} SH7722DriverData;
+
+#endif
+
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7723_blt.c b/Source/DirectFB/gfxdrivers/sh772x/sh7723_blt.c
new file mode 100755
index 0000000..f784e81
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7723_blt.c
@@ -0,0 +1,890 @@
+#ifdef SH7723_DEBUG_BLT
+ #define DIRECT_ENABLE_DEBUG
+#endif
+
+
+#include <config.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <malloc.h>
+#include <errno.h>
+
+#include <asm/types.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/memcpy.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/surface.h>
+#include <core/surface_buffer.h>
+
+#include <gfx/convert.h>
+
+#include "sh7722.h"
+
+#include "sh7723_blt.h"
+
+
+D_DEBUG_DOMAIN( SH7723_BLT, "SH7723/BLT", "Renesas SH7723 Drawing Engine" );
+
+/*
+ * State validation flags.
+ *
+ * There's no prefix because of the macros below.
+ */
+enum {
+ DEST = 0x00000001,
+ CLIP = 0x00000002,
+ DEST_CLIP = 0x00000003,
+
+ COLOR16 = 0x00000100,
+
+ ALPHA = 0x00001000,
+
+ SOURCE = 0x00010000,
+ STRANS = 0x00020000,
+
+ ALL = 0x00031103,
+};
+
+/*
+ * State handling macros.
+ */
+
+#define SH7723_VALIDATE(flags) do { sdev->v_flags |= (flags); } while (0)
+#define SH7723_INVALIDATE(flags) do { sdev->v_flags &= ~(flags); } while (0)
+
+#define SH7723_CHECK_VALIDATE(flag) do { \
+ if ((sdev->v_flags & flag) != flag) \
+ sh7723_validate_##flag( sdrv, sdev, state ); \
+ } while (0)
+
+#define DUMP_INFO() D_DEBUG_AT( SH7723_BLT, " -> %srunning, hw %d-%d, next %d-%d - %svalid\n", \
+ sdrv->gfx_shared->hw_running ? "" : "not ", \
+ sdrv->gfx_shared->hw_start, \
+ sdrv->gfx_shared->hw_end, \
+ sdrv->gfx_shared->next_start, \
+ sdrv->gfx_shared->next_end, \
+ sdrv->gfx_shared->next_valid ? "" : "not " );
+
+/**********************************************************************************************************************/
+
+static inline bool
+start_hardware( SH7722DriverData *sdrv )
+{
+ SH772xGfxSharedArea *shared = sdrv->gfx_shared;
+
+ D_DEBUG_AT( SH7723_BLT, "%s()\n", __FUNCTION__ );
+
+ DUMP_INFO();
+
+ if (shared->hw_running || !shared->next_valid || shared->next_end == shared->next_start)
+ return false;
+
+ shared->hw_running = true;
+ shared->hw_start = shared->next_start;
+ shared->hw_end = shared->next_end;
+
+ shared->next_start = shared->next_end = (shared->hw_end + 1 + 3) & ~3;
+ shared->next_valid = false;
+
+ shared->num_words += shared->hw_end - shared->hw_start;
+
+ shared->num_starts++;
+
+ DUMP_INFO();
+
+ D_ASSERT( shared->buffer[shared->hw_end] == M2DG_OPCODE_TRAP );
+
+ SH7722_TDG_SETREG32( sdrv, M2DG_DLSAR, shared->buffer_phys + shared->hw_start*4 );
+ SH7722_TDG_SETREG32( sdrv, M2DG_SCLR, 1 );
+ return true;
+}
+
+__attribute__((noinline))
+static void
+flush_prepared( SH7722DriverData *sdrv )
+{
+ SH772xGfxSharedArea *shared = sdrv->gfx_shared;
+ unsigned int timeout = 2;
+
+ D_DEBUG_AT( SH7723_BLT, "%s()\n", __FUNCTION__ );
+
+ DUMP_INFO();
+
+ D_ASSERT( sdrv->prep_num < SH772xGFX_BUFFER_WORDS );
+ D_ASSERT( sdrv->prep_num <= D_ARRAY_SIZE(sdrv->prep_buf) );
+
+ /* Something prepared? */
+ while (sdrv->prep_num) {
+ int next_end;
+
+ /* Mark shared information as invalid. From this point on the interrupt handler
+ * will not continue with the next block, and we'll start the hardware ourself. */
+ shared->next_valid = false;
+
+ /* Check if there's enough space at the end.
+ * Wait until hardware has started next block before it gets too big. */
+ if (shared->next_end + sdrv->prep_num >= SH772xGFX_BUFFER_WORDS ||
+ shared->next_end - shared->next_start >= SH772xGFX_BUFFER_WORDS/4) {
+ /* If there's no next block waiting, start at the beginning. */
+ if (shared->next_start == shared->next_end)
+ shared->next_start = shared->next_end = 0;
+ else {
+ D_ASSERT( shared->buffer[shared->hw_end] == M2DG_OPCODE_TRAP );
+
+ /* Mark area as valid again. */
+ shared->next_valid = true;
+
+ /* Start in case it got idle while doing the checks. */
+ if (!start_hardware( sdrv )) {
+ /*
+ * Hardware has not been started (still running).
+ * Check for timeout. */
+ if (!timeout--) {
+ D_ERROR( "SH7723/Blt: Timeout waiting for processing!\n" );
+ direct_log_printf( NULL, " -> %srunning, hw %d-%d, next %d-%d - %svalid\n", \
+ sdrv->gfx_shared->hw_running ? "" : "not ", \
+ sdrv->gfx_shared->hw_start, \
+ sdrv->gfx_shared->hw_end, \
+ sdrv->gfx_shared->next_start, \
+ sdrv->gfx_shared->next_end, \
+ sdrv->gfx_shared->next_valid ? "" : "not " );
+ D_ASSERT( shared->buffer[shared->hw_end] == M2DG_OPCODE_TRAP );
+ sh7723EngineReset( sdrv, sdrv->dev );
+ }
+
+ /* Wait til next block is started. */
+ ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_WAIT_NEXT );
+ }
+
+ /* Start over with the checks. */
+ continue;
+ }
+ }
+
+ /* We are appending in case there was already a next block. */
+ next_end = shared->next_end + sdrv->prep_num;
+
+ /* Reset the timeout counter. */
+ timeout = 2;
+
+ /* While the hardware is running... */
+ while (shared->hw_running) {
+ D_ASSERT( shared->buffer[shared->hw_end] == M2DG_OPCODE_TRAP );
+
+ /* ...make sure we don't over lap with its current buffer, otherwise wait. */
+ if (shared->hw_start > next_end || shared->hw_end < shared->next_start)
+ break;
+
+ /* Check for timeout. */
+ if (!timeout--) {
+ D_ERROR( "SH7723/Blt: Timeout waiting for space!\n" );
+ direct_log_printf( NULL, " -> %srunning, hw %d-%d, next %d-%d - %svalid\n", \
+ sdrv->gfx_shared->hw_running ? "" : "not ", \
+ sdrv->gfx_shared->hw_start, \
+ sdrv->gfx_shared->hw_end, \
+ sdrv->gfx_shared->next_start, \
+ sdrv->gfx_shared->next_end, \
+ sdrv->gfx_shared->next_valid ? "" : "not " );
+ D_ASSERT( shared->buffer[shared->hw_end] == M2DG_OPCODE_TRAP );
+ sh7723EngineReset( sdrv, sdrv->dev );
+ }
+
+ /* Wait til next block is started. */
+ ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_WAIT_NEXT );
+ }
+
+ /* Copy from local to shared buffer. */
+ direct_memcpy( (void*) &shared->buffer[shared->next_end], &sdrv->prep_buf[0], sdrv->prep_num * sizeof(__u32) );
+
+ /* Terminate the block. */
+ shared->buffer[next_end] = M2DG_OPCODE_TRAP;
+
+ /* Update next block information and mark valid. */
+ shared->next_end = next_end;
+ shared->next_valid = true;
+
+ /* Reset local counter. */
+ sdrv->prep_num = 0;
+ }
+
+ /* Start in case it is idle. */
+ start_hardware( sdrv );
+}
+
+static inline __u32 *
+start_buffer( SH7722DriverData *sdrv,
+ int space )
+{
+ /* Check for space in local buffer. */
+ if (sdrv->prep_num + space > SH7722GFX_MAX_PREPARE) {
+ /* Flush local buffer. */
+ flush_prepared( sdrv );
+
+ D_ASSERT( sdrv->prep_num == 0 );
+ }
+
+ /* Return next write position. */
+ return &sdrv->prep_buf[sdrv->prep_num];
+}
+
+static inline void
+submit_buffer( SH7722DriverData *sdrv,
+ int entries )
+{
+ D_ASSERT( sdrv->prep_num + entries <= SH7722GFX_MAX_PREPARE );
+
+ /* Increment next write position. */
+ sdrv->prep_num += entries;
+}
+
+/**********************************************************************************************************************/
+
+static inline void
+sh7723_validate_DEST_CLIP( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev,
+ CardState *state )
+{
+ __u32 *prep = start_buffer( sdrv, 18 );
+
+ D_DEBUG_AT( SH7723_BLT, "%s( 0x%08lx [%d] - %4d,%4d-%4dx%4d )\n", __FUNCTION__,
+ state->dst.phys, state->dst.pitch, DFB_RECTANGLE_VALS_FROM_REGION( &state->clip ) );
+
+ prep[0] = M2DG_OPCODE_WPR;
+ prep[1] = 0x0d4;
+ prep[2] = SH7723_XY( state->clip.x1, state->clip.y1 ) ;
+
+ prep[3] = M2DG_OPCODE_WPR;
+ prep[4] = 0x0d8;
+ prep[5] = SH7723_XY( state->clip.x2, state->clip.y2) ;
+
+ if (sdev->v_flags & DEST) {
+ submit_buffer( sdrv, 6 );
+ }
+ else {
+ CoreSurface *surface = state->destination;
+ CoreSurfaceBuffer *buffer = state->dst.buffer;
+
+ sdev->dst_phys = state->dst.phys;
+ sdev->dst_pitch = state->dst.pitch;
+ sdev->dst_bpp = DFB_BYTES_PER_PIXEL( buffer->format );
+ sdev->dst_index = DFB_PIXELFORMAT_INDEX( buffer->format ) % DFB_NUM_PIXELFORMATS;
+
+ sdev->rclr &= ~0x00140000;
+
+ switch (buffer->format) {
+ case DSPF_RGB16:
+ sdev->rclr |= 0x00040000;
+ break;
+
+ case DSPF_ARGB1555:
+ sdev->rclr |= 0x00140000;
+ break;
+
+ default:
+ D_BUG("Unexpected pixelformat\n");
+ return;
+ }
+
+ /* Set destination start address. */
+ prep[ 6] = M2DG_OPCODE_WPR;
+ prep[ 7] = 0x50;
+ prep[ 8] = sdev->dst_phys;
+
+ /* Set destination stride. */
+ prep[ 9] = M2DG_OPCODE_WPR;
+ prep[10] = 0x5c;
+ prep[11] = sdev->dst_pitch / sdev->dst_bpp;
+
+ /* Set destination pixelformat in rendering control. */
+ prep[12] = M2DG_OPCODE_WPR;
+ prep[13] = 0xc0;
+ prep[14] = sdev->rclr;
+
+ /* Set system clipping rectangle. */
+ prep[15] = M2DG_OPCODE_WPR;
+ prep[16] = 0xd0;
+ prep[17] = SH7723_XY( surface->config.size.w - 1, surface->config.size.h - 1 );
+
+ submit_buffer( sdrv, 18 );
+ }
+
+ /* Set the flags. */
+ SH7723_VALIDATE( DEST_CLIP );
+}
+
+static inline void
+sh7723_validate_COLOR16( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev,
+ CardState *state )
+{
+ sdev->color16 = dfb_pixel_from_color( state->destination->config.format, &state->color );
+
+ /* Set the flags. */
+ SH7723_VALIDATE( COLOR16 );
+}
+
+static inline void
+sh7723_validate_ALPHA( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev,
+ CardState *state )
+{
+ __u32 *prep = start_buffer( sdrv, 3 );
+
+ prep[0] = M2DG_OPCODE_WPR;
+ prep[1] = 0x088;
+ prep[2] = state->color.a;
+
+ submit_buffer( sdrv, 3 );
+
+ /* Set the flags. */
+ SH7723_VALIDATE( ALPHA );
+}
+
+static inline void
+sh7723_validate_SOURCE( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev,
+ CardState *state )
+{
+ __u32 *prep = start_buffer( sdrv, 6 );
+
+ CoreSurfaceBuffer *buffer = state->src.buffer;
+
+ sdev->src_phys = state->src.phys;
+ sdev->src_pitch = state->src.pitch;
+ sdev->src_bpp = DFB_BYTES_PER_PIXEL( buffer->format );
+ sdev->src_index = DFB_PIXELFORMAT_INDEX( buffer->format ) % DFB_NUM_PIXELFORMATS;
+
+ /* Set source start address. */
+ prep[0] = M2DG_OPCODE_WPR;
+ prep[1] = 0x4c;
+ prep[2] = sdev->src_phys;
+
+ /* Set source stride. */
+ prep[3] = M2DG_OPCODE_WPR;
+ prep[4] = 0x58;
+ prep[5] = sdev->src_pitch / sdev->src_bpp;
+
+ submit_buffer( sdrv, 6 );
+
+ /* Set the flags. */
+ SH7723_VALIDATE( SOURCE );
+}
+
+static inline void
+sh7723_validate_STRANS( SH7722DriverData *sdrv,
+ SH7722DeviceData *sdev,
+ CardState *state )
+{
+ __u32 *prep = start_buffer( sdrv, 3 );
+
+ prep[0] = M2DG_OPCODE_WPR;
+ prep[1] = 0x080;
+ prep[2] = state->src_colorkey;
+
+ submit_buffer( sdrv, 3 );
+
+ /* Set the flags. */
+ SH7723_VALIDATE( STRANS );
+}
+
+/**********************************************************************************************************************/
+
+DFBResult
+sh7723EngineSync( void *drv, void *dev )
+{
+ DFBResult ret = DFB_OK;
+ SH7722DriverData *sdrv = drv;
+ SH772xGfxSharedArea *shared = sdrv->gfx_shared;
+
+ D_DEBUG_AT( SH7723_BLT, "%s()\n", __FUNCTION__ );
+
+ DUMP_INFO();
+
+ while (shared->hw_running && ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_WAIT_IDLE ) < 0) {
+ if (errno == EINTR)
+ continue;
+
+ ret = errno2result( errno );
+ D_PERROR( "SH7723/BLT: SH7723GFX_IOCTL_WAIT_IDLE failed!\n" );
+
+ direct_log_printf( NULL, " -> %srunning, hw %d-%d, next %d-%d - %svalid\n", \
+ sdrv->gfx_shared->hw_running ? "" : "not ", \
+ sdrv->gfx_shared->hw_start, \
+ sdrv->gfx_shared->hw_end, \
+ sdrv->gfx_shared->next_start, \
+ sdrv->gfx_shared->next_end, \
+ sdrv->gfx_shared->next_valid ? "" : "not " );
+
+ break;
+ }
+
+ if (ret == DFB_OK) {
+ D_ASSERT( !shared->hw_running );
+ D_ASSERT( !shared->next_valid );
+ }
+
+ return ret;
+}
+
+void
+sh7723EngineReset( void *drv, void *dev )
+{
+ SH7722DriverData *sdrv = drv;
+ __u32 *prep;
+
+ D_DEBUG_AT( SH7723_BLT, "%s()\n", __FUNCTION__ );
+
+ DUMP_INFO();
+
+ ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_RESET );
+
+ prep = start_buffer( sdrv, 4 );
+
+ /* Reset current pointer. */
+ prep[0] = M2DG_OPCODE_MOVE;
+ prep[1] = 0;
+
+ /* Reset local offset. */
+ prep[2] = M2DG_OPCODE_LCOFS;
+ prep[3] = 0;
+
+ submit_buffer( sdrv, 4 );
+}
+
+void
+sh7723EmitCommands( void *drv, void *dev )
+{
+ SH7722DriverData *sdrv = drv;
+
+ D_DEBUG_AT( SH7723_BLT, "%s()\n", __FUNCTION__ );
+
+ flush_prepared( sdrv );
+}
+
+void
+sh7723FlushTextureCache( void *drv, void *dev )
+{
+ SH7722DriverData *sdrv = drv;
+ __u32 *prep = start_buffer( sdrv, 1 );
+
+ D_DEBUG_AT( SH7723_BLT, "%s()\n", __FUNCTION__ );
+
+ DUMP_INFO();
+
+ prep[0] = M2DG_OPCODE_SYNC | M2DG_SYNC_TCLR;
+
+ submit_buffer( sdrv, 1 );
+}
+
+/**********************************************************************************************************************/
+
+void
+sh7723CheckState( void *drv,
+ void *dev,
+ CardState *state,
+ DFBAccelerationMask accel )
+{
+ D_DEBUG_AT( SH7723_BLT, "%s( %p, 0x%08x )\n", __FUNCTION__, state, accel );
+
+ /* Return if the desired function is not supported at all. */
+ if (accel & ~(SH7723_SUPPORTED_DRAWINGFUNCTIONS | SH7723_SUPPORTED_BLITTINGFUNCTIONS))
+ return;
+
+ /* Return if the destination format is not supported. */
+ switch (state->destination->config.format) {
+ case DSPF_RGB16:
+// case DSPF_ARGB1555:
+ break;
+
+ default:
+ return;
+ }
+
+ /* Check if drawing or blitting is requested. */
+ if (DFB_DRAWING_FUNCTION( accel )) {
+ /* Return if unsupported drawing flags are set. */
+ if (state->drawingflags & ~SH7723_SUPPORTED_DRAWINGFLAGS)
+ return;
+
+ /* Return if blending with unsupported blend functions is requested. */
+ if (state->drawingflags & DSDRAW_BLEND) {
+ switch (accel) {
+ case DFXL_FILLRECTANGLE:
+ case DFXL_FILLTRIANGLE:
+ break;
+ default:
+ return;
+ }
+
+ /* Return if blending with unsupported blend functions is requested. */
+ if (state->src_blend != DSBF_SRCALPHA || state->dst_blend != DSBF_INVSRCALPHA)
+ return;
+
+ /* XOR only without blending. */
+ if (state->drawingflags & DSDRAW_XOR)
+ return;
+ }
+
+ /* Enable acceleration of drawing functions. */
+ state->accel |= accel;
+ } else {
+ DFBSurfaceBlittingFlags flags = state->blittingflags;
+
+ /* Return if unsupported blitting flags are set. */
+ if (flags & ~SH7723_SUPPORTED_BLITTINGFLAGS)
+ return;
+
+ /* Return if the source format is not supported. */
+ if (state->source->config.format != state->destination->config.format)
+ return;
+
+ /* Return if blending with unsupported blend functions is requested. */
+ if (flags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
+ if (state->src_blend != DSBF_SRCALPHA || state->dst_blend != DSBF_INVSRCALPHA)
+ return;
+ }
+
+ /* XOR only without blending etc. */
+ if (flags & DSBLIT_XOR &&
+ flags & ~(DSBLIT_SRC_COLORKEY | DSBLIT_ROTATE180 | DSBLIT_XOR))
+ return;
+
+ /* Return if colorizing for non-font surfaces is requested. */
+ if ((flags & DSBLIT_COLORIZE) && !(state->source->type & CSTF_FONT))
+ return;
+
+ /* Return if blending with both alpha channel and value is requested. */
+ if (D_FLAGS_ARE_SET( flags, DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA))
+ return;
+
+ /* Enable acceleration of blitting functions. */
+ state->accel |= accel;
+ }
+}
+
+/*
+ * Make sure that the hardware is programmed for execution of 'accel' according to the 'state'.
+ */
+void
+sh7723SetState( void *drv,
+ void *dev,
+ GraphicsDeviceFuncs *funcs,
+ CardState *state,
+ DFBAccelerationMask accel )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+ StateModificationFlags modified = state->mod_hw;
+
+ D_DEBUG_AT( SH7723_BLT, "%s( %p, 0x%08x ) <- modified 0x%08x\n",
+ __FUNCTION__, state, accel, modified );
+
+ DUMP_INFO();
+
+ /*
+ * 1) Invalidate hardware states
+ *
+ * Each modification to the hw independent state invalidates one or more hardware states.
+ */
+
+ /* Simply invalidate all? */
+ if (modified == SMF_ALL) {
+ SH7723_INVALIDATE( ALL );
+ } else if (modified) {
+ /* Invalidate destination registers. */
+ if (modified & SMF_DESTINATION)
+ SH7723_INVALIDATE( DEST | COLOR16 );
+
+ /* Invalidate clipping registers. */
+ if (modified & SMF_CLIP)
+ SH7723_INVALIDATE( CLIP );
+
+ /* Invalidate color registers. */
+ if (modified & SMF_COLOR)
+ SH7723_INVALIDATE( ALPHA | COLOR16 );
+
+ /* Invalidate source registers. */
+ if (modified & SMF_SOURCE)
+ SH7723_INVALIDATE( SOURCE );
+
+ /* Invalidate source colorkey. */
+ if (modified & SMF_SRC_COLORKEY)
+ SH7723_INVALIDATE( STRANS );
+ }
+
+ /*
+ * 2) Validate hardware states
+ *
+ * Each function has its own set of states that need to be validated.
+ */
+
+ /* Always requiring valid destination and clip. */
+ SH7723_CHECK_VALIDATE( DEST_CLIP );
+
+ /* Depending on the function... */
+ switch (accel) {
+ case DFXL_FILLRECTANGLE:
+ case DFXL_DRAWRECTANGLE:
+ case DFXL_FILLTRIANGLE:
+ case DFXL_DRAWLINE:
+ /* ...require valid color. */
+ SH7723_CHECK_VALIDATE( COLOR16 );
+
+ /* If blending is used, validate the alpha value. */
+ if (state->drawingflags & DSDRAW_BLEND)
+ SH7723_CHECK_VALIDATE( ALPHA );
+
+ /*
+ * 3) Tell which functions can be called without further validation, i.e. SetState()
+ *
+ * When the hw independent state is changed, this collection is reset.
+ */
+ state->set = SH7723_SUPPORTED_DRAWINGFUNCTIONS;
+
+ break;
+
+ case DFXL_BLIT:
+ /* ...require valid source. */
+ SH7723_CHECK_VALIDATE( SOURCE );
+
+ /* If blending is used, validate the alpha value. */
+ if (state->blittingflags & DSBLIT_BLEND_COLORALPHA)
+ SH7723_CHECK_VALIDATE( ALPHA );
+
+ /* If colorkeying is used, validate the colorkey. */
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY)
+ SH7723_CHECK_VALIDATE( STRANS );
+
+ /*
+ * 3) Tell which functions can be called without further validation, i.e. SetState()
+ *
+ * When the hw independent state is changed, this collection is reset.
+ */
+ state->set = SH7723_SUPPORTED_BLITTINGFUNCTIONS;
+
+ break;
+
+ default:
+ D_BUG( "unexpected drawing/blitting function" );
+ break;
+
+ }
+
+ sdev->dflags = state->drawingflags;
+ sdev->bflags = state->blittingflags;
+ sdev->render_options = state->render_options;
+ sdev->color = state->color;
+
+ /*
+ * 4) Clear modification flags
+ *
+ * All flags have been evaluated in 1) and remembered for further validation.
+ * If the hw independent state is not modified, this function won't get called
+ * for subsequent rendering functions, unless they aren't defined by 3).
+ */
+ state->mod_hw = 0;
+}
+
+/**********************************************************************************************************************/
+
+/*
+ * Render a filled rectangle using the current hardware state.
+ */
+bool
+sh7723FillRectangle( void *drv, void *dev, DFBRectangle *rect )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+ __u32 *prep = start_buffer( sdrv, 6 );
+
+ D_DEBUG_AT( SH7723_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__,
+ DFB_RECTANGLE_VALS( rect ) );
+ DUMP_INFO();
+
+ prep[0] = M2DG_OPCODE_BITBLTC | M2DG_DRAWMODE_CLIP;
+
+ if (sdev->dflags & DSDRAW_BLEND)
+ prep[0] |= M2DG_DRAWMODE_ALPHA;
+
+ prep[1] = 0xcc;
+ prep[2] = sdev->color16;
+ prep[3] = rect->w - 1;
+ prep[4] = rect->h - 1;
+ prep[5] = SH7723_XY( rect->x, rect->y );
+
+ submit_buffer( sdrv, 6 );
+
+ return true;
+}
+
+/**********************************************************************************************************************/
+
+/*
+ * Render rectangle outlines using the current hardware state.
+ */
+bool
+sh7723DrawRectangle( void *drv, void *dev, DFBRectangle *rect )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+ __u32 *prep = start_buffer(sdrv, 8 );
+
+ int x1, x2, y1, y2;
+
+ x1 = rect->x;
+ y1 = rect->y;
+ x2 = rect->x + rect->w - 1;
+ y2 = rect->y + rect->h - 1;
+
+ D_DEBUG_AT( SH7723_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__,
+ DFB_RECTANGLE_VALS( rect ) );
+ DUMP_INFO();
+
+ prep[0] = M2DG_OPCODE_LINE_C | M2DG_DRAWMODE_CLIP;
+
+ if (sdev->dflags & DSDRAW_BLEND)
+ prep[0] |= M2DG_DRAWMODE_ALPHA;
+
+ prep[1] = (sdev->color16 << 16 ) | 5;
+ prep[2] = 0;
+
+ prep[3] = SH7723_XY( x1, y1 );
+ prep[4] = SH7723_XY( x2, y1 );
+ prep[5] = SH7723_XY( x2, y2 );
+ prep[6] = SH7723_XY( x1, y2 );
+ prep[7] = SH7723_XY( x1, y1 );
+
+ submit_buffer( sdrv, 8 );
+
+ return true;
+}
+
+/**********************************************************************************************************************/
+
+/*
+ * Render a triangle using the current hardware state.
+ */
+bool
+sh7723FillTriangle( void *drv, void *dev, DFBTriangle *triangle )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+ __u32 *prep = start_buffer( sdrv, 6 );
+
+ D_DEBUG_AT( SH7723_BLT, "%s( %d, %d - %dx, %d - %d, %d )\n", __FUNCTION__,
+ DFB_TRIANGLE_VALS( triangle ) );
+ DUMP_INFO();
+
+ prep[0] = M2DG_OPCODE_POLYGON_4C | M2DG_DRAWMODE_CLIP;
+
+ if (sdev->dflags & DSDRAW_BLEND)
+ prep[0] |= M2DG_DRAWMODE_ALPHA;
+
+ prep[1] = sdev->color16;
+
+ prep[2] = SH7723_XY( triangle->x1, triangle->y1 );
+ prep[3] = SH7723_XY( triangle->x2, triangle->y2 );
+ prep[4] = SH7723_XY( triangle->x3, triangle->y3 );
+ prep[5] = SH7723_XY( triangle->x3, triangle->y3 );
+
+ submit_buffer( sdrv, 6 );
+
+ /*
+ * TODO: use rlined to draw the aa'ed outline of a polygon
+ * if also aval, set blke to 1
+ */
+
+
+
+ return true;
+}
+
+/**********************************************************************************************************************/
+
+/*
+ * Render a line with the specified width using the current hardware state.
+ */
+bool
+sh7723DrawLine( void *drv, void *dev, DFBRegion *line )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+ __u32 *prep = start_buffer( sdrv, 5 );
+
+ D_DEBUG_AT( SH7723_BLT, "%s( %d, %d - %d, %d )\n", __FUNCTION__,
+ line->x1, line->y1, line->x2, line->y2 );
+ DUMP_INFO();
+
+ prep[0] = M2DG_OPCODE_LINE_C | M2DG_DRAWMODE_CLIP;
+
+ if (sdev->render_options & DSRO_ANTIALIAS)
+ prep[0] |= M2DG_DRAWMODE_ANTIALIAS;
+
+ prep[1] = (sdev->color16 << 16) | 2;
+ prep[2] = 0;
+
+ prep[3] = SH7723_XY( line->x1, line->y1 );
+ prep[4] = SH7723_XY( line->x2, line->y2 );
+
+ submit_buffer( sdrv, 5);
+
+ return true;
+}
+
+/*
+ * Blit a rectangle using the current hardware state.
+ */
+bool
+sh7723Blit( void *drv, void *dev, DFBRectangle *rect, int dx, int dy )
+{
+ SH7722DriverData *sdrv = drv;
+ SH7722DeviceData *sdev = dev;
+ __u32 *prep = start_buffer( sdrv, 6 );
+
+ D_DEBUG_AT( SH7723_BLT, "%s( %d, %d - %dx%d <- %d, %d )\n", __FUNCTION__,
+ dx, dy, rect->w, rect->h, rect->x, rect->y );
+ DUMP_INFO();
+
+ prep[0] = M2DG_OPCODE_BITBLTA | M2DG_DRAWMODE_CLIP;
+
+ if (sdev->bflags & DSBLIT_BLEND_COLORALPHA)
+ prep[0] |= M2DG_DRAWMODE_ALPHA;
+
+ if (sdev->bflags & DSBLIT_SRC_COLORKEY)
+ prep[0] |= M2DG_DRAWMODE_STRANS;
+
+ if (sdev->src_phys == sdev->dst_phys) {
+ if (dy > rect->y)
+ prep[0] |= M2DG_DRAWMODE_DSTDIR_Y | M2DG_DRAWMODE_SRCDIR_Y;
+ else if (dy == rect->y) {
+ if (dx > rect->x)
+ prep[0] |= M2DG_DRAWMODE_DSTDIR_X | M2DG_DRAWMODE_SRCDIR_X;
+ }
+ }
+
+ prep[1] = 0xcc;
+ prep[2] = SH7723_XY( rect->x, rect->y );
+ prep[3] = rect->w - 1;
+ prep[4] = rect->h - 1;
+ prep[5] = SH7723_XY( dx, dy );
+
+ submit_buffer( sdrv, 6 );
+
+ return true;
+}
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7723_blt.h b/Source/DirectFB/gfxdrivers/sh772x/sh7723_blt.h
new file mode 100755
index 0000000..182c4b8
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/sh772x/sh7723_blt.h
@@ -0,0 +1,239 @@
+#ifndef __SH7723_BLT_H__
+#define __SH7723_BLT_H__
+
+#include <sys/ioctl.h>
+
+#include "sh7722_types.h"
+
+
+
+#define SH7723_SUPPORTED_DRAWINGFLAGS (DSDRAW_NOFX | DSDRAW_BLEND)
+
+#define SH7723_SUPPORTED_DRAWINGFUNCTIONS (DFXL_FILLRECTANGLE | \
+ DFXL_FILLTRIANGLE | \
+ DFXL_DRAWLINE | \
+ DFXL_DRAWRECTANGLE)
+
+#define SH7723_SUPPORTED_BLITTINGFLAGS (DSBLIT_BLEND_COLORALPHA | \
+ DSBLIT_SRC_COLORKEY)
+
+#define SH7723_SUPPORTED_BLITTINGFUNCTIONS (DFXL_BLIT)
+
+
+DFBResult sh7723EngineSync ( void *drv, void *dev );
+
+void sh7723EngineReset ( void *drv, void *dev );
+void sh7723FlushTextureCache( void *drv, void *dev );
+
+void sh7723EmitCommands ( void *drv, void *dev );
+
+void sh7723CheckState ( void *drv, void *dev,
+ CardState *state, DFBAccelerationMask accel );
+
+void sh7723SetState ( void *drv, void *dev,
+ GraphicsDeviceFuncs *funcs,
+ CardState *state, DFBAccelerationMask accel );
+
+bool sh7723FillRectangle ( void *drv, void *dev, DFBRectangle *rect );
+bool sh7723FillTriangle ( void *drv, void *dev, DFBTriangle *triangle );
+bool sh7723DrawRectangle ( void *drv, void *dev, DFBRectangle *rect );
+bool sh7723DrawLine ( void *drv, void *dev, DFBRegion *line );
+bool sh7723Blit ( void *drv, void *dev, DFBRectangle *rect, int dx, int dy );
+
+#define SH7723_S16S16(h,l) ((u32)((((u16)(h)) << 16) | ((u16)(l))))
+
+#define SH7723_XY(x,y) SH7723_S16S16(x,y)
+
+#define SH7723_TDG_BASE 0xA4680000
+
+//#define BEM_HC_DMA_START (SH7723_TDG_BASE + 0x00044)
+#define M2DG_SCLR (SH7723_TDG_BASE + 0x000)
+//#define BEM_HC_DMA_ADR (SH7723_TDG_BASE + 0x00040)
+#define M2DG_DLSAR (SH7723_TDG_BASE + 0x048)
+
+
+
+
+#define M2DG_OPCODE_TRAP 0x00000000
+#define M2DG_OPCODE_WPR 0x18000000
+#define M2DG_OPCODE_SYNC 0x12000000
+#define M2DG_OPCODE_LCOFS 0x40000000
+#define M2DG_OPCODE_MOVE 0x48000000
+#define M2DG_OPCODE_NOP 0x08000000
+#define M2DG_OPCODE_INTERRUPT 0x08008000
+#define M2DG_SYNC_TCLR 0x00000010
+
+#define M2DG_OPCODE_POLYGON_4C 0x80000000
+#define M2DG_OPCODE_LINE_C 0xB0000000
+#define M2DG_OPCODE_BITBLTA 0xA2000100
+#define M2DG_OPCODE_BITBLTC 0xA0000000
+
+#define M2DG_DRAWMODE_STRANS 0x00000800
+#define M2DG_DRAWMODE_CLIP 0x00002000
+#define M2DG_DRAWMODE_ANTIALIAS 0x00000002
+#define M2DG_DRAWMODE_ALPHA 0x00000002
+
+#define M2DG_DRAWMODE_SRCDIR_X 0x00000040
+#define M2DG_DRAWMODE_SRCDIR_Y 0x00000020
+#define M2DG_DRAWMODE_DSTDIR_X 0x00000010
+#define M2DG_DRAWMODE_DSTDIR_Y 0x00000008
+
+
+
+//ignore and replace
+#define BEM_WR_CTRL (0x00400)
+#define BEM_WR_V1 (0x00410)
+#define BEM_WR_V2 (0x00414)
+#define BEM_WR_FGC (0x00420)
+
+#define BEM_BE_CTRL (0x00800)
+#define BEM_BE_V1 (0x00810)
+#define BEM_BE_V2 (0x00814)
+#define BEM_BE_V3 (0x00818)
+#define BEM_BE_V4 (0x0081C)
+#define BEM_BE_COLOR1 (0x00820)
+#define BEM_BE_SRC_LOC (0x00830)
+#define BEM_BE_SRC_SIZE (0x00834)
+#define BEM_BE_MATRIX_A (0x00850)
+#define BEM_BE_MATRIX_B (0x00854)
+#define BEM_BE_MATRIX_C (0x00858)
+#define BEM_BE_MATRIX_D (0x0085C)
+#define BEM_BE_MATRIX_E (0x00860)
+#define BEM_BE_MATRIX_F (0x00864)
+#define BEM_BE_ORIGIN (0x00870)
+#define BEM_BE_SC_MIN (0x00880)
+#define BEM_BE_SC_MAX (0x00884)
+
+#define BEM_TE_SRC (0x00C00)
+#define BEM_TE_SRC_BASE (0x00C04)
+#define BEM_TE_SRC_SIZE (0x00C08)
+#define BEM_TE_SRC_CNV (0x00C0C)
+#define BEM_TE_MASK (0x00C10)
+#define BEM_TE_MASK_BASE (0x00C14)
+#define BEM_TE_MASK_SIZE (0x00C18)
+#define BEM_TE_MASK_CNV (0x00C1C)
+#define BEM_TE_ALPHA (0x00C28)
+#define BEM_TE_FILTER (0x00C30)
+#define BEM_TE_INVALID (0x00C40)
+
+#define BEM_PE_DST (0x01000)
+#define BEM_PE_DST_BASE (0x01004)
+#define BEM_PE_DST_SIZE (0x01008)
+#define BEM_PE_SC (0x0100C)
+#define BEM_PE_SC0_MIN (0x01010)
+#define BEM_PE_SC0_MAX (0x01014)
+#define BEM_PE_CKEY (0x01040)
+#define BEM_PE_CKEY_B (0x01044)
+#define BEM_PE_CKEY_A (0x01048)
+#define BEM_PE_COLORCHANGE (0x01050)
+#define BEM_PE_ALPHA (0x01058)
+#define BEM_PE_COLORCHANGE_0 (0x01060)
+#define BEM_PE_COLORCHANGE_1 (0x01064)
+#define BEM_PE_OPERATION (0x01080)
+#define BEM_PE_FIXEDALPHA (0x01084)
+#define BEM_PE_OFFSET (0x01088)
+#define BEM_PE_MASK (0x01094)
+#define BEM_PE_CACHE (0x010B0)
+
+/*
+ * BEM_BE_CTRL
+ */
+#define BE_FLIP_NONE 0x00000000
+#define BE_FLIP_HORIZONTAL 0x01000000
+#define BE_FLIP_VERTICAL 0x02000000
+#define BE_FLIP_BOTH 0x03000000
+
+#define BE_CTRL_FIXMODE_20_12 0x00000000
+#define BE_CTRL_FIXMODE_16_16 0x00100000
+#define BE_CTRL_CLIP 0x00080000
+#define BE_CTRL_ORIGIN 0x00040000
+#define BE_CTRL_ZOOM 0x00020000
+#define BE_CTRL_MATRIX 0x00010000
+
+#define BE_CTRL_SCANMODE_LINE 0x00000000
+#define BE_CTRL_SCANMODE_4x4 0x00001000
+#define BE_CTRL_SCANMODE_8x4 0x00002000
+
+#define BE_CTRL_BLTDIR_FORWARD 0x00000000
+#define BE_CTRL_BLTDIR_BACKWARD 0x00000100
+#define BE_CTRL_BLTDIR_AUTOMATIC 0x00000200
+
+#define BE_CTRL_TEXTURE 0x00000020
+#define BE_CTRL_QUADRANGLE 0x00000002
+#define BE_CTRL_RECTANGLE 0x00000001
+
+/*
+ * BEM_PE_OPERATION
+ */
+#define BLE_FUNC_NONE 0x00000000
+#define BLE_FUNC_AxB_plus_CxD 0x10000000
+#define BLE_FUNC_CxD_minus_AxB 0x20000000
+#define BLE_FUNC_AxB_minus_CxD 0x30000000
+
+#define BLE_ROP_XOR 0x01660000
+
+#define BLE_SRCA_FIXED 0x00000000
+#define BLE_SRCA_SOURCE_ALPHA 0x00001000
+#define BLE_SRCA_ALPHA_CHANNEL 0x00002000
+
+#define BLE_DSTA_FIXED 0x00000000
+#define BLE_DSTA_DEST_ALPHA 0x00000100
+
+#define BLE_SRCF_ZERO 0x00000000
+#define BLE_SRCF_ONE 0x00000010
+#define BLE_SRCF_DST 0x00000020
+#define BLE_SRCF_1_DST 0x00000030
+#define BLE_SRCF_SRC_A 0x00000040
+#define BLE_SRCF_1_SRC_A 0x00000050
+#define BLE_SRCF_DST_A 0x00000060
+#define BLE_SRCF_1_DST_A 0x00000070
+
+#define BLE_DSTO_DST 0x00000000
+#define BLE_DSTO_OFFSET 0x00000008
+
+#define BLE_DSTF_ZERO 0x00000000
+#define BLE_DSTF_ONE 0x00000001
+#define BLE_DSTF_SRC 0x00000002
+#define BLE_DSTF_1_SRC 0x00000003
+#define BLE_DSTF_SRC_A 0x00000004
+#define BLE_DSTF_1_SRC_A 0x00000005
+#define BLE_DSTF_DST_A 0x00000006
+#define BLE_DSTF_1_DST_A 0x00000007
+
+/*
+ * BEM_PE_CKEY
+ */
+#define CKEY_EXCLUDE_UNUSED 0x00100000
+#define CKEY_EXCLUDE_ALPHA 0x00010000
+#define CKEY_A_ENABLE 0x00000100
+#define CKEY_B_ENABLE 0x00000001
+
+/*
+ * BEM_PE_COLORCHANGE
+ */
+#define COLORCHANGE_DISABLE 0x00000000
+#define COLORCHANGE_COMPARE_FIRST 0x0000000b
+#define COLORCHANGE_EXCLUDE_UNUSED 0x00010000
+
+/*
+ * BEM_PE_MASK
+ */
+#define PE_MASK_DISABLE 0x00000000
+#define PE_MASK_COLOR 0x00000001
+#define PE_MASK_ALPHA 0x00000080
+
+/*
+ * BEM_TE_MASK
+ */
+#define TE_MASK_DISABLE 0x00000000
+#define TE_MASK_ENABLE 0x00010000
+
+/*
+ * BEM_WR_CTRL
+ */
+#define WR_CTRL_LINE 0x00000002
+#define WR_CTRL_POLYLINE 0x00000003
+#define WR_CTRL_ANTIALIAS 0x00020100
+#define WR_CTRL_ENDPOINT 0x00001000
+
+#endif