diff --git a/Makefile.in b/Makefile.in index ca02f3c..a897f86 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -37,7 +37,17 @@ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -103,16 +113,12 @@ POST_UNINSTALL = : @BUILD_DSP_FALSE@@BUILD_NAT_TRUE@am__append_3 = xrp-linux-native @BUILD_EXAMPLE_TRUE@am__append_4 = xrp-example subdir = . -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/configure $(am__configure_deps) README \ - autoconf/compile autoconf/depcomp autoconf/install-sh \ - autoconf/missing $(top_srcdir)/autoconf/compile \ - $(top_srcdir)/autoconf/install-sh \ - $(top_srcdir)/autoconf/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d @@ -174,6 +180,10 @@ ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = xrp-dsp xrp-linux-sim xrp-linux-native xrp-example +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/autoconf/compile \ + $(top_srcdir)/autoconf/install-sh \ + $(top_srcdir)/autoconf/missing README autoconf/compile \ + autoconf/depcomp autoconf/install-sh autoconf/missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -303,6 +313,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -331,7 +342,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -538,15 +548,15 @@ dist-xz: distdir $(am__post_remove_distdir) dist-tarZ: distdir - @echo WARNING: "Support for shar distribution archives is" \ - "deprecated." >&2 + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir - @echo WARNING: "Support for distribution archives compressed with" \ - "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) @@ -582,17 +592,17 @@ distcheck: dist esac chmod -R a-w $(distdir) chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_inst + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build \ - && ../configure \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=.. --prefix="$$dc_install_base" \ + --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ @@ -766,6 +776,8 @@ uninstall-am: maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + # 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. diff --git a/README.xrp_porting b/README.xrp_porting new file mode 100644 index 0000000..10d9323 --- /dev/null +++ b/README.xrp_porting @@ -0,0 +1,102 @@ +This README file defines what I have experimented so far w.r.t. porting xrp driver. + +Charles Qi 2/22/2018 + +1. clone XRP git repo +======================= +The DCT flow is built around git. To make changes to XRP code base, I forked the XRP +github repo to git@github.com:zhengstake/xrp.git and created a branch dct_port_0222. + +The local repo can be referenced from DCT flow by creating symbolic links to .git under +feeds/packages: + lede/feeds/sdip/sdip-xrp-application/git-src /.git + lede/feeds/sdip/sdip-xrp-driver/git-src /.git + +2. Code change +======================= +So far there are two main modifications. +under xrp-kernel, I have created xrp_hw_dct.c and xrp_hw_dct_dsp_interface.h for the +low level driver. The generic driver is not touched. The main changes are how the +MMIO field related to DSP control, IRQ handling are mapped and communicated. + +Unlike the simple HW driver, the DCT platform control regsisters are more spread out and +shared by many modules. Fields within the registers are also interleaved for different DSPs. +Please refer to DCT Platform PG for details: + a. the reset and runstall registgers are in SCU DSP control + b. the host <-> DSP IPI interrupts are in DSP control + +Currently on the host side, the acccess to the two MMIO regions are down through syscon regmap, +consistent with the existing IVP driver. Additionally, a device_mmio_base and offset to +IRQ control registers are defined in dts. DSP reset, runstall and IRQ send, ack routines are +modified in xrp_hw_dct.c. + +The new HW driver uses the cma binding, defining a shared reserve memory region in DDR for +ARM <=> DSP communication and data sharing. the 'reg' field in dts is not used. xrp_init_cma +in xrp_main.c is called by the HW driver at probe. + +reset and runstall are not used by Xtensa DSP code. So only DSP control base is included in +xrp_hw_dct_sync_data structure as device_mmio_base. + +On DSP side, a low level driver is derived from the simple driver. The code is under test-xrp/xrp_dsp_hw_dct.c. +The DCT platform uses a set of registers to control interrupts between ARM and DSP. These are +documented in the PG. The offset and bit locations of the registers are defined in dts and +passed to DSP in xrp_hw_dct_sync_data. Currently only set and clear registers are used to control IRQ singaling. +Further modification may be needed to include usage of mask registers. + +3.XRP driver and IVP driver co-existance +============================================ +The DCT platform uses an low level IVP driver to allow ARM host and Vision DSP to communicate. +Existing image/vision demos utilizes V4L2 streaming framework on top of IVP driver to +send video frames to DSP for processing. Then displays the processed frames. + +We'd like to preserve the IVP driver and V4L2 framework while integrate the XRP function. +The best approach is to integrate low-level HW driver function into the IVP driver. Then allow +both XRP generic driver and whatever on top of the XRP to communicate through the IVP driver. +This is considered a TBD Phase 2 effort. + +For initial integration, the plan is to split the 4 DSPs, two for IVP driver + V4L2, the other two +for XRP generic + HW driver. + +The split is shown in xrp-example/sdip-xrp.dtsi. + +The sdip-xrp.dtsi should be copied to +ede/build_dir/target-aarch64_cortex-a53+neon-vfpv4_musl-1.1.16/linux-sdip_sdip64/linux-4.9.47/arch/arm64/boot/dts/dct + +and included in sdip-v2.dts. + +The Linux target should be rebuild to utilize this new dts. + + +4. Integration of host side code to DCT flow +============================================ + +with help from Ralph, the latest XRP kernel module and host app have been integrated +into DCT flow. The package can be pulled for git server: + +./scripts/feeds update sdip +./scripts/feeds install -a -p sdip +make menuconfig +make -j8 + +Note: make menuconfig is used to select XRP driver and app under Xtensa tab. + +You can clean and compile these two modules with: +make package/sdip-xrp-application/clean V=s make package/sdip-xrp-application/compile V=s +make package/sdip-xrp-driver/clean V=s make package/sdip-xrp-driver/compile V=s + +If you setup the git-src symbolic link properly, you will be able to see the local code +being picked up under +lede/build_dir/target-aarch64_cortex-a53+neon-vfpv4_musl-1.1.16/sdip-xrp-application-2018-02-15 +lede/build_dir/target-aarch64_cortex-a53+neon-vfpv4_musl-1.1.16/linux-sdip_sdip64/sdip-xrp-driver-2018-02-15 + +respectively. + +5. Integration of DSP side code to DCT flow +============================================ +Xtensa side of XRP framework and driver code are integrated under +lede/build_dir/target-aarch64_cortex-a53+neon-vfpv4_musl-1.1.16/sdip-xtensa-2017-06-08/test-xrp. + +I created a cmake based flow to build the driver and framework into a sigle elf, using the LSP designed for +any test demos. + +The test_xrp directory is copied into dct_port_0222 branch just for completeness. diff --git a/aclocal.m4 b/aclocal.m4 index 9ce1375..f3cdf4c 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.14.1 -*- Autoconf -*- +# generated automatically by aclocal 1.15 -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2013 Free Software Foundation, Inc. +# Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.]) # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.14' +[am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.14.1], [], +m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.14.1])dnl +[AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Figure out how to run the assembler. -*- Autoconf -*- -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -78,7 +78,7 @@ _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -130,7 +130,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -161,7 +161,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -352,7 +352,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -428,7 +428,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -518,8 +518,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl @@ -593,6 +593,9 @@ END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not @@ -622,7 +625,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -633,7 +636,7 @@ echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_co # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh}" != xset; then +if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; @@ -643,7 +646,7 @@ if test x"${install_sh}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2013 Free Software Foundation, Inc. +# Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -664,7 +667,7 @@ AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -714,7 +717,7 @@ rm -f confinc confmf # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -753,7 +756,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -782,7 +785,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -829,7 +832,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -848,7 +851,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -929,7 +932,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2013 Free Software Foundation, Inc. +# Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -989,7 +992,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1017,7 +1020,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2013 Free Software Foundation, Inc. +# Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1036,7 +1039,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2013 Free Software Foundation, Inc. +# Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/rebuild.sh b/rebuild.sh new file mode 100755 index 0000000..588c408 --- /dev/null +++ b/rebuild.sh @@ -0,0 +1,31 @@ +#! /bin/bash -ex + +if [ "$1" = "-c" ] ; then RECONFIG=1 ; fi + +DIR=build-linux +[ -z "$RECONFIG" ] || ( rm -rf $DIR ; mkdir $DIR ; cd $DIR ; ../configure --prefix=`pwd`/root --disable-dsp --disable-sim --enable-example ) +make -C $DIR + +DIR=build-linux-sim +[ -z "$RECONFIG" ] || ( rm -rf $DIR ; mkdir $DIR ; cd $DIR ; ../configure --prefix=`pwd`/root --disable-dsp --enable-sim --enable-example ) +make -C build-linux-sim + +export PATH=/opt/xtensa/XtDevTools/install/tools/RG-2017.7-linux/XtensaTools/bin:$PATH +export XTENSA_CORE=visionp6cnn_ao_exls + +DIR=build-dsp +[ -z "$RECONFIG" ] || ( rm -rf $DIR ; mkdir $DIR ; cd $DIR ; ../configure --prefix=`pwd`/root --host=xtensa-elf --enable-dsp --disable-sim --enable-example DSP_CORE=visionp6cnn_ao_exls CC=xt-xcc ) +make -C $DIR \ + DSP_LSP=`pwd`/xrp-example/MW-MP/P6_0/xtensa-elf/lib/sim-stacklocal + +DIR=build-dsp-sim +[ -z "$RECONFIG" ] || ( rm -rf $DIR ; mkdir $DIR ; cd $DIR ; ../configure --prefix=`pwd`/root --host=xtensa-elf --enable-dsp --enable-sim --enable-example DSP_CORE=visionp6cnn_ao_exls CC=xt-xcc ) +make -C $DIR \ + DSP_LSP=`pwd`/xrp-example/MW-MP/P6_0/xtensa-elf/lib/sim-stacklocal \ + DSP_COMM_BASE=0xf0000000 +mv $DIR/xrp-example/xrp-dsp-sim{,0} + +make -C $DIR \ + DSP_LSP=`pwd`/xrp-example/MW-MP/P6_1/xtensa-elf/lib/sim-stacklocal \ + DSP_COMM_BASE=0xf4000000 +mv $DIR/xrp-example/xrp-dsp-sim{,1} diff --git a/run_dsp b/run_dsp new file mode 100755 index 0000000..bfa3e1c --- /dev/null +++ b/run_dsp @@ -0,0 +1,6 @@ +$XTENSA_TOOLS/bin/xtsc-run --xtensa-system=$XTENSA_TOOLS/config \ + --set_xtsc_parm=turbo=true \ + --define=P6_0_BINARY=build-dsp-sim/xrp-example/xrp-dsp-sim0 \ + --define=P6_1_BINARY=build-dsp-sim/xrp-example/xrp-dsp-sim1 \ + --include=./xrp-example/MW-MP/sim/xtsc-run/SubSystem.inc + diff --git a/run_host b/run_host new file mode 100755 index 0000000..eb6f0b1 --- /dev/null +++ b/run_host @@ -0,0 +1 @@ +./build-linux-sim/xrp-example/xrp-linux-sim diff --git a/test-xrp/CMakeLists.txt b/test-xrp/CMakeLists.txt new file mode 100644 index 0000000..3a0a666 --- /dev/null +++ b/test-xrp/CMakeLists.txt @@ -0,0 +1,104 @@ +cmake_minimum_required(VERSION 2.6) + +project(test-xrp) + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_VERSION 1) + +add_definitions(-Wall -Wmissing-declarations -Wextra) + +set(NAME "test-xrp") +set(CORENAME VP6_DCT_PROD_200) +set(SYSUPGRADE "sysupgrade-sdipv2") + +set(CMAKE_C_FLAGS_DEBUG "-O0 -DDEBUG") +set(CMAKE_CXX_FLAGS_DEBUG "-O0 -DDEBUG") +set(CMAKE_C_FLAGS_RELEASE "-Os -DNDEBUG") +set(CMAKE_CXX_FLAGS_RELEASE "-Os -DNDEBUG") + +set(CMAKE_EXE_LINKER_FLAGS "-lhal -mlsp=${CMAKE_CURRENT_BINARY_DIR}/sdip-lsp") +set(CMAKE_C_COMPILER_ARG1 --xtensa-core=${CORENAME}) +set(CMAKE_CXX_COMPILER_ARG1 --xtensa-core=${CORENAME}) + +set(LSP_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sdip-lsp/) +set(LSP_INPUT min-rt) + +include(GNUInstallDirs) + +if (NOT SUPER_BUILD) + include_directories("${CMAKE_SOURCE_DIR}/../bsp") + link_directories("${CMAKE_SOURCE_DIR}/../bsp/build") +endif () + +if (NOT CMAKE_BUILD_TYPE) + message(STATUS "${NAME}: No build type selected, default to Debug") + set(CMAKE_BUILD_TYPE "Debug") +endif() + +set(${NAME}-SOURCES dsp_main.c xrp_dsp.c xrp_dsp_hw_dct.c) + +add_executable(${NAME}.elf ${${NAME}-SOURCES}) + +target_link_libraries(${NAME}.elf LINK_PUBLIC bsp) + +add_custom_command( + OUTPUT ivp.iram.bin ivp.dram.bin ivp.lmem.bin sdipv2-${NAME}-upgrade.tar.gz ${NAME}.bin ${SYSUPGRADE} + + COMMAND xt-objcopy -R .data -R .bss -R .rodata -R .text -R .sram.data -O binary ${NAME}.elf ivp.iram.bin + COMMAND xt-objcopy -j .data -j .bss -j .rodata -O binary ${NAME}.elf ivp.dram.bin + COMMAND xt-objcopy -j .text -j .sram.data -O binary ${NAME}.elf ivp.lmem.bin + + COMMAND dd if=ivp.dram.bin of=ivp.dram.bin.new bs=8 conv=sync + COMMAND dd if=ivp.iram.bin of=ivp.iram.bin.new bs=8 conv=sync + COMMAND dd if=ivp.lmem.bin of=ivp.lmem.bin.new bs=8 conv=sync + + COMMAND mv ivp.dram.bin.new ivp.dram.bin + COMMAND mv ivp.iram.bin.new ivp.iram.bin + COMMAND mv ivp.lmem.bin.new ivp.lmem.bin + + COMMAND dd if=ivp.dram.bin of=${NAME}.dram.img bs=524288 conv=sync + COMMAND dd if=ivp.iram.bin of=${NAME}.iram.img bs=31744 conv=sync + COMMAND dd if=ivp.lmem.bin of=${NAME}.lmem.img bs=524288 conv=sync + COMMAND dd if=/dev/zero of=header.img bs=1024 count=1 conv=sync + + COMMAND cat ${NAME}.dram.img > ${NAME}.bin + COMMAND cat header.img >> ${NAME}.bin + COMMAND cat ${NAME}.iram.img >> ${NAME}.bin + COMMAND cat ${NAME}.lmem.img >> ${NAME}.bin + + COMMAND mkdir -p ${SYSUPGRADE} && cp ${NAME}.bin ${SYSUPGRADE}/ivp + COMMAND tar czf sdipv2-${NAME}-upgrade.tar.gz ${SYSUPGRADE}/ivp + + COMMAND rm *.img + COMMAND xt-size ${NAME}.elf + COMMAND xt-size --format=sysv -x ${NAME}.elf + DEPENDS ${NAME}.elf + ) + +add_custom_target(${NAME}-bin ALL + DEPENDS ivp.iram.bin ivp.dram.bin ivp.lmem.bin + ) + +add_custom_command( + OUTPUT ${NAME}.lst + COMMAND xt-objdump -h -S ${NAME}.elf > ${NAME}.lst + DEPENDS ${NAME}.elf + ) + +add_custom_target(${NAME}-disassemble + DEPENDS ${NAME}.lst + ) + +add_custom_command( + OUTPUT ${LSP_OUTPUT} + COMMAND mkdir -p ${LSP_OUTPUT} && cp -vr ${CMAKE_CURRENT_SOURCE_DIR}/${LSP_INPUT}/* ${LSP_OUTPUT}/ + COMMAND xt-genldscripts -v -b ${LSP_OUTPUT}/ + + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${LSP_INPUT}/specs ${CMAKE_CURRENT_SOURCE_DIR}/${LSP_INPUT}/memmap.xmm + ) + +add_custom_target(${NAME}-lsp + DEPENDS ${LSP_OUTPUT} + ) + +add_dependencies(${NAME}.elf ${NAME}-lsp) diff --git a/test-xrp/dsp_main.c b/test-xrp/dsp_main.c new file mode 100644 index 0000000..807fc9b --- /dev/null +++ b/test-xrp/dsp_main.c @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2016 - 2017 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include "xrp_api.h" +#include "xrp_dsp_hw.h" +#include "example_namespace.h" + +static void hang(void) __attribute__((noreturn)); +static void hang(void) +{ + for (;;); +} + +void abort(void) +{ + fprintf(stderr, "abort() is called; halting\n"); + hang(); +} + +static void exception(void) +{ + unsigned long exccause, excvaddr, ps, epc1; + + __asm__ volatile ("rsr %0, exccause\n\t" + "rsr %1, excvaddr\n\t" + "rsr %2, ps\n\t" + "rsr %3, epc1" + : "=a"(exccause), "=a"(excvaddr), + "=a"(ps), "=a"(epc1)); + + fprintf(stderr, "%s: EXCCAUSE = %ld, EXCVADDR = 0x%08lx, PS = 0x%08lx, EPC1 = 0x%08lx\n", + __func__, exccause, excvaddr, ps, epc1); + hang(); +} + +static void register_exception_handlers(void) +{ + static const int cause[] = { + EXCCAUSE_ILLEGAL, + EXCCAUSE_INSTR_ERROR, + EXCCAUSE_LOAD_STORE_ERROR, + EXCCAUSE_DIVIDE_BY_ZERO, + EXCCAUSE_PRIVILEGED, + EXCCAUSE_UNALIGNED, + EXCCAUSE_INSTR_DATA_ERROR, + EXCCAUSE_LOAD_STORE_DATA_ERROR, + EXCCAUSE_INSTR_ADDR_ERROR, + EXCCAUSE_LOAD_STORE_ADDR_ERROR, + EXCCAUSE_ITLB_MISS, + EXCCAUSE_ITLB_MULTIHIT, + EXCCAUSE_INSTR_RING, + EXCCAUSE_INSTR_PROHIBITED, + EXCCAUSE_DTLB_MISS, + EXCCAUSE_DTLB_MULTIHIT, + EXCCAUSE_LOAD_STORE_RING, + EXCCAUSE_LOAD_PROHIBITED, + EXCCAUSE_STORE_PROHIBITED, + }; + unsigned i; + + for (i = 0; i < sizeof(cause) / sizeof(cause[0]); ++i) { + _xtos_set_exception_handler(cause[i], exception); + } +} + +void xrp_run_command(const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group, + enum xrp_status *status) +{ + (void)in_data; + (void)in_data_size; + (void)out_data; + (void)out_data_size; + (void)buffer_group; + printf("%s\n", __func__); + if (status) + *status = XRP_STATUS_SUCCESS; +} + +static enum xrp_status example_v1_handler(void *handler_context, + const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group) +{ + size_t i; + uint32_t sz = 0; + + (void)handler_context; + printf("%s, in_data_size = %zu, out_data_size = %zu\n", + __func__, in_data_size, out_data_size); + + for (i = 0; i < in_data_size; ++i) { + if (i < out_data_size) + ((uint8_t *)out_data)[i] = + ((uint8_t *)in_data)[i] + i; + } + + if (in_data_size >= sizeof(sz)) + memcpy(&sz, in_data, sizeof(sz)); + + for (i = 0; sz; i += 2) { + struct xrp_buffer *sbuf = xrp_get_buffer_from_group(buffer_group, i, NULL); + struct xrp_buffer *dbuf = xrp_get_buffer_from_group(buffer_group, i + 1, NULL); + void *src, *dst; + + if (!sbuf || !dbuf) + break; + + src = xrp_map_buffer(sbuf, 0, sz, XRP_READ, NULL); + dst = xrp_map_buffer(dbuf, 0, sz, XRP_WRITE, NULL); + + if (!src || !dst) { + xrp_release_buffer(sbuf, NULL); + xrp_release_buffer(dbuf, NULL); + break; + } + + printf("%s: copy %d bytes from %p to %p\n", + __func__, sz, src, dst); + memcpy(dst, src, sz); + xrp_unmap_buffer(sbuf, src, NULL); + xrp_unmap_buffer(dbuf, dst, NULL); + xrp_release_buffer(sbuf, NULL); + xrp_release_buffer(dbuf, NULL); + } + return XRP_STATUS_SUCCESS; +} + +static enum xrp_status example_v2_handler(void *handler_context, + const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group) +{ + const struct example_v2_cmd *cmd = in_data; + + (void)handler_context; + (void)out_data; + (void)out_data_size; + (void)buffer_group; + + if (in_data_size < sizeof(*cmd)) { + return XRP_STATUS_FAILURE; + } + switch (cmd->cmd) { + case EXAMPLE_V2_CMD_OK: + return XRP_STATUS_SUCCESS; + case EXAMPLE_V2_CMD_FAIL: + return XRP_STATUS_FAILURE; + default: + return XRP_STATUS_FAILURE; + } +} + +static enum xrp_status test_ns(struct xrp_device *device) +{ + enum xrp_status status; + char test_nsid[16][XRP_NAMESPACE_ID_SIZE]; + size_t i; + + for (i = 0; i < sizeof(test_nsid) / sizeof(test_nsid[0]); ++i) { + size_t j; + + for (j = 0; j < XRP_NAMESPACE_ID_SIZE; ++j) { + test_nsid[i][j] = rand(); + } + } + for (i = 0; i < sizeof(test_nsid) / sizeof(test_nsid[0]); ++i) { + xrp_device_register_namespace(device, test_nsid[i], + NULL, NULL, &status); + if (status != XRP_STATUS_SUCCESS) { + printf("xrp_register_namespace failed\n"); + return XRP_STATUS_FAILURE; + } + } + for (i = 0; i < sizeof(test_nsid) / sizeof(test_nsid[0]); ++i) { + xrp_device_unregister_namespace(device, test_nsid[i], + &status); + if (status != XRP_STATUS_SUCCESS) { + printf("xrp_unregister_namespace failed\n"); + return XRP_STATUS_FAILURE; + } + } + return XRP_STATUS_SUCCESS; +} + +int main(void) +{ + enum xrp_status status; + struct xrp_device *device; + + register_exception_handlers(); + device = xrp_open_device(0, &status); + if (status != XRP_STATUS_SUCCESS) { + printf("xrp_open_device failed\n"); + return 1; + } + status = test_ns(device); + if (status != XRP_STATUS_SUCCESS) { + printf("test_ns failed\n"); + return 1; + } + xrp_device_register_namespace(device, XRP_EXAMPLE_V1_NSID, + example_v1_handler, NULL, &status); + if (status != XRP_STATUS_SUCCESS) { + printf("xrp_register_namespace for XRP_EXAMPLE_V1_NSID failed\n"); + return 1; + } + xrp_device_register_namespace(device, XRP_EXAMPLE_V2_NSID, + example_v2_handler, NULL, &status); + if (status != XRP_STATUS_SUCCESS) { + printf("xrp_register_namespace for XRP_EXAMPLE_V2_NSID failed\n"); + return 1; + } + for (;;) { + status = xrp_device_dispatch(device); + if (status == XRP_STATUS_PENDING) + xrp_hw_wait_device_irq(); + } + return 0; +} diff --git a/test-xrp/example_namespace.h b/test-xrp/example_namespace.h new file mode 100644 index 0000000..4833931 --- /dev/null +++ b/test-xrp/example_namespace.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _EXAMPLE_NAMESPACE_H +#define _EXAMPLE_NAMESPACE_H + +#define XRP_EXAMPLE_V1_NSID_INITIALIZER \ + {0x47, 0xf4, 0x5d, 0x8c, 0x99, 0xc5, 0x11, 0xe7, \ + 0xb5, 0x86, 0x00, 0x21, 0xcc, 0x4a, 0x5f, 0xb6} +#define XRP_EXAMPLE_V1_NSID (unsigned char [])XRP_EXAMPLE_V1_NSID_INITIALIZER + +#define XRP_EXAMPLE_V2_NSID_INITIALIZER \ + {0x33, 0x56, 0xfc, 0x3c, 0x63, 0x27, 0x40, 0x96, \ + 0x8a, 0x33, 0x1a, 0x5c, 0xca, 0x3b, 0xa1, 0x64} +#define XRP_EXAMPLE_V2_NSID (unsigned char [])XRP_EXAMPLE_V2_NSID_INITIALIZER + +enum { + EXAMPLE_V2_CMD_OK, + EXAMPLE_V2_CMD_FAIL, +}; + +struct example_v2_cmd { + uint32_t cmd; +}; + +struct example_v2_rsp { +}; + +#endif diff --git a/test-xrp/lsp/sdip.map b/test-xrp/lsp/sdip.map new file mode 100644 index 0000000..fbf60de --- /dev/null +++ b/test-xrp/lsp/sdip.map @@ -0,0 +1,4 @@ +BEGIN lmem +0x01000000: sysram : lmem : 0x200000 : writable; + lram0 : C : 0x01000000 - 0x011fffff : .lram0.bss; +END lmem diff --git a/test-xrp/lsp/sdip.parms b/test-xrp/lsp/sdip.parms new file mode 100644 index 0000000..5a7cb93 --- /dev/null +++ b/test-xrp/lsp/sdip.parms @@ -0,0 +1,4 @@ +PLACE SECTIONS(STACK) WITH_SECTION(.dram0.bss) +PLACE SECTIONS(HEAP) WITH_SECTION(.dram0.bss) +PLACE SECTIONS(.data) WITH_SECTION(.dram0.bss) +PLACE SECTIONS(.bss) WITH_SECTION(.dram0.bss) diff --git a/test-xrp/min-rt/memmap.xmm b/test-xrp/min-rt/memmap.xmm new file mode 100644 index 0000000..c285a80 --- /dev/null +++ b/test-xrp/min-rt/memmap.xmm @@ -0,0 +1,52 @@ +VECSELECT=1 +VECBASE=0xd0000400 + +PLACE SECTIONS(.bss) WITH_SECTION(.dram1.bss) +PLACE SECTIONS(.data) WITH_SECTION(.dram1.data) +PLACE SECTIONS(.rodata) WITH_SECTION(.dram1.rodata) +PLACE SECTIONS(STACK) WITH_SECTION(.dram1.bss) +PLACE SECTIONS(HEAP) WITH_SECTION(.dram1.bss) + +BEGIN dram1 +0xcff80000: dataRam : dram1 : 0x40000 : writable; + dram1_0 : C : 0xcff80000 - 0xcffbffff : STACK : HEAP : .dram1.rodata .rodata .dram1.literal .dram1.data .data .dram1.bss .bss; +END dram1 + +BEGIN dram0 +0xcffc0000: dataRam : dram0 : 0x40000 : writable; + dram0_0 : C : 0xcffc0000 - 0xcfffffff : .dram0.rodata .dram0.literal .dram0.data .dram0.bss; +END dram0 + +BEGIN iram0 +0xd0000000: instRam : iram0 : 0x8000 : executable, writable; + iram0_00 : C : 0xd0000000 - 0xd00003ff : ; + iram0_01 : F : 0xd0000400 - 0xd0000577 : .WindowVectors.text; + iram0_02 : C : 0xd0000578 - 0xd000057f : .Level2InterruptVector.literal; + iram0_03 : F : 0xd0000580 - 0xd00005b7 : .Level2InterruptVector.text; + iram0_04 : C : 0xd00005b8 - 0xd00005bf : .DebugExceptionVector.literal; + iram0_05 : F : 0xd00005c0 - 0xd00005f7 : .DebugExceptionVector.text; + iram0_06 : C : 0xd00005f8 - 0xd00005ff : .NMIExceptionVector.literal; + iram0_07 : F : 0xd0000600 - 0xd0000637 : .NMIExceptionVector.text; + iram0_08 : C : 0xd0000638 - 0xd000063f : .KernelExceptionVector.literal; + iram0_09 : F : 0xd0000640 - 0xd0000677 : .KernelExceptionVector.text; + iram0_10 : C : 0xd0000678 - 0xd000067f : .UserExceptionVector.literal; + iram0_11 : F : 0xd0000680 - 0xd00006b7 : .UserExceptionVector.text; + iram0_12 : C : 0xd00006b8 - 0xd00006ff : .DoubleExceptionVector.literal; + iram0_13 : F : 0xd0000700 - 0xd000073f : .DoubleExceptionVector.text; + iram0_14 : F : 0xd0000740 - 0xd0000a3f : .ResetVector.text; + iram0_15 : C : 0xd0000a40 - 0xd0007fff : .iram0.literal .iram0.text; +END iram0 + +BEGIN srom +0xd0080000: sysrom : srom : 0x1000000 : executable; + srom0 : C : 0xd0080000 - 0xd107ffff : .srom.rodata .srom.literal .srom.text .rom.store; +END srom + +BEGIN sram +0xe0000000: sysram : sram : 0x20000000 : executable, writable; +END sram + +BEGIN lmem +0x01180000: sysram : lmem : 0x80000 : executable, writable; + lmem0 : C : 0x01180000 - 0x011fffff : .sram.rodata .sram.literal .sram.text .sram.data .literal .text .sram.bss; +END lmem diff --git a/test-xrp/min-rt/specs b/test-xrp/min-rt/specs new file mode 100644 index 0000000..38f4a7e --- /dev/null +++ b/test-xrp/min-rt/specs @@ -0,0 +1,36 @@ +# Customer ID=12289; Build=0x65b6c; Copyright (c) 2001-2015 Cadence Design Systems, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +# The %O suffix on the start and end files indicates that the system's +# standard suffix for object files (e.g., ".o") should be appended. +# The %s suffix tells the compiler driver to search for the file in the +# list of known locations for startfiles. + +*startfile: +crt1-boards%O%s crti%O%s crtbegin%O%s _sharedvectors%O%s _vectors%O%s + +*endfile: +crtend%O%s crtn%O%s + +*lib: +-lc -lgloss -lminrt -lc -lhandler-reset -lhandlers-board -lminrt -lhal -lc -lidma + diff --git a/test-xrp/xrp_api.h b/test-xrp/xrp_api.h new file mode 100644 index 0000000..95a90e8 --- /dev/null +++ b/test-xrp/xrp_api.h @@ -0,0 +1,494 @@ +/* + * Copyright (c) 2016 - 2017 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _XRP_API_H +#define _XRP_API_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * User API. + */ + +struct xrp_device; +struct xrp_queue; +struct xrp_buffer; +struct xrp_buffer_group; +struct xrp_event; + +enum xrp_status { + XRP_STATUS_SUCCESS, + XRP_STATUS_FAILURE, + XRP_STATUS_PENDING, +}; +enum xrp_access_flags { + XRP_READ = 0x1, + XRP_WRITE = 0x2, + XRP_READ_WRITE = 0x3, +}; +enum xrp_buffer_info { + XRP_BUFFER_SIZE_SIZE_T, + XRP_BUFFER_HOST_POINTER_PTR, +}; +enum xrp_buffer_group_info { + XRP_BUFFER_GROUP_BUFFER_FLAGS_ENUM, +}; + +#define XRP_NAMESPACE_ID_SIZE 16 + +/* + * General notes: + * - all status pointers can be NULL; + * - reference counting is not meant to work across host/DSP boundary, i.e. + * DSP may not retain the host buffer; + * - a buffer allocated for one device can be passed as command parameter to + * a different device; implementation should do reasonable thing, e.g. use + * the original data if possible or transparently migrate it to suitable + * memory; + * - a group of API calls may be host side only, DSP side only, or usable on + * both sides. When it's usable on both sides there may be additional + * restrictions on the DSP side. + */ + +/* + * Device API. + */ + +/* + * Open device by index. + * A device is reference counted and is opened with reference count of 1. + * Devices are numbered sequentially starting at 0, they can be probed with + * simple loop. + */ +struct xrp_device *xrp_open_device(int idx, enum xrp_status *status); + +/* + * Increment device reference count. + */ +void xrp_retain_device(struct xrp_device *device, enum xrp_status *status); + +/* + * Decrement device reference count (and free associated resources once the + * counter gets down to zero). + */ +void xrp_release_device(struct xrp_device *device, enum xrp_status *status); + + +/* + * Buffer API. + * Available on both host and DSP side. + */ + +/* + * Create memory buffer and allocate device-specific storage (host_ptr == NULL) + * or use host buffer (host_ptr != NULL, treated as virtual address in the + * current process). + * A buffer is reference counted and is created with reference count of 1. + */ +struct xrp_buffer *xrp_create_buffer(struct xrp_device *device, + size_t size, void *host_ptr, + enum xrp_status *status); + +/* + * Increment buffer reference count. + */ +void xrp_retain_buffer(struct xrp_buffer *buffer, enum xrp_status *status); + +/* + * Decrement buffer reference count (and free the storage if it was allocated + * once the counter gets down to zero). + */ +void xrp_release_buffer(struct xrp_buffer *buffer, enum xrp_status *status); + +/* + * Map subbuffer of the buffer. Buffer may be mapped multiple times. + * + * \param map_flags: access to the mapping requested by the mapper. Access + * to buffers on DSP side is subject to restrictions set by the host side. + */ +void *xrp_map_buffer(struct xrp_buffer *buffer, size_t offset, size_t size, + enum xrp_access_flags map_flags, enum xrp_status *status); + +/* + * Unmap previously mapped buffer. + */ +void xrp_unmap_buffer(struct xrp_buffer *buffer, void *p, + enum xrp_status *status); + +/* + * Get information about the buffer object. + * + * \param info: information type to retrieve. + * \param out: pointer to return information to. + * \param out_sz: size of out buffer. + */ +void xrp_buffer_get_info(struct xrp_buffer *buffer, enum xrp_buffer_info info, + void *out, size_t out_sz, enum xrp_status *status); + + +/* + * Buffer group API. + * Available on both host and DSP side. + */ + +/* + * Create a group of shared buffers. Group is reference counted and is + * created with reference count of 1. + */ +struct xrp_buffer_group *xrp_create_buffer_group(enum xrp_status *status); + +/* + * Increment buffer group reference count. + */ +void xrp_retain_buffer_group(struct xrp_buffer_group *group, + enum xrp_status *status); + +/* + * Decrement group reference count (and free it once the counter gets down + * to zero). + */ +void xrp_release_buffer_group(struct xrp_buffer_group *group, + enum xrp_status *status); + +/* + * Add buffer to the group and get its index. + * This adds a reference to the buffer. + * + * \param access_flags: granted access. User of the buffer on the DSP side + * will be able to map it only for this type of access. + */ +size_t xrp_add_buffer_to_group(struct xrp_buffer_group *group, + struct xrp_buffer *buffer, + enum xrp_access_flags access_flags, + enum xrp_status *status); + +/* + * Put new buffer to the existing index in the group. + * When operation succeeds it releases the buffer previously contained at + * that index and adds a reference to the new buffer. + * + * \param access_flags: granted access. User of the buffer on the DSP side + * will be able to map it only for this type of access. + */ +void xrp_set_buffer_in_group(struct xrp_buffer_group *group, + size_t index, + struct xrp_buffer *buffer, + enum xrp_access_flags access_flags, + enum xrp_status *status); + +/* + * Get buffer from the group by its index. + * Buffer must be freed with release_buffer. + */ +struct xrp_buffer *xrp_get_buffer_from_group(struct xrp_buffer_group *group, + size_t idx, + enum xrp_status *status); + +/* + * Get information about the buffer group object. + * + * \param info: information type to retrieve. + * \param idx: buffer index (if applicable). + * \param out: pointer to return information to. + * \param out_sz: size of out buffer. + */ +void xrp_buffer_group_get_info(struct xrp_buffer_group *group, + enum xrp_buffer_group_info info, size_t idx, + void *out, size_t out_sz, + enum xrp_status *status); + + +/* + * Queue API. + */ + +/* + * Create queue to the default namespace of the device. + * Queue is an ordered device communication channel. Queue is reference + * counted and is created with reference count of 1. + */ +struct xrp_queue *xrp_create_queue(struct xrp_device *device, + enum xrp_status *status); + +/* + * Create queue to the specified namespace of the device. + * Queue is an ordered device communication channel. Queue is reference + * counted and is created with reference count of 1. + */ +struct xrp_queue *xrp_create_ns_queue(struct xrp_device *device, + const void *nsid, + enum xrp_status *status); + +/* + * Increment queue reference count. + */ +void xrp_retain_queue(struct xrp_queue *queue, + enum xrp_status *status); + +/* + * Decrement queue reference count (and free it once the counter gets down + * to zero). + */ +void xrp_release_queue(struct xrp_queue *queue, + enum xrp_status *status); + + +/* + * Event API. + */ + +/* + * Increment event reference count. + */ +void xrp_retain_event(struct xrp_event *event, + enum xrp_status *status); + +/* + * Decrement event reference count (and free it once the counter gets down + * to zero). + */ +void xrp_release_event(struct xrp_event *event, + enum xrp_status *status); + + +/* + * Get status of the event/associated command. + * The function may be called at any time, it sets *status to + * XRP_STATUS_PENDING if the command has not been executed yet, or to the + * command execution status. See status description of xrp_run_command_sync + * for the description of command execution status. + */ +void xrp_event_status(struct xrp_event *event, enum xrp_status *status); + +/* + * Communication API. + */ + +/* + * Even more internal API related to command passing between cores. + * These are tightly coupled to the host-DSP communication model and + * are likely to be changed/enhanced as the model evolves. + */ + +/* + * When this is invoked on the host it synchronously runs a command on DSP, + * passing a group of shared buffers and two additional (small) buffers + * with opaque command description (in_data) and results (out_data). + * + * in_data is used at the function call and is not referenced afterwards. + * out_data is updated with the value returned by DSP before the function + * returns. + * + * Optimal processing is guaranteed for in_data and out_data buffers not + * exceeding 16 bytes in size. Larger buffers may require additional data + * copying depending on the implementation. + * + * All buffers in the passed group must be unmapped at that point. + * + * status is the result of command execution. Command execution is + * successfull if the command was delivered to the DSP and the response was + * delivered back. Otherwise the command execution is failed. IOW execution + * success means that the out_data contains command-specific response received + * from the DSP, execution failure means that out_data does not contain useful + * information. + */ +void xrp_run_command_sync(struct xrp_queue *queue, + const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group, + enum xrp_status *status); + +/* + * When this is invoked on the host it queues a command to DSP, + * passing a group of shared buffers and two additional (small) buffers + * with opaque command description (in_data) and results (out_data). + * + * in_data is used at the function call and is not referenced afterwards. + * out_data must stay valid after this function call until command completion, + * at which point it is updated with the value returned by DSP. + * + * Optimal processing is guaranteed for in_data and out_data buffers not + * exceeding 16 bytes in size. Larger buffers may require additional data + * copying depending on the implementation. + * + * All buffers in the passed group must be unmapped at that point. + * + * If event is non-NULL then a pointer to an event corresponding to the + * queued command is returned. This event can be waited for with xrp_wait, + * it is signaled when the command execution is complete. + * The returned event object is reference counted and is created with + * reference count of 1. + * + * status is the result of command enqueuing. Command enqueuing is + * successfull if the command was enqueued on the host side and an associated + * event has been returned (if requested). Otherwise the command execution is + * failed. IOW enqueuing success means that if event is non-NULL then *event + * contains valid event, enqueuing failure means that *event does not contain + * useful information. + */ +void xrp_enqueue_command(struct xrp_queue *queue, + const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group, + struct xrp_event **event, + enum xrp_status *status); + +/* + * Wait for the event. + * Waiting for already signaled event completes immediately. + * Successful completion of this function does not alter the event state, + * i.e. the event remains signaled. + * status is the result of waiting, not the result of the command execution. + * Use xrp_event_status to get the command execution status. + */ +void xrp_wait(struct xrp_event *event, enum xrp_status *status); + + +/* New DSP-specific interface (library-style) */ + +/* + * Check if there's a command from the host in the hardware queue. + * Returns XRP_STATUS_PENDING if the queue is empty or XRP_STATUS_SUCCESS + * if there is a command ready for processing. + * + * The check is quick and may be issued in any context. + */ +enum xrp_status xrp_device_poll(struct xrp_device *device); + +/* + * Check if there's a command from the host in the hardware queue and invoke + * command handler if there's one. + * Returns XRP_STATUS_PENDING if the queue is empty, or the status returned by + * the command handler. + */ +enum xrp_status xrp_device_dispatch(struct xrp_device *device); + +/* + * Function type for command handler. + * + * This callback is called on the DSP side to process queued command. + * in_data, out_data and buffer_group correspond to the same parameters of the + * host side API calls. + * + * On return from this function buffer group and individual buffer reference + * counters shall be restored to their entry values. out_data buffer shall be + * updated with command return value. + * Neither in_data nor out_data may be referenced after this function returns. + * + * Return value shall describe whether xrp_command_handler itself was + * successful or not, not the command it was requested to run. + * I.e. if the command was not recognized or its handler could not be called + * due to insufficient memory, that's XRP_STATUS_FAILURE returned in status. + * The host will also receive XRP_STATUS_FAILURE as a completion status. + * If the command was run that's XRP_STATUS_SUCCESS regardless of the + * command-specific status, which should be returned in out_data. + * + * \param handler_context: context that was passed to the + * xrp_device_register_namespace + */ +typedef enum xrp_status +(xrp_command_handler)(void *handler_context, + const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group); + +/* + * Register namespace handler. + * + * There may be only one handler for a namespace, second attempt to register + * a handler for the same namespace will fail. + * + * \param device: device for which namespace handler is registered + * \param nsid: namespace identifier, XRP_NAMESPACE_ID_SIZE bytes long + * \param handler: pointer to the handler function + * \param handler_context: first argument that will be passed to the handler + * function + * \param status: status of the registration operation + */ +void xrp_device_register_namespace(struct xrp_device *device, + const void *nsid, + xrp_command_handler *handler, + void *handler_context, + enum xrp_status *status); + +/* + * Unregister namespace handler. + * + * Only registered namespace handler may be unregistered. + * + * \param device: device for which namespace handler is registered + * \param nsid: namespace identifier, XRP_NAMESPACE_ID_SIZE bytes long + * \param status: status of the unregistration operation + */ +void xrp_device_unregister_namespace(struct xrp_device *device, + const void *nsid, + enum xrp_status *status); + + +/* Legacy DSP-specific interface (framework-style) */ + +/* + * DSP side callbacks. + */ + +/* + * Optional initialization callback. + */ +void xrp_user_initialize(enum xrp_status *status); + +/* + * This callback is called on the DSP side to process queued command. + * in_data, out_data and buffer_group correspond to the same parameters of the + * host side API calls. + * + * On return from this function buffer group and individual buffer reference + * counters shall be restored to their entry values. out_data buffer shall be + * updated with command return value. + * Neither in_data nor out_data may be referenced after this function returns. + * + * Value returned in status shall describe whether xrp_run_command itself was + * successful or not, not the command it was requested to run. + * I.e. if the command was not recognized or its handler could not be called + * due to insufficient memory, that's XRP_STATUS_FAILURE returned in status. + * If the command was run that's XRP_STATUS_SUCCESS regardless of the + * command-specific status, which should be returned in out_data. + */ +void xrp_run_command(const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group, + enum xrp_status *status); + +/* + * Helper function that terminates fast simulation + */ +void xrp_exit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/test-xrp/xrp_dsp.c b/test-xrp/xrp_dsp.c new file mode 100644 index 0000000..7e5f387 --- /dev/null +++ b/test-xrp/xrp_dsp.c @@ -0,0 +1,721 @@ +/* + * Copyright (c) 2016 - 2017 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "xrp_api.h" +#include "xrp_dsp_hw.h" + +typedef uint8_t __u8; +typedef uint32_t __u32; +#include "xrp_kernel_dsp_interface.h" + +#ifdef DEBUG +#define pr_debug printf +#else +static inline int pr_debug(const char *p, ...) +{ + (void)p; + return 0; +} +#endif + +extern char xrp_dsp_comm_base_magic[] __attribute__((weak)); +void *xrp_dsp_comm_base = &xrp_dsp_comm_base_magic; + +static int manage_cache; + +/* DSP side XRP API implementation */ + +struct xrp_refcounted { + unsigned long count; +}; + +struct xrp_cmd_ns { + uint8_t id[XRP_NAMESPACE_ID_SIZE]; + xrp_command_handler *handler; + void *handler_context; +}; + +struct xrp_device { + struct xrp_refcounted ref; + void *dsp_cmd; + size_t n_cmd_ns; + size_t size_cmd_ns; + struct xrp_cmd_ns *cmd_ns; +}; + +struct xrp_buffer { + struct xrp_refcounted ref; + void *ptr; + size_t size; + unsigned long map_count; + enum xrp_access_flags allowed_access; + enum xrp_access_flags map_flags; +}; + +struct xrp_buffer_group { + struct xrp_refcounted ref; + size_t n_buffers; + struct xrp_buffer *buffer; +}; + + +static inline void dcache_region_invalidate(void *p, size_t sz) +{ + if (manage_cache) + xthal_dcache_region_invalidate(p, sz); +} + +static inline void dcache_region_writeback(void *p, size_t sz) +{ + if (manage_cache) + xthal_dcache_region_writeback(p, sz); +} + +static inline void set_status(enum xrp_status *status, enum xrp_status v) +{ + if (status) + *status = v; +} + +static enum xrp_status retain_refcounted(struct xrp_refcounted *ref) +{ + if (ref) { + ++ref->count; + return XRP_STATUS_SUCCESS; + } + return XRP_STATUS_FAILURE; +} + +static enum xrp_status release_refcounted(struct xrp_refcounted *ref) +{ + if (ref) { + if (ref->count-- > 0) + return XRP_STATUS_SUCCESS; + } + return XRP_STATUS_FAILURE; +} + +struct xrp_device *xrp_open_device(int idx, enum xrp_status *status) +{ + static struct xrp_device device; + + if (idx == 0) { + device.dsp_cmd = xrp_dsp_comm_base; + set_status(status, XRP_STATUS_SUCCESS); + return &device; + } else { + set_status(status, XRP_STATUS_FAILURE); + return NULL; + } +} + +void xrp_retain_device(struct xrp_device *device, enum xrp_status *status) +{ + set_status(status, retain_refcounted(&device->ref)); +} + +void xrp_release_device(struct xrp_device *device, enum xrp_status *status) +{ + set_status(status, release_refcounted(&device->ref)); +} + +static int compare_cmd_ns(const void *nsid, struct xrp_cmd_ns *cmd_ns) +{ + return memcmp(nsid, cmd_ns->id, sizeof(cmd_ns->id)); +} + +static int cmd_ns_match(const void *nsid, struct xrp_cmd_ns *cmd_ns) +{ + return cmd_ns && compare_cmd_ns(nsid, cmd_ns) == 0; +} + +#ifdef DEBUG +static void dump_nsid(const void *p) +{ + const uint8_t *id = p; + + printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + id[0], id[1], id[2], id[3], + id[4], id[5], + id[6], id[7], + id[8], id[9], + id[10], id[11], id[12], id[13], id[14], id[15]); +} + +static void dump_cmd_ns(const struct xrp_cmd_ns *cmd_ns) +{ + if (cmd_ns) { + dump_nsid(cmd_ns->id); + printf(" -> %p(%p)", cmd_ns->handler, cmd_ns->handler_context); + } else { + printf("NULL"); + } +} + +static void dump_cmd_ns_map(const struct xrp_device *device) +{ + size_t i; + + printf("n_cmd_ns: %zu, size_cmd_ns: %zu\n", + device->n_cmd_ns, device->size_cmd_ns); + for (i = 0; i < device->n_cmd_ns; ++i) { + printf(" "); + dump_cmd_ns(device->cmd_ns + i); + printf("\n"); + } +} +#else +static void dump_nsid(const void *p) +{ + (void)p; +} + +static void dump_cmd_ns(const struct xrp_cmd_ns *cmd_ns) +{ + (void)cmd_ns; +} + +static void dump_cmd_ns_map(const struct xrp_device *device) +{ + (void)device; +} +#endif + +static struct xrp_cmd_ns *find_cmd_ns(struct xrp_device *device, + const void *id) +{ + size_t a = 0; + size_t b = device->n_cmd_ns; + struct xrp_cmd_ns *p; + + pr_debug("%s: ", __func__); + dump_nsid(id); + pr_debug("\n"); + while (b - a > 1) { + size_t c = (a + b) / 2; + + pr_debug("a: %zu, b:%zu, c: %zu\n", a, b, c); + p = device->cmd_ns + c; + if (compare_cmd_ns(id, p) < 0) + b = c; + else + a = c; + pr_debug("...a: %zu, b:%zu\n", a, b); + } + p = device->cmd_ns + a; + if (a < b && compare_cmd_ns(id, p) > 0) + ++p; + pr_debug("%s: found: ", __func__); + dump_cmd_ns(p); + pr_debug("\n"); + + return p; +} + +static int cmd_ns_present(struct xrp_device *device, struct xrp_cmd_ns *cmd_ns) +{ + return cmd_ns >= device->cmd_ns && + cmd_ns < device->cmd_ns + device->n_cmd_ns; +} + +static struct xrp_cmd_ns *insert_cmd_ns(struct xrp_device *device, + struct xrp_cmd_ns *cmd_ns) +{ + size_t i = cmd_ns - device->cmd_ns; + + if (device->n_cmd_ns == device->size_cmd_ns) { + size_t new_size = (device->size_cmd_ns + 1) * 2; + void *new_cmd_ns = realloc(device->cmd_ns, + new_size * sizeof(*device->cmd_ns)); + + if (!new_cmd_ns) + return NULL; + device->cmd_ns = new_cmd_ns; + device->size_cmd_ns = new_size; + cmd_ns = device->cmd_ns + i; + } + memmove(cmd_ns + 1, cmd_ns, + sizeof(*cmd_ns) * (device->n_cmd_ns - i)); + ++device->n_cmd_ns; + return cmd_ns; +} + +static void remove_cmd_ns(struct xrp_device *device, + struct xrp_cmd_ns *cmd_ns) +{ + size_t i = cmd_ns - device->cmd_ns; + + memmove(cmd_ns, cmd_ns + 1, + sizeof(*cmd_ns) * (device->n_cmd_ns - i - 1)); + --device->n_cmd_ns; +} + +struct xrp_buffer *xrp_create_buffer(struct xrp_device *device, + size_t size, void *host_ptr, + enum xrp_status *status) +{ + (void)device; + (void)size; + (void)host_ptr; + set_status(status, XRP_STATUS_FAILURE); + return NULL; +} + +void xrp_retain_buffer(struct xrp_buffer *buffer, enum xrp_status *status) +{ + set_status(status, retain_refcounted(&buffer->ref)); +} + +void xrp_release_buffer(struct xrp_buffer *buffer, enum xrp_status *status) +{ + set_status(status, release_refcounted(&buffer->ref)); +} + +void *xrp_map_buffer(struct xrp_buffer *buffer, size_t offset, size_t size, + enum xrp_access_flags map_flags, enum xrp_status *status) +{ + if (offset <= buffer->size && + size <= buffer->size - offset && + (buffer->allowed_access & map_flags) == map_flags) { + retain_refcounted(&buffer->ref); + ++buffer->map_count; + buffer->map_flags |= map_flags; + set_status(status, XRP_STATUS_SUCCESS); + return buffer->ptr + offset; + } + set_status(status, XRP_STATUS_FAILURE); + return NULL; +} + +void xrp_unmap_buffer(struct xrp_buffer *buffer, void *p, + enum xrp_status *status) +{ + if (p >= buffer->ptr && (size_t)(p - buffer->ptr) <= buffer->size) { + --buffer->map_count; + release_refcounted(&buffer->ref); + set_status(status, XRP_STATUS_SUCCESS); + } else { + set_status(status, XRP_STATUS_FAILURE); + } +} + +void xrp_buffer_get_info(struct xrp_buffer *buffer, enum xrp_buffer_info info, + void *out, size_t out_sz, enum xrp_status *status) +{ + enum xrp_status s = XRP_STATUS_FAILURE; + size_t sz; + void *ptr; + + switch (info) { + case XRP_BUFFER_SIZE_SIZE_T: + sz = sizeof(buffer->size); + ptr = &buffer->size; + break; + + case XRP_BUFFER_HOST_POINTER_PTR: + sz = sizeof(void *); + ptr = &buffer->ptr; + break; + + default: + goto out; + } + + if (sz == out_sz) { + memcpy(out, ptr, sz); + s = XRP_STATUS_SUCCESS; + } +out: + set_status(status, s); +} + +struct xrp_buffer_group *xrp_create_buffer_group(enum xrp_status *status) +{ + set_status(status, XRP_STATUS_FAILURE); + return NULL; +} + +void xrp_retain_buffer_group(struct xrp_buffer_group *group, + enum xrp_status *status) +{ + set_status(status, retain_refcounted(&group->ref)); +} + +void xrp_release_buffer_group(struct xrp_buffer_group *group, + enum xrp_status *status) +{ + set_status(status, release_refcounted(&group->ref)); +} + +size_t xrp_add_buffer_to_group(struct xrp_buffer_group *group, + struct xrp_buffer *buffer, + enum xrp_access_flags access_flags, + enum xrp_status *status) +{ + (void)group; + (void)buffer; + (void)access_flags; + set_status(status, XRP_STATUS_FAILURE); + return -1; +} + +struct xrp_buffer *xrp_get_buffer_from_group(struct xrp_buffer_group *group, + size_t idx, + enum xrp_status *status) +{ + if (idx < group->n_buffers) { + set_status(status, XRP_STATUS_SUCCESS); + xrp_retain_buffer(group->buffer + idx, NULL); + return group->buffer + idx; + } + set_status(status, XRP_STATUS_FAILURE); + return NULL; +} + +void xrp_buffer_group_get_info(struct xrp_buffer_group *group, + enum xrp_buffer_group_info info, size_t idx, + void *out, size_t out_sz, + enum xrp_status *status) +{ + enum xrp_status s = XRP_STATUS_FAILURE; + size_t sz; + void *ptr; + + switch (info) { + case XRP_BUFFER_GROUP_BUFFER_FLAGS_ENUM: + if (idx >= group->n_buffers) + goto out; + sz = sizeof(group->buffer[idx].allowed_access); + ptr = &group->buffer[idx].allowed_access; + break; + + default: + goto out; + } + + if (sz == out_sz) { + memcpy(out, ptr, sz); + s = XRP_STATUS_SUCCESS; + } +out: + set_status(status, s); +} + +/* DSP side request handling */ + +static void do_handshake(struct xrp_dsp_sync *shared_sync) +{ + uint32_t v; + + pr_debug("%s, shared_sync = %p\n", __func__, shared_sync); + + while (XT_L32AI(&shared_sync->sync, 0) != XRP_DSP_SYNC_START) { + dcache_region_invalidate(&shared_sync->sync, + sizeof(shared_sync->sync)); + } + + XT_S32RI(XRP_DSP_SYNC_DSP_READY, &shared_sync->sync, 0); + dcache_region_writeback(&shared_sync->sync, + sizeof(shared_sync->sync)); + + for (;;) { + dcache_region_invalidate(&shared_sync->sync, + sizeof(shared_sync->sync)); + v = XT_L32AI(&shared_sync->sync, 0); + if (v == XRP_DSP_SYNC_HOST_TO_DSP) + break; + if (v != XRP_DSP_SYNC_DSP_READY) + return; + } + + xrp_hw_set_sync_data(shared_sync->hw_sync_data); + + XT_S32RI(XRP_DSP_SYNC_DSP_TO_HOST, &shared_sync->sync, 0); + dcache_region_writeback(&shared_sync->sync, + sizeof(shared_sync->sync)); + + xrp_hw_wait_device_irq(); + + xrp_hw_send_host_irq(); + + pr_debug("%s: done\n", __func__); +} + +static inline int xrp_request_valid(struct xrp_dsp_cmd *dsp_cmd, + uint32_t *pflags) +{ + uint32_t flags = XT_L32AI(&dsp_cmd->flags, 0); + + *pflags = flags; + return (flags & (XRP_DSP_CMD_FLAG_REQUEST_VALID | + XRP_DSP_CMD_FLAG_RESPONSE_VALID)) == + XRP_DSP_CMD_FLAG_REQUEST_VALID; + +} + +static void complete_request(struct xrp_dsp_cmd *dsp_cmd, uint32_t flags) +{ + flags |= XRP_DSP_CMD_FLAG_RESPONSE_VALID; + + dcache_region_writeback(dsp_cmd, + sizeof(*dsp_cmd)); + XT_S32RI(flags, &dsp_cmd->flags, 0); + dcache_region_writeback(&dsp_cmd->flags, + sizeof(dsp_cmd->flags)); + xrp_hw_send_host_irq(); +} + +static enum xrp_access_flags dsp_buffer_allowed_access(__u32 flags) +{ + return flags == XRP_DSP_BUFFER_FLAG_READ ? + XRP_READ : XRP_READ_WRITE; +} + +void xrp_run_command(const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group, + enum xrp_status *status) __attribute__((weak)); + +void xrp_run_command(const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group, + enum xrp_status *status) +{ + (void)in_data; + (void)in_data_size; + (void)out_data; + (void)out_data_size; + (void)buffer_group; + *status = XRP_STATUS_FAILURE; +} + +static inline enum xrp_status +xrp_run_command_handler(void *handler_context, + const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group) +{ + enum xrp_status status = XRP_STATUS_FAILURE; + + (void)handler_context; + xrp_run_command(in_data, in_data_size, + out_data, out_data_size, + buffer_group, &status); + return status; +} + +static enum xrp_status process_command(struct xrp_device *device, + uint32_t flags) +{ + enum xrp_status status; + struct xrp_dsp_cmd *dsp_cmd = device->dsp_cmd; + size_t n_buffers = dsp_cmd->buffer_size / sizeof(struct xrp_dsp_buffer); + struct xrp_dsp_buffer *dsp_buffer; + struct xrp_buffer_group buffer_group; + struct xrp_buffer buffer[n_buffers]; /* TODO */ + xrp_command_handler *command_handler = xrp_run_command_handler; + void *handler_context = NULL; + size_t i; + + if (dsp_cmd->flags & XRP_DSP_CMD_FLAG_REQUEST_NSID) { + struct xrp_cmd_ns *cmd_ns = find_cmd_ns(device, dsp_cmd->nsid); + if (cmd_ns_match(dsp_cmd->nsid, cmd_ns)) { + command_handler = cmd_ns->handler; + handler_context = cmd_ns->handler_context; + } else { + flags |= XRP_DSP_CMD_FLAG_RESPONSE_DELIVERY_FAIL; + status = XRP_STATUS_FAILURE; + goto out; + } + } + + if (n_buffers > XRP_DSP_CMD_INLINE_BUFFER_COUNT) { + dsp_buffer = (void *)dsp_cmd->buffer_addr; + dcache_region_invalidate(dsp_buffer, + n_buffers * sizeof(*dsp_buffer)); + + } else { + dsp_buffer = (void *)&dsp_cmd->buffer_data; + } + if (dsp_cmd->in_data_size > sizeof(dsp_cmd->in_data)) { + dcache_region_invalidate((void *)dsp_cmd->in_data_addr, + dsp_cmd->in_data_size); + } + /* Create buffers from incoming buffer data, put them to group. + * Passed flags add some restrictions to possible buffer mapping + * modes: + * R only allows R + * W and RW allow R, W or RW + * (actually W only allows W and RW, but that's hard to express and + * is not particularly useful) + */ + for (i = 0; i < n_buffers; ++i) { + buffer[i] = (struct xrp_buffer){ + .allowed_access = + dsp_buffer_allowed_access(dsp_buffer[i].flags), + .ptr = (void *)dsp_buffer[i].addr, + .size = dsp_buffer[i].size, + }; + if (buffer[i].allowed_access & XRP_READ) { + dcache_region_invalidate(buffer[i].ptr, + buffer[i].size); + } + } + + buffer_group = (struct xrp_buffer_group){ + .n_buffers = n_buffers, + .buffer = buffer, + }; + + status = command_handler(handler_context, + dsp_cmd->in_data_size > sizeof(dsp_cmd->in_data) ? + (void *)dsp_cmd->in_data_addr : dsp_cmd->in_data, + dsp_cmd->in_data_size, + dsp_cmd->out_data_size > sizeof(dsp_cmd->out_data) ? + (void *)dsp_cmd->out_data_addr : dsp_cmd->out_data, + dsp_cmd->out_data_size, + &buffer_group); + + if (status != XRP_STATUS_SUCCESS) + flags |= XRP_DSP_CMD_FLAG_RESPONSE_DELIVERY_FAIL; + + /* + * update flags in the buffer data: what access actually took place, + * to update caches on the host side. + */ + for (i = 0; i < n_buffers; ++i) { + __u32 flags = 0; + + if (buffer[i].map_flags & XRP_READ) + flags |= XRP_DSP_BUFFER_FLAG_READ; + if (buffer[i].map_flags & XRP_WRITE) + flags |= XRP_DSP_BUFFER_FLAG_WRITE; + + pr_debug("%s: dsp_buffer[%d].flags = %d\n", __func__, i, flags); + dsp_buffer[i].flags = flags; + + if (buffer[i].ref.count) { + pr_debug("%s: refcount leak on buffer %d\n", + __func__, i); + } + if (buffer[i].map_count) { + pr_debug("%s: map_count leak on buffer %d\n", + __func__, i); + } + if (buffer[i].map_flags & XRP_WRITE) { + dcache_region_writeback(buffer[i].ptr, + buffer[i].size); + } + } + if (buffer_group.ref.count) { + pr_debug("%s: refcount leak on buffer group\n", __func__); + } + if (dsp_cmd->out_data_size > sizeof(dsp_cmd->out_data)) { + dcache_region_writeback((void *)dsp_cmd->out_data_addr, + dsp_cmd->out_data_size); + } + if (n_buffers > XRP_DSP_CMD_INLINE_BUFFER_COUNT) { + dcache_region_writeback(dsp_buffer, + n_buffers * sizeof(*dsp_buffer)); + } +out: + complete_request(dsp_cmd, flags); + return status; +} + +void xrp_device_register_namespace(struct xrp_device *device, + const void *nsid, + xrp_command_handler *handler, + void *handler_context, + enum xrp_status *status) +{ + struct xrp_cmd_ns *cmd_ns = find_cmd_ns(device, nsid); + + if (cmd_ns_present(device, cmd_ns) && cmd_ns_match(nsid, cmd_ns)) { + set_status(status, XRP_STATUS_FAILURE); + } else { + cmd_ns = insert_cmd_ns(device, cmd_ns); + if (cmd_ns) { + memcpy(cmd_ns->id, nsid, sizeof(cmd_ns->id)); + cmd_ns->handler = handler; + cmd_ns->handler_context = handler_context; + dump_cmd_ns_map(device); + set_status(status, XRP_STATUS_SUCCESS); + } else { + set_status(status, XRP_STATUS_FAILURE); + } + } +} + +void xrp_device_unregister_namespace(struct xrp_device *device, + const void *nsid, + enum xrp_status *status) +{ + struct xrp_cmd_ns *cmd_ns = find_cmd_ns(device, nsid); + + if (cmd_ns_present(device, cmd_ns) && cmd_ns_match(nsid, cmd_ns)) { + remove_cmd_ns(device, cmd_ns); + dump_cmd_ns_map(device); + set_status(status, XRP_STATUS_SUCCESS); + } else { + set_status(status, XRP_STATUS_FAILURE); + } +} + +enum xrp_status xrp_device_poll(struct xrp_device *device) +{ + uint32_t flags; + + dcache_region_invalidate(device->dsp_cmd, + sizeof(*device->dsp_cmd)); + if (xrp_request_valid(device->dsp_cmd, &flags)) + return XRP_STATUS_SUCCESS; + else + return XRP_STATUS_PENDING; +} + +enum xrp_status xrp_device_dispatch(struct xrp_device *device) +{ + uint32_t flags; + enum xrp_status status; + + dcache_region_invalidate(device->dsp_cmd, + sizeof(*device->dsp_cmd)); + if (!xrp_request_valid(device->dsp_cmd, &flags)) + return XRP_STATUS_PENDING; + + if (flags == XRP_DSP_SYNC_START) { + do_handshake(device->dsp_cmd); + status = XRP_STATUS_SUCCESS; + } else { + status = process_command(device, flags); + } + return status; +} diff --git a/test-xrp/xrp_dsp_hw.h b/test-xrp/xrp_dsp_hw.h new file mode 100644 index 0000000..3a05723 --- /dev/null +++ b/test-xrp/xrp_dsp_hw.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef XRP_DSP_HW_H +#define XRP_DSP_HW_H + +void xrp_hw_send_host_irq(void); +void xrp_hw_wait_device_irq(void); +void xrp_hw_set_sync_data(void *p); + +#endif diff --git a/test-xrp/xrp_dsp_hw_dct.c b/test-xrp/xrp_dsp_hw_dct.c new file mode 100644 index 0000000..ad96c17 --- /dev/null +++ b/test-xrp/xrp_dsp_hw_dct.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2016 - 2017 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "xrp_dsp_hw.h" + +typedef uint32_t __u32; +#include "xrp_hw_dct_dsp_interface.h" + +#ifdef DEBUG +#define pr_debug printf +#else +static inline int pr_debug(const char *p, ...) +{ + (void)p; + return 0; +} +#endif + +static uint32_t mmio_base; + +#define device_mmio(off) ((volatile void *)mmio_base + off) +#define host_mmio(off) ((volatile void *)mmio_base + off) + +enum xrp_irq_mode { + XRP_IRQ_NONE, + XRP_IRQ_LEVEL, + XRP_IRQ_EDGE, +}; +static enum xrp_irq_mode host_irq_mode; +static enum xrp_irq_mode device_irq_mode; + +/* Charles Qi - split to set and clr controls as the 1st step +static uint32_t device_irq_offset; +static uint32_t device_irq_bit; +static uint32_t device_irq; + +static uint32_t host_irq_offset; +static uint32_t host_irq_bit; +*/ + +static uint32_t device_irq_set_offset; +static uint32_t device_irq_set_bit; +static uint32_t device_irq_clr_offset; +static uint32_t device_irq_clr_bit; +static uint32_t device_irq; + +static uint32_t host_irq_set_offset; +static uint32_t host_irq_set_bit; +static uint32_t host_irq_clr_offset; +static uint32_t host_irq_clr_bit; + +static void xrp_irq_handler(void) +{ + pr_debug("%s\n", __func__); + if (device_irq_mode == XRP_IRQ_LEVEL) + XT_S32RI(1u << device_irq_clr_bit, device_mmio(device_irq_clr_offset), 0); +} + +void xrp_hw_send_host_irq(void) +{ + switch (host_irq_mode) { + case XRP_IRQ_EDGE: + XT_S32RI(1u << device_irq_set_bit, host_mmio(host_irq_set_offset), 0); + XT_S32RI(1u << device_irq_clr_bit, device_mmio(device_irq_clr_offset), 0); + /* fall through */ + case XRP_IRQ_LEVEL: + XT_S32RI(1u << device_irq_set_bit, host_mmio(host_irq_set_offset), 0); + break; + default: + break; + } +} + +void xrp_hw_wait_device_irq(void) +{ + unsigned old_intlevel; + + if (device_irq_mode == XRP_IRQ_NONE) + return; + + pr_debug("%s: waiting for device IRQ...\n", __func__); + old_intlevel = XTOS_SET_INTLEVEL(XCHAL_NUM_INTLEVELS - 1); + _xtos_interrupt_enable(device_irq); + XT_WAITI(0); + _xtos_interrupt_disable(device_irq); + XTOS_RESTORE_INTLEVEL(old_intlevel); +} + +void xrp_hw_set_sync_data(void *p) +{ + static const enum xrp_irq_mode irq_mode[] = { + [XRP_DSP_SYNC_IRQ_MODE_NONE] = XRP_IRQ_NONE, + [XRP_DSP_SYNC_IRQ_MODE_LEVEL] = XRP_IRQ_LEVEL, + [XRP_DSP_SYNC_IRQ_MODE_EDGE] = XRP_IRQ_EDGE, + }; + struct xrp_hw_dct_sync_data *hw_sync = p; + + mmio_base = hw_sync->device_mmio_base; + pr_debug("%s: mmio_base: 0x%08x\n", __func__, mmio_base); + + if (hw_sync->device_irq_mode < sizeof(irq_mode) / sizeof(*irq_mode)) { + device_irq_mode = irq_mode[hw_sync->device_irq_mode]; + device_irq_set_offset = hw_sync->device_irq_iss[0]; + device_irq_set_bit = hw_sync->device_irq_iss[1]; + device_irq_clr_offset = hw_sync->device_irq_isc[0]; + device_irq_clr_bit = hw_sync->device_irq_isc[1]; + device_irq = hw_sync->device_irq; + pr_debug("%s: device_irq_mode = %d, device_irq_set_offset = %d, device_irq_set_bit = %d, device_irq_clr_offset = %d, device_irq_clr_bit = %d, device_irq = %d\n", + __func__, device_irq_mode, + device_irq_set_offset, device_irq_set_bit, device_irq_clr_offset, device_irq_clr_bit, device_irq); + } else { + device_irq_mode = XRP_IRQ_NONE; + } + + if (hw_sync->host_irq_mode < sizeof(irq_mode) / sizeof(*irq_mode)) { + host_irq_mode = irq_mode[hw_sync->host_irq_mode]; + host_irq_set_offset = hw_sync->host_irq_iss[0]; + host_irq_set_bit = hw_sync->host_irq_iss[1]; + host_irq_clr_offset = hw_sync->host_irq_isc[0]; + host_irq_clr_bit = hw_sync->host_irq_isc[1]; + pr_debug("%s: host_irq_mode = %d, host_irq_set_offset = %d, host_irq_set_bit = %d, host_irq_clr_offset = %d, host_irq_clr_bit = %d\n", + __func__, host_irq_mode, host_irq_set_offset, host_irq_set_bit, host_irq_clr_offset, host_irq_clr_bit); + } else { + host_irq_mode = XRP_IRQ_NONE; + } + + if (device_irq_mode != XRP_IRQ_NONE) { + _xtos_interrupt_disable(device_irq); + _xtos_set_interrupt_handler(device_irq, xrp_irq_handler); + } +} diff --git a/test-xrp/xrp_hw_dct_dsp_interface.h b/test-xrp/xrp_hw_dct_dsp_interface.h new file mode 100644 index 0000000..4812ad9 --- /dev/null +++ b/test-xrp/xrp_hw_dct_dsp_interface.h @@ -0,0 +1,58 @@ +/* + * XRP interface between hardware-specific linux and DSP parts of example + * hardware + * + * Copyright (c) 2017 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef _XRP_KERNEL_DCT_HW_DSP_INTERFACE +#define _XRP_KERNEL_DCT_HW_DSP_INTERFACE + +enum { + XRP_DSP_SYNC_IRQ_MODE_NONE = 0x0, + XRP_DSP_SYNC_IRQ_MODE_LEVEL = 0x1, + XRP_DSP_SYNC_IRQ_MODE_EDGE = 0x2, +}; + +//ZQI: +//get all individual register fields from dts +struct xrp_hw_dct_sync_data { + __u32 device_mmio_base; + __u32 device_irq_ism[2]; + __u32 device_irq_ris[2]; + __u32 device_irq_mis[2]; + __u32 device_irq_isc[2]; + __u32 device_irq_iss[2]; + __u32 device_irq_mode; + __u32 device_irq; + __u32 host_irq_ism[2]; + __u32 host_irq_ris[2]; + __u32 host_irq_mis[2]; + __u32 host_irq_isc[2]; + __u32 host_irq_iss[2]; + __u32 host_irq_mode; +}; + +#endif diff --git a/test-xrp/xrp_kernel_dsp_interface.h b/test-xrp/xrp_kernel_dsp_interface.h new file mode 100644 index 0000000..cbff1ce --- /dev/null +++ b/test-xrp/xrp_kernel_dsp_interface.h @@ -0,0 +1,97 @@ +/* + * Data structures and constants for generic XRP interface between + * linux and DSP + * + * Copyright (c) 2015 - 2017 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef _XRP_KERNEL_DSP_INTERFACE_H +#define _XRP_KERNEL_DSP_INTERFACE_H + +#ifndef XRP_DSP_COMM_BASE_MAGIC +#define XRP_DSP_COMM_BASE_MAGIC 0x20161006 +#endif + +enum { + XRP_DSP_SYNC_IDLE = 0, + XRP_DSP_SYNC_HOST_TO_DSP = 0x1, + XRP_DSP_SYNC_DSP_TO_HOST = 0x3, + XRP_DSP_SYNC_START = 0x101, + XRP_DSP_SYNC_DSP_READY = 0x203, +}; + +struct xrp_dsp_sync { + __u32 sync; + __u32 hw_sync_data[0]; +}; + +enum { + XRP_DSP_BUFFER_FLAG_READ = 0x1, + XRP_DSP_BUFFER_FLAG_WRITE = 0x2, +}; + +struct xrp_dsp_buffer { + /* + * When submitted to DSP: types of access allowed + * When returned to host: actual access performed + */ + __u32 flags; + __u32 size; + __u32 addr; +}; + +enum { + XRP_DSP_CMD_FLAG_REQUEST_VALID = 0x00000001, + XRP_DSP_CMD_FLAG_RESPONSE_VALID = 0x00000002, + XRP_DSP_CMD_FLAG_REQUEST_NSID = 0x00000004, + XRP_DSP_CMD_FLAG_RESPONSE_DELIVERY_FAIL = 0x00000008, +}; + +#define XRP_DSP_CMD_INLINE_DATA_SIZE 16 +#define XRP_DSP_CMD_INLINE_BUFFER_COUNT 1 +#define XRP_DSP_CMD_NAMESPACE_ID_SIZE 16 + +struct xrp_dsp_cmd { + __u32 flags; + __u32 in_data_size; + __u32 out_data_size; + __u32 buffer_size; + union { + __u32 in_data_addr; + __u8 in_data[XRP_DSP_CMD_INLINE_DATA_SIZE]; + }; + union { + __u32 out_data_addr; + __u8 out_data[XRP_DSP_CMD_INLINE_DATA_SIZE]; + }; + union { + __u32 buffer_addr; + struct xrp_dsp_buffer buffer_data[XRP_DSP_CMD_INLINE_BUFFER_COUNT]; + __u8 buffer_alignment[XRP_DSP_CMD_INLINE_DATA_SIZE]; + }; + __u8 nsid[XRP_DSP_CMD_NAMESPACE_ID_SIZE]; +}; + +#endif diff --git a/xrp-dsp/Makefile.in b/xrp-dsp/Makefile.in index 507791f..dd0c440 100644 --- a/xrp-dsp/Makefile.in +++ b/xrp-dsp/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -39,7 +39,17 @@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -101,12 +111,12 @@ NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = xrp-dsp -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/autoconf/depcomp $(include_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \ + $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @@ -210,6 +220,7 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/autoconf/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -298,6 +309,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -328,7 +340,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xrp-dsp/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xrp-dsp/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -639,6 +650,8 @@ uninstall-am: uninstall-includeHEADERS uninstall-libLIBRARIES mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-includeHEADERS uninstall-libLIBRARIES +.PRECIOUS: Makefile + # 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. diff --git a/xrp-example/Makefile.in b/xrp-example/Makefile.in index 7b148bb..cb11a74 100644 --- a/xrp-example/Makefile.in +++ b/xrp-example/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -38,7 +38,17 @@ # VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -108,12 +118,11 @@ bin_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @BUILD_DSP_FALSE@@BUILD_SIM_TRUE@am__append_5 = xrp-linux-sim @BUILD_DSP_FALSE@@BUILD_NAT_TRUE@am__append_6 = xrp-linux-nat subdir = xrp-example -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/autoconf/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @@ -214,6 +223,7 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/autoconf/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -302,6 +312,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -352,7 +363,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xrp-example/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xrp-example/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -697,6 +707,8 @@ uninstall-am: uninstall-binPROGRAMS ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS +.PRECIOUS: Makefile + xrp.s: $(srcdir)/xrp.dts $(AM_V_GEN)$(DTC) -o $@ -O asm $< diff --git a/xrp-example/sdip-xrp.dtsi b/xrp-example/sdip-xrp.dtsi new file mode 100644 index 0000000..2c39043 --- /dev/null +++ b/xrp-example/sdip-xrp.dtsi @@ -0,0 +1,626 @@ +/* + * dts file for DCT SDIP + * + * (C) Copyright 2017 + * Dream Chip Technologies + * Ralph Hempel, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +/ { + interrupt-parent = <&gic>; + #size-cells = <2>; + #address-cells = <2>; + + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c1; + gpio0 = &pinctrl0; + serial0 = &uart0; + serial1 = &uart1; + ivp0 = &ivp0; + ivp1 = &ivp1; + ivp2 = &ivp2; + ivp3 = &ivp3; + viu0 = &viu0; + viu1 = &viu1; + viu2 = &viu2; + viu3 = &viu3; + }; + + gic: intc@0x02281000 { + #address-cells = <0x00000002>; + #size-cells = <0x00000002>; + reg = <0x00000000 0x02281000 0x00000000 0x00001000>, + <0x00000000 0x02282000 0x00000000 0x00002000>, + <0x00000000 0x02284000 0x00000000 0x00002000>, + <0x00000000 0x02286000 0x00000000 0x00002000>; + compatible = "arm,gic-400"; + ranges; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + interrupts = ; + }; + + cpus { + #address-cells = <0x00000001>; + #size-cells = <0x00000000>; + + cpu@0 { + reg = <0>; + compatible = "arm,cortex-a53", "arm,armv8"; + device_type = "cpu"; + clocks = <&a53_clk>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; + }; + cpu@1 { + reg = <1>; + compatible = "arm,cortex-a53", "arm,armv8"; + device_type = "cpu"; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; + }; + cpu@2 { + reg = <2>; + compatible = "arm,cortex-a53", "arm,armv8"; + device_type = "cpu"; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; + }; + cpu@3 { + reg = <3>; + compatible = "arm,cortex-a53", "arm,armv8"; + device_type = "cpu"; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; + }; + + }; + + timer { + interrupts = , + , + , + ; + always-on; + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + }; + + a53_clk: a53_clk { + clock-output-names = "clk500mhz"; + clock-frequency = <500000000>; + #clock-cells = <0>; + compatible = "fixed-clock"; + }; + + apu_clk: apu_clk { + clock-output-names = "clk250mhz"; + clock-frequency = <250000000>; + #clock-cells = <0>; + compatible = "fixed-clock"; + }; + + pclk: pclk { + clock-output-names = "clk54mhz"; + clock-frequency = <54000000>; + #clock-cells = <0>; + compatible = "fixed-clock"; + }; + + apb_clk: apb_clk { + clock-output-names = "clk125mhz"; + clock-frequency = <125000000>; + #clock-cells = <0>; + compatible = "fixed-clock"; + }; + + gem_clk: gem_clk { + clock-output-names = "clk25mhz"; + clock-frequency = <25000000>; + #clock-cells = <0>; + compatible = "fixed-clock"; + }; + + /* 27MHz reference crystal */ + ref27: oscillator { + clock-output-names = "clk27mhz"; + clock-frequency = <27000000>; + #clock-cells = <0>; + compatible = "fixed-clock"; + }; + + noc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + chip-control@02344000 { + compatible = "simple-mfd", "syscon"; + reg = <0x00000000 0x02344000 0x00000000 0x00000088>; + pinctrl0: pinctrl0 { + #gpio-cells = <2>; + interrupts = , + ; + gpio-controller; + compatible = "dct,dct-pinctrl"; + pinctrl-names = "default"; + + i2c0_pmx: i2c0_pmx { + i2c { + dct,function = "i2c0"; + dct,groups = "i2c0"; + }; + }; + + i2c1_pmx: i2c1_pmx { + i2c { + dct,function = "i2c1"; + dct,groups = "i2c1"; + }; + }; + + i2c2_pmx: i2c2_pmx { + i2c { + dct,function = "i2c2"; + dct,groups = "i2c2"; + }; + }; + + i2c3_pmx: i2c3_pmx { + i2c { + dct,function = "i2c3"; + dct,groups = "i2c3"; + }; + }; + + i2c4_pmx: i2c4_pmx { + i2c { + dct,function = "i2c4"; + dct,groups = "i2c4"; + }; + }; + + i2c5_pmx: i2c5_pmx { + i2c { + dct,function = "i2c5"; + dct,groups = "i2c5"; + }; + }; + + i2c6_pmx: i2c6_pmx { + i2c { + dct,function = "i2c6"; + dct,groups = "i2c6"; + }; + }; + + i2c7_pmx: i2c7_pmx { + i2c { + dct,function = "i2c7"; + dct,groups = "i2c7"; + }; + }; + + uart1_pmx: uart1_pmx { + uart { + dct,function = "uart1"; + dct,groups = "uart1"; + }; + }; + + spi_boot1_pmx: spi_boot1_pmx { + spi_boot { + dct,function = "spi_boot1"; + dct,groups = "spi_boot1"; + }; + }; + + spi_boot2_pmx: spi_boot2_pmx { + spi_boot { + dct,function = "spi_boot2"; + dct,groups = "spi_boot2"; + }; + }; + + spi_boot3_pmx: spi_boot3_pmx { + spi_boot { + dct,function = "spi_boot3"; + dct,groups = "spi_boot3"; + }; + }; + + }; + }; + + dmac0: dma@02200000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x0 0x02200000 0x00000000 0x00001000>; + #dma-cells = <1>; + #dma-channels = <8>; + #dma-requests = <8>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + clocks = <&apu_clk>; + clock-names = "apb_pclk"; + }; + + uart0: dct-uart@02340000 { + device_type = "serial"; + clock-names = "uartclk"; + clocks = <&apb_clk>; + interrupts = ; + reg = <0x00000000 0x02340000 0x00000000 0x00000100>; + compatible = "dct,dct-uart"; + }; + + uart1: dct-uart@02340100 { + device_type = "serial"; + clock-names = "uartclk"; + clocks = <&apb_clk>; + interrupts = ; + reg = <0x00000000 0x02340100 0x00000000 0x00000100>; + compatible = "dct,dct-uart"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pmx>; + }; + + wdt0: watchdog@02345000 { + compatible = "dct,dct-wdt"; + clock-names = "wdogclk"; + clocks = <&apb_clk>; + reg = <0x00000000 0x02345000 0x00000000 0x00001000>; + interrupts = ; + timer = <7>; + /* reset-on-timeout; */ + timeout-sec = <10>; + }; + + qspi0: dct-qspi@02343000 { + #address-cells = <0x00000001>; + #size-cells = <0x00000000>; + bus-num = <0x00000000>; + num-cs = <0x00000004>; + interrupts = ; + reg = <0x00000000 0x02343000 0x00000000 0x00000030>; + compatible = "dct,dct-qspi"; + pinctrl-names = "default"; + qflash0: qflash@0 { + status = "disabled"; + #address-cells = <0x00000001>; + #size-cells = <0x00000001>; + reg = <0x00000000>; + compatible = "jedec,spi-nor"; + }; + qflash1: qflash@1 { + status = "disabled"; + #address-cells = <0x00000001>; + #size-cells = <0x00000001>; + reg = <0x00000001>; + compatible = "jedec,spi-nor"; + }; + qflash2: qflash@2 { + status = "disabled"; + #address-cells = <0x00000001>; + #size-cells = <0x00000001>; + reg = <0x00000002>; + compatible = "jedec,spi-nor"; + }; + qflash3: qflash@3 { + status = "disabled"; + #address-cells = <0x00000001>; + #size-cells = <0x00000001>; + reg = <0x00000003>; + compatible = "jedec,spi-nor"; + }; + }; + + i2c0: i2c@0232000 { + #address-cells = <0x00000001>; + #size-cells = <0x00000000>; + reg = <0x00000000 0x02320000 0x00000000 0x00000100>; + compatible = "dct,dct-i2c"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pmx>; + clock-names = "clk"; + clocks = <&apb_clk>; + }; + + i2c1: i2c@02320100 { + #address-cells = <0x00000001>; + #size-cells = <0x00000000>; + reg = <0x00000000 0x02320100 0x00000000 0x00000100>; + compatible = "dct,dct-i2c"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pmx>; + clock-names = "clk"; + clocks = <&apb_clk>; + }; + + i2c2: i2c@02320200 { + #address-cells = <0x00000001>; + #size-cells = <0x00000000>; + reg = <0x00000000 0x02320200 0x00000000 0x00000100>; + compatible = "dct,dct-i2c"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pmx>; + clock-names = "clk"; + clocks = <&apb_clk>; + }; + + i2c3: i2c@02320300 { + #address-cells = <0x00000001>; + #size-cells = <0x00000000>; + reg = <0x00000000 0x02320300 0x00000000 0x00000100>; + compatible = "dct,dct-i2c"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_pmx>; + clock-names = "clk"; + clocks = <&apb_clk>; + }; + + i2c4: i2c@02320400 { + #address-cells = <0x00000001>; + #size-cells = <0x00000000>; + reg = <0x00000000 0x02320400 0x00000000 0x00000100>; + compatible = "dct,dct-i2c"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c4_pmx>; + clock-names = "clk"; + clocks = <&apb_clk>; + }; + + i2c5: i2c@02320500 { + #address-cells = <0x00000001>; + #size-cells = <0x00000000>; + reg = <0x00000000 0x02320500 0x00000000 0x00000100>; + compatible = "dct,dct-i2c"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c5_pmx>; + clock-names = "clk"; + clocks = <&apb_clk>; + }; + + i2c6: i2c@0232060 { + #address-cells = <0x00000001>; + #size-cells = <0x00000000>; + reg = <0x00000000 0x02320600 0x00000000 0x00000100>; + compatible = "dct,dct-i2c"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c6_pmx>; + clock-names = "clk"; + clocks = <&apb_clk>; + }; + + i2c7: i2c@02320700 { + #address-cells = <0x00000001>; + #size-cells = <0x00000000>; + reg = <0x00000000 0x02320700 0x00000000 0x00000100>; + compatible = "dct,dct-i2c"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c7_pmx>; + clock-names = "clk"; + clocks = <&apb_clk>; + }; + + mvdu: mvdu@02021000 { + #address-cells = <2>; + #size-cells = <2>; + compatible = "dct,dct-mvdu"; + reg = <0x00000000 0x002021000 0x00000000 0x00001000>; + interrupts = ; + status = "disabled"; + }; + + viu0: viu@02000000 { + #address-cells = <2>; + #size-cells = <2>; + compatible = "dct,dct-viu"; + reg = <0x00000000 0x002000000 0x00000000 0x00004000>; + interrupts = , + ; + status = "disabled"; + }; + + viu1: viu@02004000 { + #address-cells = <2>; + #size-cells = <2>; + compatible = "dct,dct-viu"; + reg = <0x00000000 0x002004000 0x00000000 0x00004000>; + interrupts = , + ; + status = "disabled"; + }; + + viu2: viu@02008000 { + #address-cells = <2>; + #size-cells = <2>; + compatible = "dct,dct-viu"; + reg = <0x00000000 0x002008000 0x00000000 0x00004000>; + interrupts = , + ; + status = "disabled"; + }; + + viu3: viu@0200c000 { + #address-cells = <2>; + #size-cells = <2>; + compatible = "dct,dct-viu"; + reg = <0x00000000 0x00200c000 0x00000000 0x00004000>; + interrupts = , + ; + status = "disabled"; + }; + + dsp_ctrl: dsp_ctrl@01FF0000 { + #address-cells = <2>; + #size-cells = <2>; + compatible = "dct,dct-dsp-ctrl", "syscon", "simple-bus"; + reg = <0x00000000 0x01FF0000 0x00000000 0x1000>; + }; + + dsp_syscon: dsp_syscon@02316000 { + #address-cells = <2>; + #size-cells = <2>; + compatible = "dct,dct-dsp-syscon", "syscon", "simple-bus"; + reg = <0x00000000 0x02316000 0x00000000 0x1000>; + interrupts = , + ; + }; + + ivp0: ivp@01280000 { + reg = <0x00000000 0x01280000 0x00000000 0x00008000>, /*DRAM*/ + <0x00000000 0x01200000 0x00000000 0x00080000>, /*DRAM*/ + <0x00000000 0x01000000 0x00000000 0x00000400>; /*mailbox*/ + compatible = "dtc,dct-ivp"; + interrupts = , + ; + status = "disabled"; + }; + + ivp1: ivp@01480000 { + reg = <0x00000000 0x01480000 0x00000000 0x00008000>, /*DRAM*/ + <0x00000000 0x01400000 0x00000000 0x00080000>, /*DRAM*/ + <0x00000000 0x01000400 0x00000000 0x00000400>; /*mailbox*/ + compatible = "dtc,dct-ivp"; + interrupts = , + ; + status = "disabled"; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + xrp_reserved: xrp@98000000 { + compatible = "shared-dma-pool"; + reg = <0x0 0x98000000 0x0 0x08000000>; /* shared SRAM */ + reusable; + }; + }; + + ivp2: xrp@01680000 { + compatible = "cdns,xrp-hw-dct,cma"; + reg = <0x00000000 0x01680000 0x00000000 0x00008000>, + <0x00000000 0x01600000 0x00000000 0x00080000>, + <0x00000000 0x01000800 0x00000000 0x00000400>; + device-irq-mode = <2>; + device-irq-ism = <0x248 1>; /* offset, bit# */ + device-irq-ris = <0x2a8 1>; /* offset, bit# */ + device-irq-mis = <0x308 1>; /* offset, bit# */ + device-irq-isc = <0x368 1>; /* offset, bit# */ + device-irq-iss = <0x3c8 1>; /* offset, bit# */ + device-irq = <16>; + device-mmio-base = <0x01ff0000>; + + host-irq-mode = <2>; + host-irq-ism = <0x218 6>; /* offset, bit# */ + host-irq-ris = <0x278 6>; /* offset, bit# */ + host-irq-mis = <0x2d8 6>; /* offset, bit# */ + host-irq-isc = <0x338 6>; /* offset, bit# */ + host-irq-iss = <0x398 6>; /* offset, bit# */ + + dsp-reset = <0x4 2>; /* offset, bit# */ + dsp-runstall = <0x4 10>; /* offset, bit# */ + + firmware-name = "xrp.elf"; + interrupts = , + ; + status = "disabled"; + ranges = <0x0 0x01001000 0x0 0x01001000 0x0 0x001ff000 + 0x0 0xcff80000 0x0 0x01600000 0x0 0x00040000 + 0x0 0xcffc0000 0x0 0x01640000 0x0 0x00040000 + 0x0 0xd0000000 0x0 0x01680000 0x0 0x00008000 + 0x0 0x98000000 0x0 0x98000000 0x0 0x08000000>; + }; + + ivp3: xrp@01880000 { + compatible = "cdns,xrp-hw-dct,cma"; + reg = <0x00000000 0x01880000 0x00000000 0x00008000>, + <0x00000000 0x01800000 0x00000000 0x00080000>, + <0x00000000 0x01000c00 0x00000000 0x00000400>; + device-irq-mode = <2>; + device-irq-ism = <0x258 1>; /* offset, bit# */ + device-irq-ris = <0x2b8 1>; /* offset, bit# */ + device-irq-mis = <0x318 1>; /* offset, bit# */ + device-irq-isc = <0x378 1>; /* offset, bit# */ + device-irq-iss = <0x3d8 1>; /* offset, bit# */ + device-irq = <16>; + device-mmio-base = <0x01ff0000>; + + host-irq-mode = <2>; + host-irq-ism = <0x218 7>; /* offset, bit# */ + host-irq-ris = <0x278 7>; /* offset, bit# */ + host-irq-mis = <0x2d8 7>; /* offset, bit# */ + host-irq-isc = <0x338 7>; /* offset, bit# */ + host-irq-iss = <0x398 7>; /* offset, bit# */ + + dsp-reset = <0x4 3>; /* offset, bit# */ + dsp-runstall = <0x4 11>; /* offset, bit# */ + + firmware-name = "xrp.elf"; + status = "disabled"; + interrupts = , + ; + ranges = <0x0 0x01001000 0x0 0x01001000 0x0 0x001ff000 + 0x0 0xcff80000 0x0 0x01800000 0x0 0x00040000 + 0x0 0xcffc0000 0x0 0x01840000 0x0 0x00040000 + 0x0 0xd0000000 0x0 0x01880000 0x0 0x00008000 + 0x0 0x98000000 0x0 0x98000000 0x0 0x08000000>; + }; + + macb0: ethernet@0x02020000 { + compatible = "cdns,macb"; + reg = <0x00000000 0x02020000 0x00000000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + clock-names = "pclk", "hclk", "tx_clk"; + clocks = <&apb_clk>, <&apb_clk>, <&gem_clk>; + ethernet-phy@1 { + reg = <0x1>; + reset-gpios = <&pinctrl0 31 0>; + }; + }; + + }; + +}; diff --git a/xrp-kernel/Makefile b/xrp-kernel/Makefile index 0c01c8a..388a6ce 100644 --- a/xrp-kernel/Makefile +++ b/xrp-kernel/Makefile @@ -29,7 +29,8 @@ xrp-$(CONFIG_OF) += xrp_firmware.o xrp-$(CONFIG_CMA) += xrp_cma_alloc.o obj-m += xrp.o -obj-$(CONFIG_XRP_HW_SIMPLE) += xrp_hw_simple.o +#obj-$(CONFIG_XRP_HW_SIMPLE) += xrp_hw_simple.o +obj-$(CONFIG_XRP_HW_SIMPLE) += xrp_hw_dct.o ccflags-$(CONFIG_XRP_DEBUG) += -DDEBUG diff --git a/xrp-kernel/xrp_hw_dct.c b/xrp-kernel/xrp_hw_dct.c new file mode 100755 index 0000000..5baae3b --- /dev/null +++ b/xrp-kernel/xrp_hw_dct.c @@ -0,0 +1,506 @@ +/* + * xrp_hw_dct: Simple xtensa/arm low-level XRP driver + * + * Copyright (c) 2017 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xrp_hw.h" +#include "xrp_hw_dct_dsp_interface.h" +#include "xrp_internal.h" + +#define DRIVER_NAME "xrp-hw-dct" + +enum xrp_irq_mode { + XRP_IRQ_NONE, + XRP_IRQ_LEVEL, + XRP_IRQ_EDGE, + XRP_IRQ_MAX, +}; + +struct xrp_hw_dct { + struct xvp xrp; + phys_addr_t device_mmio_base; + + struct regmap *dsp_ctrl; + struct regmap *scu_ctrl; + + /* how IRQ is used to notify the device of incoming data */ + enum xrp_irq_mode device_irq_mode; + /* + * offset of device IRQ register in MMIO region (device side) + * bit number + * device IRQ# + */ + u32 device_irq_ism[2]; + u32 device_irq_ris[2]; + u32 device_irq_mis[2]; + u32 device_irq_isc[2]; + u32 device_irq_iss[2]; + u32 device_irq; + + /* how IRQ is used to notify the host of incoming data */ + enum xrp_irq_mode host_irq_mode; + /* + * offset of IRQ register (device side) + * bit number + */ + u32 host_irq_ism[2]; + u32 host_irq_ris[2]; + u32 host_irq_mis[2]; + u32 host_irq_isc[2]; + u32 host_irq_iss[2]; + u32 host_irq[2]; + + u32 dsp_reset[2]; + u32 dsp_runstall[2]; +}; + +static inline void reg_bitset32(struct regmap *reg, u32 ofst, u32 bit) +{ + u32 mask = (0x1 << bit); + regmap_update_bits(reg, ofst, mask, mask); +} + +static inline void reg_bitclr32(struct regmap *reg, u32 ofst, u32 bit) +{ + u32 mask = (0x1 << bit); + regmap_update_bits(reg, ofst, mask, 0); +} + + +static void *get_hw_sync_data(void *hw_arg, size_t *sz) +{ + struct xrp_hw_dct *hw = hw_arg; + struct xrp_hw_dct_sync_data *hw_sync_data = + kmalloc(sizeof(*hw_sync_data), GFP_KERNEL); + + if (!hw_sync_data) + return NULL; + + //prepare info struct for DSP + *hw_sync_data = (struct xrp_hw_dct_sync_data){ + .device_mmio_base = hw->device_mmio_base, + .device_irq_ism[0] = hw->device_irq_ism[0], + .device_irq_ism[1] = hw->device_irq_ism[1], + .device_irq_ris[0] = hw->device_irq_ris[0], + .device_irq_ris[1] = hw->device_irq_ris[1], + .device_irq_mis[0] = hw->device_irq_mis[0], + .device_irq_mis[1] = hw->device_irq_mis[1], + .device_irq_isc[0] = hw->device_irq_isc[0], + .device_irq_isc[1] = hw->device_irq_isc[1], + .device_irq_iss[0] = hw->device_irq_iss[0], + .device_irq_iss[1] = hw->device_irq_iss[1], + .device_irq_mode = hw->device_irq_mode, + .device_irq = hw->device_irq, + + .host_irq_ism[0] = hw->host_irq_ism[0], + .host_irq_ism[1] = hw->host_irq_ism[1], + .host_irq_ris[0] = hw->host_irq_ris[0], + .host_irq_ris[1] = hw->host_irq_ris[1], + .host_irq_mis[0] = hw->host_irq_mis[0], + .host_irq_mis[1] = hw->host_irq_mis[1], + .host_irq_isc[0] = hw->host_irq_isc[0], + .host_irq_isc[1] = hw->host_irq_isc[1], + .host_irq_iss[0] = hw->host_irq_iss[0], + .host_irq_iss[1] = hw->host_irq_iss[1], + .host_irq_mode = hw->host_irq_mode + }; + *sz = sizeof(*hw_sync_data); + return hw_sync_data; +} + +static void reset(void *hw_arg) +{ + struct xrp_hw_dct *hw = hw_arg; + + //reset is active-low, so 'bitclr' is reset, 'biset' is normal op + reg_bitclr32(hw->scu_ctrl, hw->dsp_reset[0], hw->dsp_reset[1]); + udelay(1); + reg_bitset32(hw->scu_ctrl, hw->dsp_reset[0], hw->dsp_reset[1]); +} + +static void halt(void *hw_arg) +{ + struct xrp_hw_dct *hw = hw_arg; + reg_bitset32(hw->scu_ctrl, hw->dsp_runstall[0], hw->dsp_runstall[1]); +} + +static void release(void *hw_arg) +{ + struct xrp_hw_dct *hw = hw_arg; + reg_bitclr32(hw->scu_ctrl, hw->dsp_runstall[0], hw->dsp_runstall[1]); +} + +static void send_irq(void *hw_arg) +{ + struct xrp_hw_dct *hw = hw_arg; + + switch (hw->device_irq_mode) { + case XRP_IRQ_EDGE: + reg_bitset32(hw->dsp_ctrl, hw->device_irq_iss[0], hw->device_irq_iss[1]); + udelay(1); + reg_bitset32(hw->dsp_ctrl, hw->device_irq_isc[0], hw->device_irq_isc[1]); + /* fallthrough */ + case XRP_IRQ_LEVEL: + wmb(); + reg_bitset32(hw->dsp_ctrl, hw->device_irq_iss[0], hw->device_irq_iss[1]); + break; + default: + break; + } +} + +static void ack_irq(void *hw_arg) +{ + struct xrp_hw_dct *hw = hw_arg; + + if (hw->host_irq_mode == XRP_IRQ_LEVEL) + reg_bitset32(hw->dsp_ctrl, hw->device_irq_isc[0], hw->device_irq_isc[1]); +} + +static irqreturn_t irq_handler(int irq, void *dev_id) +{ + struct xrp_hw_dct *hw = dev_id; + irqreturn_t ret = xrp_irq_handler(irq, &hw->xrp); + + if (ret == IRQ_HANDLED) + ack_irq(hw); + + return ret; +} + +#if defined(__XTENSA__) +static void clean_cache(void *vaddr, phys_addr_t paddr, unsigned long sz) +{ + __flush_dcache_range((unsigned long)vaddr, sz); +} + +static void flush_cache(void *vaddr, phys_addr_t paddr, unsigned long sz) +{ + __flush_dcache_range((unsigned long)vaddr, sz); + __invalidate_dcache_range((unsigned long)vaddr, sz); +} + +static void invalidate_cache(void *vaddr, phys_addr_t paddr, unsigned long sz) +{ + __invalidate_dcache_range((unsigned long)vaddr, sz); +} +#elif defined(__arm__) +static void clean_cache(void *vaddr, phys_addr_t paddr, unsigned long sz) +{ + __cpuc_flush_dcache_area(vaddr, sz); + outer_clean_range(paddr, paddr + sz); +} + +static void flush_cache(void *vaddr, phys_addr_t paddr, unsigned long sz) +{ + __cpuc_flush_dcache_area(vaddr, sz); + outer_flush_range(paddr, paddr + sz); +} + +static void invalidate_cache(void *vaddr, phys_addr_t paddr, unsigned long sz) +{ + __cpuc_flush_dcache_area(vaddr, sz); + outer_inv_range(paddr, paddr + sz); +} +#else +#warning "cache operations are not implemented for this architecture" +static void clean_cache(void *vaddr, phys_addr_t paddr, unsigned long sz) +{ +} + +static void flush_cache(void *vaddr, phys_addr_t paddr, unsigned long sz) +{ +} + +static void invalidate_cache(void *vaddr, phys_addr_t paddr, unsigned long sz) +{ +} +#endif + +static const struct xrp_hw_ops hw_ops = { + .halt = halt, + .release = release, + .reset = reset, + + .get_hw_sync_data = get_hw_sync_data, + + .send_irq = send_irq, + + .clean_cache = clean_cache, + .flush_cache = flush_cache, + .invalidate_cache = invalidate_cache, +}; + +static int init_hw_dct(struct platform_device *pdev, struct xrp_hw_dct *hw, + int mem_idx) +{ + struct resource *mem; + int irq; + int ret; + + hw->dsp_ctrl = syscon_regmap_lookup_by_compatible("dct,dct-dsp-ctrl"); + if (IS_ERR(hw->dsp_ctrl)) { + dev_err(&pdev->dev, "unable to get dsp ctrl regmap"); + return PTR_ERR(hw->dsp_ctrl); + } + + hw->scu_ctrl = syscon_regmap_lookup_by_compatible("dct,dct-dsp-syscon"); + if (IS_ERR(hw->scu_ctrl)) { + dev_err(&pdev->dev, "unable to get scu ctrl regmap"); + return PTR_ERR(hw->scu_ctrl); + } + +#if 0 + mem = platform_get_resource(pdev, IORESOURCE_MEM, mem_idx); + if (mem) { + hw->device_mmio_base = mem->start; + } else { + } + +#endif + + u32 device_mmio_base; + ret = of_property_read_u32(pdev->dev.of_node, + "device-mmio-base", + &device_mmio_base); + + if (ret < 0) { + dev_err(&pdev->dev, "device_mmio_base not specified\n"); + goto err; + } + hw->device_mmio_base = device_mmio_base; + + ret = of_property_read_u32(pdev->dev.of_node, + "device-irq", + &hw->device_irq); + if (ret == 0) { + ret = of_property_read_u32_array(pdev->dev.of_node, + "device-irq-ism", + hw->device_irq_ism, + ARRAY_SIZE(hw->device_irq_ism)); + } + if (ret == 0) { + ret = of_property_read_u32_array(pdev->dev.of_node, + "device-irq-ris", + hw->device_irq_ris, + ARRAY_SIZE(hw->device_irq_ris)); + } + if (ret == 0) { + ret = of_property_read_u32_array(pdev->dev.of_node, + "device-irq-mis", + hw->device_irq_mis, + ARRAY_SIZE(hw->device_irq_mis)); + } + if (ret == 0) { + ret = of_property_read_u32_array(pdev->dev.of_node, + "device-irq-isc", + hw->device_irq_isc, + ARRAY_SIZE(hw->device_irq_isc)); + } + if (ret == 0) { + ret = of_property_read_u32_array(pdev->dev.of_node, + "device-irq-iss", + hw->device_irq_iss, + ARRAY_SIZE(hw->device_irq_iss)); + } + if (ret == 0) { + u32 device_irq_mode; + + ret = of_property_read_u32(pdev->dev.of_node, + "device-irq-mode", + &device_irq_mode); + if (device_irq_mode < XRP_IRQ_MAX) + hw->device_irq_mode = device_irq_mode; + else + ret = -ENOENT; + } + if (ret == 0) { + dev_dbg(&pdev->dev, + "%s: device IRQ set offset = 0x%08x, set bit = %d, clear offset = 0x%08x, clear bit = %d, device IRQ = %d, IRQ mode = %d", + __func__, hw->device_irq_iss[0], hw->device_irq_iss[1], + hw->device_irq_isc[0], hw->device_irq_isc[1], + hw->device_irq, hw->device_irq_mode); + } else { + dev_info(&pdev->dev, + "using polling mode on the device side\n"); + } + + //host + ret = of_property_read_u32_array(pdev->dev.of_node, "host-irq", + hw->host_irq, + ARRAY_SIZE(hw->host_irq)); + if (ret == 0) { + ret = of_property_read_u32_array(pdev->dev.of_node, "host-irq-ism", + hw->host_irq_ism, + ARRAY_SIZE(hw->host_irq_ism)); + } + if (ret == 0) { + ret = of_property_read_u32_array(pdev->dev.of_node, "host-irq-ris", + hw->host_irq_ris, + ARRAY_SIZE(hw->host_irq_ris)); + } + if (ret == 0) { + ret = of_property_read_u32_array(pdev->dev.of_node, "host-irq-mis", + hw->host_irq_mis, + ARRAY_SIZE(hw->host_irq_mis)); + } + if (ret == 0) { + ret = of_property_read_u32_array(pdev->dev.of_node, "host-irq-isc", + hw->host_irq_isc, + ARRAY_SIZE(hw->host_irq_isc)); + } + if (ret == 0) { + ret = of_property_read_u32_array(pdev->dev.of_node, "host-irq-iss", + hw->host_irq_iss, + ARRAY_SIZE(hw->host_irq_iss)); + } + if (ret == 0) { + u32 host_irq_mode; + + ret = of_property_read_u32(pdev->dev.of_node, + "host-irq-mode", + &host_irq_mode); + if (host_irq_mode < XRP_IRQ_MAX) + hw->host_irq_mode = host_irq_mode; + else + ret = -ENOENT; + } + irq = platform_get_irq(pdev, 0); + if (irq >= 0 && ret == 0) { + dev_dbg(&pdev->dev, "%s: host IRQ = %d, ", + __func__, irq); + ret = devm_request_irq(&pdev->dev, irq, irq_handler, + IRQF_SHARED, pdev->name, hw); + if (ret < 0) { + dev_err(&pdev->dev, "request_irq %d failed\n", irq); + goto err; + } + hw->xrp.host_irq_mode = true; + } else { + dev_info(&pdev->dev, "using polling mode on the host side\n"); + } + + if (ret == 0) { + ret = of_property_read_u32_array(pdev->dev.of_node, "dsp-reset", + hw->dsp_reset, + ARRAY_SIZE(hw->dsp_reset)); + } + if (ret < 0) { + dev_err(&pdev->dev, "Unspecified reset.\n"); + goto err; + } + + if (ret == 0) { + ret = of_property_read_u32_array(pdev->dev.of_node, "dsp-runstall", + hw->dsp_runstall, + ARRAY_SIZE(hw->dsp_runstall)); + } + if (ret < 0) { + dev_err(&pdev->dev, "Unspecified runstall.\n"); + goto err; + } + ret = 0; +err: + return ret; +} + +static int init_dct(struct platform_device *pdev, struct xrp_hw_dct *hw) +{ + int ret; + + ret = init_hw_dct(pdev, hw, 2); + if (ret < 0) + return ret; + + return xrp_init_cma(pdev, &hw->xrp, &hw_ops, hw); +} + +#ifdef CONFIG_OF +static const struct of_device_id xrp_hw_dct_match[] = { + { + .compatible = "cdns,xrp-hw-dct,cma", + .data = init_dct, + }, {}, +}; +MODULE_DEVICE_TABLE(of, xrp_hw_dct_match); +#endif + +static int xrp_hw_dct_probe(struct platform_device *pdev) +{ + struct xrp_hw_dct *hw = + devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL); + const struct of_device_id *match; + int (*init)(struct platform_device *pdev, struct xrp_hw_dct *hw); + + if (!hw) + return -ENOMEM; + + match = of_match_device(of_match_ptr(xrp_hw_dct_match), + &pdev->dev); + if (!match) + return -ENODEV; + + init = match->data; + return init(pdev, hw); + +} + +static int xrp_hw_dct_remove(struct platform_device *pdev) +{ + return xrp_deinit(pdev); +} + +static const struct dev_pm_ops xrp_hw_dct_pm_ops = { + SET_RUNTIME_PM_OPS(xrp_runtime_suspend, + xrp_runtime_resume, NULL) +}; + +static struct platform_driver xrp_hw_dct_driver = { + .probe = xrp_hw_dct_probe, + .remove = xrp_hw_dct_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = of_match_ptr(xrp_hw_dct_match), + .pm = &xrp_hw_dct_pm_ops, + }, +}; + +module_platform_driver(xrp_hw_dct_driver); + +MODULE_AUTHOR("Max Filippov"); +MODULE_DESCRIPTION("XRP: low level device driver for Xtensa Remote Processing"); +MODULE_LICENSE("Dual MIT/GPL"); diff --git a/xrp-kernel/xrp_hw_dct_dsp_interface.h b/xrp-kernel/xrp_hw_dct_dsp_interface.h new file mode 100644 index 0000000..4812ad9 --- /dev/null +++ b/xrp-kernel/xrp_hw_dct_dsp_interface.h @@ -0,0 +1,58 @@ +/* + * XRP interface between hardware-specific linux and DSP parts of example + * hardware + * + * Copyright (c) 2017 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef _XRP_KERNEL_DCT_HW_DSP_INTERFACE +#define _XRP_KERNEL_DCT_HW_DSP_INTERFACE + +enum { + XRP_DSP_SYNC_IRQ_MODE_NONE = 0x0, + XRP_DSP_SYNC_IRQ_MODE_LEVEL = 0x1, + XRP_DSP_SYNC_IRQ_MODE_EDGE = 0x2, +}; + +//ZQI: +//get all individual register fields from dts +struct xrp_hw_dct_sync_data { + __u32 device_mmio_base; + __u32 device_irq_ism[2]; + __u32 device_irq_ris[2]; + __u32 device_irq_mis[2]; + __u32 device_irq_isc[2]; + __u32 device_irq_iss[2]; + __u32 device_irq_mode; + __u32 device_irq; + __u32 host_irq_ism[2]; + __u32 host_irq_ris[2]; + __u32 host_irq_mis[2]; + __u32 host_irq_isc[2]; + __u32 host_irq_iss[2]; + __u32 host_irq_mode; +}; + +#endif diff --git a/xrp-linux-native/Makefile.in b/xrp-linux-native/Makefile.in index f188b37..ed1ac53 100644 --- a/xrp-linux-native/Makefile.in +++ b/xrp-linux-native/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -39,7 +39,17 @@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -101,12 +111,12 @@ NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = xrp-linux-native -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/autoconf/depcomp $(include_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \ + $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @@ -204,6 +214,7 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/autoconf/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -292,6 +303,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -321,7 +333,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xrp-linux-native/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xrp-linux-native/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -625,6 +636,8 @@ uninstall-am: uninstall-includeHEADERS uninstall-libLIBRARIES mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-includeHEADERS uninstall-libLIBRARIES +.PRECIOUS: Makefile + # 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. diff --git a/xrp-linux-sim/Makefile.in b/xrp-linux-sim/Makefile.in index 381104b..1abc6cd 100644 --- a/xrp-linux-sim/Makefile.in +++ b/xrp-linux-sim/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -39,7 +39,17 @@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -101,12 +111,12 @@ NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = xrp-linux-sim -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/autoconf/depcomp $(include_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \ + $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @@ -205,6 +215,7 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/autoconf/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -293,6 +304,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -324,7 +336,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xrp-linux-sim/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign xrp-linux-sim/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -629,6 +640,8 @@ uninstall-am: uninstall-includeHEADERS uninstall-libLIBRARIES mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-includeHEADERS uninstall-libLIBRARIES +.PRECIOUS: Makefile + # 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.