From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/gfxdrivers/sh772x/Makefile.am | 80 + Source/DirectFB/gfxdrivers/sh772x/Makefile.in | 726 +++++++ Source/DirectFB/gfxdrivers/sh772x/Makefile.kernel | 61 + Source/DirectFB/gfxdrivers/sh772x/README.sh7722 | 172 ++ .../DirectFB/gfxdrivers/sh772x/directfbrc.sh7722 | 10 + .../DirectFB/gfxdrivers/sh772x/directfbrc.sh7723 | 10 + .../gfxdrivers/sh772x/kernel-module/Makefile | 3 + .../gfxdrivers/sh772x/kernel-module/sh7722.c | 1192 ++++++++++++ .../gfxdrivers/sh772x/kernel-module/sh7722.h | 21 + .../gfxdrivers/sh772x/kernel-module/sh7723.c | 566 ++++++ .../gfxdrivers/sh772x/kernel-module/sh7723.h | 21 + .../sh772x/kernel-module/sh772x_driver.c | 82 + .../gfxdrivers/sh772x/kernel-module/sh772x_gfx.h | 105 + Source/DirectFB/gfxdrivers/sh772x/sh7722.c | 490 +++++ Source/DirectFB/gfxdrivers/sh772x/sh7722.h | 131 ++ Source/DirectFB/gfxdrivers/sh772x/sh7722_blt.c | 2013 ++++++++++++++++++++ Source/DirectFB/gfxdrivers/sh772x/sh7722_blt.h | 214 +++ Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeg.c | 395 ++++ Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeglib.c | 1654 ++++++++++++++++ Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeglib.h | 47 + .../DirectFB/gfxdrivers/sh772x/sh7722_jpegtool.c | 142 ++ Source/DirectFB/gfxdrivers/sh772x/sh7722_layer.c | 529 +++++ Source/DirectFB/gfxdrivers/sh772x/sh7722_layer.h | 11 + Source/DirectFB/gfxdrivers/sh772x/sh7722_lcd.c | 172 ++ Source/DirectFB/gfxdrivers/sh772x/sh7722_lcd.h | 17 + Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.c | 412 ++++ Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.h | 11 + Source/DirectFB/gfxdrivers/sh772x/sh7722_regs.h | 624 ++++++ Source/DirectFB/gfxdrivers/sh772x/sh7722_screen.c | 85 + Source/DirectFB/gfxdrivers/sh772x/sh7722_screen.h | 9 + Source/DirectFB/gfxdrivers/sh772x/sh7722_types.h | 136 ++ Source/DirectFB/gfxdrivers/sh772x/sh7723_blt.c | 890 +++++++++ Source/DirectFB/gfxdrivers/sh772x/sh7723_blt.h | 239 +++ 33 files changed, 11270 insertions(+) create mode 100755 Source/DirectFB/gfxdrivers/sh772x/Makefile.am create mode 100755 Source/DirectFB/gfxdrivers/sh772x/Makefile.in create mode 100755 Source/DirectFB/gfxdrivers/sh772x/Makefile.kernel create mode 100755 Source/DirectFB/gfxdrivers/sh772x/README.sh7722 create mode 100755 Source/DirectFB/gfxdrivers/sh772x/directfbrc.sh7722 create mode 100755 Source/DirectFB/gfxdrivers/sh772x/directfbrc.sh7723 create mode 100755 Source/DirectFB/gfxdrivers/sh772x/kernel-module/Makefile create mode 100755 Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7722.c create mode 100755 Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7722.h create mode 100755 Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7723.c create mode 100755 Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh7723.h create mode 100755 Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh772x_driver.c create mode 100755 Source/DirectFB/gfxdrivers/sh772x/kernel-module/sh772x_gfx.h create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722.c create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722.h create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_blt.c create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_blt.h create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeg.c create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeglib.c create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_jpeglib.h create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_jpegtool.c create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_layer.c create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_layer.h create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_lcd.c create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_lcd.h create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.c create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.h create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_regs.h create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_screen.c create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_screen.h create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722_types.h create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7723_blt.c create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7723_blt.h (limited to 'Source/DirectFB/gfxdrivers/sh772x') 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 + * + * + * 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + + +//#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 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( ¤t->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( ®, (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( ®, (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, ®, 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< + * + * + * 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 , + * Denis Oliver Kropp + * + * + * + * 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) +#include +#endif + +#include + + +//#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( ¤t->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( ®, (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( ®, (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, ®, 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< + * + * + * 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 + * + * + * 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 +#include + +#include +#include + +#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 & Janine Kropp " ); +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 + + +#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 +#include + +#undef HAVE_STDLIB_H + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +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 +#include +#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 + +#include + +#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, ® ) < 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, ® ) < 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, ® ) < 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, ® ) < 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 +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#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 + +#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 +#include + +#undef HAVE_STDLIB_H + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#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( 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef STANDALONE +#include "sh7722_jpeglib_standalone.h" +#else +#undef HAVE_STDLIB_H +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#endif + +#include +#include + +#include + +#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, ® ) < 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, ® ) < 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> 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; xx2 - 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 + +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 +#include +#include +#include +#include +#include +#include +#include + +#ifdef STANDALONE +#include "sh7722_jpeglib_standalone.h" +#else +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#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\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 + +#include + +#include + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#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 + +#include + +#include + +#include + +#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 + +#include + +#include + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#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 + +#include + +#include + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + + +#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 + +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 + +#include + + +#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 +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#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 + +#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 -- cgit