diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index 886b53cf2d7a..16aae15274e9 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -61,4 +61,4 @@ jobs: cd workspace clang --verbose set -x - sof/scripts/fuzz.sh -b -c stub_build_all_${{ matrix.IPC }}.conf -- "$cmake_arg" + sof/scripts/fuzz.sh -b -- -DOVERLAY_CONFIG=stub_build_all_${{ matrix.IPC }}.conf diff --git a/.github/workflows/rimage.yml b/.github/workflows/rimage.yml new file mode 100644 index 000000000000..1806fab5f0cf --- /dev/null +++ b/.github/workflows/rimage.yml @@ -0,0 +1,60 @@ +--- +# SPDX-License-Identifier: BSD-3-Clause +# Tools that can save round-trips to github and a lot of time: +# +# yamllint -f parsable this.yml +# pip3 install ruamel.yaml.cmd +# yaml merge-expand this.yml exp.yml && diff -w -u this.yml exp.yml +# +# github.com also has a powerful web editor that can be used without +# committing. + +name: rimage + +# yamllint disable-line rule:truthy +on: + workflow_dispatch: + pull_request: + paths: + - tools/rimage/** + push: + paths: + - tools/rimage/** + +jobs: + + # Basic build test + build: + runs-on: ubuntu-22.04 + env: + # FIXME: add -Wpointer-arith + _CFLGS: -Werror -Wall -Wmissing-prototypes + -Wimplicit-fallthrough=3 + + + steps: + - uses: actions/checkout@v4 + with: {submodules: recursive, fetch-depth: 0, filter: 'tree:0'} + + - run: cmake -B build-rimage/ -S tools/rimage/ -DCMAKE_C_FLAGS="${_CFLGS}" + + # VERBOSE because CFLAGS (and -Wpointer-arith) used to be ignored + # for years and no one noticed + - run: cmake --build build-rimage/ -- -j$(nproc) VERBOSE=1 + + + # cppcheck + cppcheck: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: {submodules: recursive, fetch-depth: 0, filter: 'tree:0'} + + - name: apt install cppcheck + run: sudo apt update && sudo apt-get -y install cppcheck + + # TODO enable more types of checks as they are fixed + - name: run cppcheck + run: cppcheck --platform=unix32 --force --max-configs=1024 + --inconclusive --inline-suppr + --error-exitcode=1 tools/rimage/ diff --git a/.github/workflows/sparse-zephyr.yml b/.github/workflows/sparse-zephyr.yml index a0e7c8f3a0e7..9c63e11586fd 100644 --- a/.github/workflows/sparse-zephyr.yml +++ b/.github/workflows/sparse-zephyr.yml @@ -57,12 +57,15 @@ jobs: # --pristine is important to reproduce _warnings_. It makes no # difference for github but it's useful for anyone trying to # reproduce and copying the command from the logs. + # "sparse" is currently incompatible with PICOLIBC (the new Zephyr default), + # see https://github.com/zephyrproject-rtos/zephyr/issues/63003 - name: analyze zephyr working-directory: ./workspace run: | ./sof/zephyr/docker-run.sh \ ./sof/zephyr/docker-build.sh ${{ matrix.platform }} \ --cmake-args=-DZEPHYR_SCA_VARIANT=sparse --cmake-args=-DCONFIG_LOG_USE_VLA=n \ + --cmake-args=-DCONFIG_MINIMAL_LIBC=y \ --pristine 2>&1 | tee _.log printf '\n\n\t\t\t ---- Messages below are treated as sparse errors --- \n\n\n' diff --git a/.github/workflows/zephyr.yml b/.github/workflows/zephyr.yml index a1cb163c158d..5b2dd5798e14 100644 --- a/.github/workflows/zephyr.yml +++ b/.github/workflows/zephyr.yml @@ -107,11 +107,10 @@ jobs: IPC_platforms: [ # - IPC3 default imx8 imx8x imx8m, - tgl tgl-h, # UNSUPPORTED! Will be removed # - IPC4 default mtl, lnl, # Temporary testbed for Zephyr development. - -i IPC4 tgl tgl-h, + tgl tgl-h, ] build_opts: [""] # Sparse matrices are complicated, you must read this page slowly: @@ -134,7 +133,7 @@ jobs: - name: west clones run: pip3 install west && cd workspace/sof/ && west init -l && - west update --narrow --fetch-opt=--filter=tree:0 + time west update --narrow --fetch-opt=--filter=tree:0 - name: select zephyr revision run: | @@ -150,7 +149,7 @@ jobs: sed -e "s#=sof_zephyr_revision_override=#${rem_rev}#" \ sof-ci-jenkins/zephyr-override-template.yml > test-zephyr-main.yml ) - west update --narrow --fetch-opt=--filter=tree:0 + time west update --narrow --fetch-opt=--filter=tree:0 fi # Because we used git tricks to speed things up, we now have two git @@ -168,7 +167,7 @@ jobs: # both issues in no time. cd zephyr - git fetch --filter=tree:0 zephyrproject "$rem_rev":_branch_placeholder + time git fetch --filter=tree:0 "$(git remote |head -n1)" "$rem_rev":_branch_placeholder git branch -D _branch_placeholder set -x @@ -213,11 +212,9 @@ jobs: platforms: [ # - IPC3 default imx8 imx8x imx8m, - tgl tgl-h, # UNSUPPORTED! Will be removed # - IPC4 default mtl, - # Very few IPC3 platforms support IPC4 too. - -i IPC4 tgl tgl-h, + tgl tgl-h, ] build_opts: [""] # Sparse matrices are complicated, see comments on Linux matrix above. @@ -311,7 +308,7 @@ jobs: # Get some tags to fix `git describe`, see build-linux comments above. cd zephyr $_rev = "$(git rev-parse HEAD)" - git fetch --filter=tree:0 zephyrproject "${_rev}:_branch_placeholder" + git fetch --filter=tree:0 "$(west list -f '{url}' zephyr)" "${_rev}:_branch_placeholder" git branch -D _branch_placeholder @@ -329,7 +326,18 @@ jobs: working-directory: ${{ github.workspace }}/workspace run: pip install -r zephyr/scripts/requirements.txt + # Ninja has been coming and going, see #8250 + - name: choco install ninja + run: | + choco install ninja + ninja.exe --version + # MSYS2 provides gcc x64_86 toolchain & openssl + # Installs in D:/a/_temp/msys64 + # + # Note there is already C:/msys64/ provided by + # https://github.com/actions/runner-images/blob/win22/20230918.1/images/win/Windows2022-Readme.md + # Is it not good enough? Maybe it could save 20-30s. - name: Initialize MSYS2 uses: msys2/setup-msys2@v2 with: @@ -397,7 +405,7 @@ jobs: # http://mywiki.wooledge.org/ParsingLs for regdir in 'linux-build *mtl' \ 'windows-build *mtl' \ - 'windows-build *-i IPC4 tgl tgl-h'; do + 'windows-build *tgl tgl-h'; do find . -maxdepth 1 | grep -q "\./${regdir}\$" || { >&2 printf 'Missing %s\n' "${regdir}"; exit 1; } done diff --git a/.gitmodules b/.gitmodules index da3426a76e3d..99bed093e833 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,19 +1,17 @@ -[submodule "rimage"] - path = rimage -# This is a _relative_ submodule URL. In some use cases it's better than -# an _absolute_ submodule URL, in other cases it's not. One size does -# unfortunately not fit all. -# -# Among other pages, http://blog.tremily.us/posts/Relative_submodules/ -# has a good comparison -# -# If you use Zephyr you must also look at the comments in sof/west.yml. -# -# If you want to fork or mirror sof.git _without_ doing the same for -# rimage.git then your automation may want you to change and git commit -# an absolute URL in your branch. No need to git commit for interactive -# use; a local and temporary edit of this file is enough for interactive -# use because .gitmodules is used only once to --init[ialize] -# .git/config the first time. Then .gitmodules is never used again after -# cloning. - url = ../rimage +# This is required for non-Zephyr ("XTOS") configurations. Zephyr +# configs also get it from sof/west.yml which adds the burden of keeping +# both tomlc99 SHA1s synchronized but in practice this barely ever moves. +[submodule "tomlc99"] + path = tools/rimage/tomlc99 + # This is a _absolute_ submodule URL. In some use cases it's + # better than an _relative_ submodule URL, in other cases it's + # not. One size does unfortunately not fit all. Among other + # pages, http://blog.tremily.us/posts/Relative_submodules/ has a + # good comparison. + # + # A local and temporary edit of this url can be enough because + # .gitmodules is used _only once_ to submodule --init[ialize] + # .git/config the first time. Then .gitmodules is never used + # again after cloning tomlc99 the first time. + url = https://github.com/thesofproject/tomlc99.git + branch = master diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d951e86a2de..075d1a33c636 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,8 @@ project(SOF C ASM) set(SOF_ROOT_SOURCE_DIRECTORY "${PROJECT_SOURCE_DIR}") set(SOF_ROOT_BINARY_DIRECTORY "${PROJECT_BINARY_DIR}") +set(RIMAGE_TOP "${PROJECT_SOURCE_DIR}/tools/rimage") + # check git hooks include(scripts/cmake/git-hooks.cmake) @@ -159,8 +161,8 @@ install( ${PROJECT_SOURCE_DIR}/src/include/ipc ${PROJECT_SOURCE_DIR}/src/include/kernel ${PROJECT_SOURCE_DIR}/src/include/user - ${PROJECT_SOURCE_DIR}/rimage/src/include/sof/kernel - ${PROJECT_SOURCE_DIR}/rimage/src/include/sof/user + ${RIMAGE_TOP}/src/include/sof/kernel + ${RIMAGE_TOP}/src/include/sof/user DESTINATION include/sof PATTERN "*.h" ) diff --git a/app/boards/intel_adsp_ace15_mtpm.conf b/app/boards/intel_adsp_ace15_mtpm.conf index 8bbcc0278c58..7f0938bbdd5b 100644 --- a/app/boards/intel_adsp_ace15_mtpm.conf +++ b/app/boards/intel_adsp_ace15_mtpm.conf @@ -3,6 +3,7 @@ CONFIG_IPC_MAJOR_4=y CONFIG_COMP_SRC=y CONFIG_COMP_SRC_IPC4_FULL_MATRIX=y +CONFIG_COMP_SRC_LITE=y CONFIG_COMP_DRC=y CONFIG_COMP_CROSSOVER=y CONFIG_COMP_MULTIBAND_DRC=y @@ -67,6 +68,7 @@ CONFIG_SYS_CLOCK_TICKS_PER_SEC=12000 CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=38400000 CONFIG_LOG_BACKEND_ADSP_MTRACE=y +CONFIG_LOG_BACKEND_SOF_PROBE=n CONFIG_SOF_LOG_LEVEL_INF=y CONFIG_ZEPHYR_LOG=y CONFIG_LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP=y diff --git a/app/boards/intel_adsp_ace20_lnl.conf b/app/boards/intel_adsp_ace20_lnl.conf index b8affcf55f61..99016e3a539c 100644 --- a/app/boards/intel_adsp_ace20_lnl.conf +++ b/app/boards/intel_adsp_ace20_lnl.conf @@ -30,7 +30,6 @@ CONFIG_DAI_INTEL_SSP=y CONFIG_ZEPHYR_DP_SCHEDULER=y CONFIG_DMA=y CONFIG_DMA_INTEL_ADSP_GPDMA=n -CONFIG_DMA_DW_SUSPEND_DRAIN=y CONFIG_INTEL_MODULES=y CONFIG_LIBRARY_MANAGER=y CONFIG_INTEL_ADSP_TIMER=y @@ -58,6 +57,7 @@ CONFIG_LOG_FUNC_NAME_PREFIX_DBG=y CONFIG_COMP_VOLUME_WINDOWS_FADE=y CONFIG_COMP_UP_DOWN_MIXER=y CONFIG_COMP_CHAIN_DMA=y +CONFIG_SAMPLE_KEYPHRASE=y CONFIG_SYS_CLOCK_TICKS_PER_SEC=12000 CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=38400000 diff --git a/app/boards/intel_adsp_cavs25.conf b/app/boards/intel_adsp_cavs25.conf index 196726580e6a..c247fb8a339f 100644 --- a/app/boards/intel_adsp_cavs25.conf +++ b/app/boards/intel_adsp_cavs25.conf @@ -30,6 +30,7 @@ CONFIG_COMP_VOLUME_WINDOWS_FADE=y CONFIG_COMP_DRC=y CONFIG_COMP_CROSSOVER=y CONFIG_COMP_MULTIBAND_DRC=y +CONFIG_COMP_ARIA=y # route SOF logs to Zephyr logging subsystem CONFIG_SOF_LOG_LEVEL_INF=y diff --git a/app/boards/intel_adsp_cavs25_tgph.conf b/app/boards/intel_adsp_cavs25_tgph.conf index 47523b196375..2b110c073e43 100644 --- a/app/boards/intel_adsp_cavs25_tgph.conf +++ b/app/boards/intel_adsp_cavs25_tgph.conf @@ -29,6 +29,7 @@ CONFIG_COMP_VOLUME_WINDOWS_FADE=y CONFIG_COMP_DRC=y CONFIG_COMP_CROSSOVER=y CONFIG_COMP_MULTIBAND_DRC=y +CONFIG_COMP_ARIA=y # route SOF logs to Zephyr logging subsystem CONFIG_SOF_LOG_LEVEL_INF=y diff --git a/app/overlays/lnl/fpga_overlay.conf b/app/overlays/lnl/fpga_overlay.conf index 0fc3ac375789..eebbfee72648 100644 --- a/app/overlays/lnl/fpga_overlay.conf +++ b/app/overlays/lnl/fpga_overlay.conf @@ -1,2 +1,3 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=19200000 CONFIG_DAI_DMIC_HW_IOCLK=19200000 +CONFIG_XTENSA_CCOUNT_HZ=40000000 diff --git a/app/overlays/mtl/fpga_overlay.conf b/app/overlays/mtl/fpga_overlay.conf index 0fc3ac375789..eebbfee72648 100644 --- a/app/overlays/mtl/fpga_overlay.conf +++ b/app/overlays/mtl/fpga_overlay.conf @@ -1,2 +1,3 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=19200000 CONFIG_DAI_DMIC_HW_IOCLK=19200000 +CONFIG_XTENSA_CCOUNT_HZ=40000000 diff --git a/app/overlays/tgl-h/ipc4_overlay.conf b/app/overlays/tgl-h/ipc4_overlay.conf deleted file mode 100644 index fc4739a27eb6..000000000000 --- a/app/overlays/tgl-h/ipc4_overlay.conf +++ /dev/null @@ -1,5 +0,0 @@ -# This file is empty as IPC4 now the default. -# -# The file is kept around for the time being to -# smoothen the transition for users who use -# this overlay file in their build scripts. diff --git a/app/overlays/tgl/ipc4_overlay.conf b/app/overlays/tgl/ipc4_overlay.conf deleted file mode 100644 index fc4739a27eb6..000000000000 --- a/app/overlays/tgl/ipc4_overlay.conf +++ /dev/null @@ -1,5 +0,0 @@ -# This file is empty as IPC4 now the default. -# -# The file is kept around for the time being to -# smoothen the transition for users who use -# this overlay file in their build scripts. diff --git a/app/perf_overlay.conf b/app/perf_overlay.conf index 5c031fe97c59..cd7c16127788 100644 --- a/app/perf_overlay.conf +++ b/app/perf_overlay.conf @@ -1,2 +1,3 @@ CONFIG_PERFORMANCE_COUNTERS=y CONFIG_SYS_HEAP_RUNTIME_STATS=y +CONFIG_TIMING_FUNCTIONS=y \ No newline at end of file diff --git a/app/prj.conf b/app/prj.conf index 49b09f62789b..b3f1016620ea 100644 --- a/app/prj.conf +++ b/app/prj.conf @@ -14,6 +14,10 @@ CONFIG_OUTPUT_DISASSEMBLY=y CONFIG_HAVE_AGENT=n +# Since Zephyr commit f0daf904bb0202c PICOLIBC is the new default. +# We need more time to test and evaluate. +CONFIG_MINIMAL_LIBC=y + CONFIG_LOG=y CONFIG_LOG_PRINTK=y # Log processing is offloaded to a low-priority thread. diff --git a/app/stub_build_all_ipc3.conf b/app/stub_build_all_ipc3.conf index c64fc4790da1..b96ffe48adac 100644 --- a/app/stub_build_all_ipc3.conf +++ b/app/stub_build_all_ipc3.conf @@ -1,14 +1,17 @@ CONFIG_COMP_STUBS=y CONFIG_COMP_GOOGLE_RTC_AUDIO_PROCESSING=y -CONFIG_COMP_TONE=y +CONFIG_COMP_TONE=n CONFIG_COMP_CROSSOVER=y CONFIG_COMP_DRC=y CONFIG_COMP_MULTIBAND_DRC=y -CONFIG_COMP_SMART_AMP=y CONFIG_PASSTHROUGH_CODEC=y CONFIG_WAVES_CODEC=y CONFIG_DTS_CODEC=y CONFIG_COMP_IGO_NR=y CONFIG_COMP_RTNR=y -CONFIG_COMP_SMART_AMP=y +# temporarily disabled until it compiles: +# sof/src/audio/smart_amp/smart_amp.c:748:9: error: +# no member named 'in_channels' in 'struct smart_amp_data' +# sad->in_channels = audio_stream_get_channels(&source_buffer->stream); +CONFIG_COMP_SMART_AMP=n CONFIG_MAXIM_DSM=y diff --git a/app/stub_build_all_ipc4.conf b/app/stub_build_all_ipc4.conf index f111940b17b6..178b70388c01 100644 --- a/app/stub_build_all_ipc4.conf +++ b/app/stub_build_all_ipc4.conf @@ -1,5 +1,5 @@ --DCONFIG_COMP_STUBS=y --DCONFIG_COMP_ARIA=y --DCONFIG_COMP_CHAIN_DMA=y --DCONFIG_COMP_UP_DOWN_MIXER=y --DCONFIG_IPC_MAJOR_4=y +CONFIG_COMP_STUBS=y +CONFIG_COMP_ARIA=y +CONFIG_COMP_CHAIN_DMA=y +CONFIG_COMP_UP_DOWN_MIXER=y +CONFIG_IPC_MAJOR_4=y diff --git a/installer/GNUmakefile b/installer/GNUmakefile index 3caaab5eb3b5..d041c5bd3c8f 100644 --- a/installer/GNUmakefile +++ b/installer/GNUmakefile @@ -301,10 +301,8 @@ COMPARE_REFS ?= /lib/firmware/intel checktree: cd ${STAGING_SOF_VERSION} && \ tree -a -v --dirsfirst . > ${BUILDS_ROOT}/staging_sof_tree.txt - # Update sof-cavs-nocodec.tplg when adding or removing a default platform diff -u tests/staging_sof${IPC_VERSION}_ref.txt ${BUILDS_ROOT}/staging_sof_tree.txt # Check two random topologies are there - test -f ${STAGING_SOF_TPLG}/sof-tgl-nocodec.tplg test -f ${STAGING_SOF_TPLG}/sof-imx8-wm8960.tplg for t in sof-ctl sof-logger sof-probes; do \ test -f ${STAGING_TOOLS}${VERSION_SUFFIX}/$${t}; done diff --git a/posix/include/CMakeLists.txt b/posix/include/CMakeLists.txt new file mode 100644 index 000000000000..fd819740233b --- /dev/null +++ b/posix/include/CMakeLists.txt @@ -0,0 +1 @@ +target_include_directories(sof_public_headers INTERFACE include) diff --git a/posix/include/rtos/alloc.h b/posix/include/rtos/alloc.h new file mode 100644 index 000000000000..d64ea319f48e --- /dev/null +++ b/posix/include/rtos/alloc.h @@ -0,0 +1,172 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + * Keyon Jie + */ + +/** + * \file xtos/include/rtos/alloc.h + * \brief Memory Allocation API definition + * \author Liam Girdwood + * \author Keyon Jie + */ + +#ifndef __SOF_LIB_ALLOC_H__ +#define __SOF_LIB_ALLOC_H__ + +#include +#include +#include +#include + +#include +#include + +/** \addtogroup alloc_api Memory Allocation API + * @{ + */ + +/** + * \brief Heap Memory Zones + * + * The heap has three different zones from where memory can be allocated :- + * + * 1) System Zone. Fixed size heap where alloc always succeeds and is never + * freed. Used by any init code that will never give up the memory. + * + * 2) System Runtime Zone. Heap zone intended for runtime objects allocated + * by the kernel part of the code. + * + * 3) Runtime Zone. Main and larger heap zone where allocs are not guaranteed to + * succeed. Memory can be freed here. + * + * 4) Buffer Zone. Largest heap zone intended for audio buffers. + * + * 5) Runtime Shared Zone. Similar to Runtime Zone, but content may be used and + * fred from any enabled core. + * + * 6) System Shared Zone. Similar to System Zone, but content may be used from + * any enabled core. + * + * See platform/memory.h for heap size configuration and mappings. + */ +enum mem_zone { + SOF_MEM_ZONE_SYS = 0, /**< System zone */ + SOF_MEM_ZONE_SYS_RUNTIME, /**< System-runtime zone */ + SOF_MEM_ZONE_RUNTIME, /**< Runtime zone */ + SOF_MEM_ZONE_BUFFER, /**< Buffer zone */ + SOF_MEM_ZONE_RUNTIME_SHARED, /**< Runtime shared zone */ + SOF_MEM_ZONE_SYS_SHARED, /**< System shared zone */ +}; + +/** \name Heap zone flags + * @{ + */ + +/** \brief Indicates that original content should not be copied by realloc. */ +#define SOF_MEM_FLAG_NO_COPY BIT(1) +/** \brief Indicates that if we should return uncached address. */ +#define SOF_MEM_FLAG_COHERENT BIT(2) + +/** @} */ + +/** + * Allocates memory block. + * @param zone Zone to allocate memory from, see enum mem_zone. + * @param flags Flags, see SOF_MEM_FLAG_... + * @param caps Capabilities, see SOF_MEM_CAPS_... + * @param bytes Size in bytes. + * @return Pointer to the allocated memory or NULL if failed. + * + * @note Do not use for buffers (SOF_MEM_ZONE_BUFFER zone). + * Use rballoc(), rballoc_align() to allocate memory for buffers. + */ +void *rmalloc(enum mem_zone zone, uint32_t flags, uint32_t caps, size_t bytes); + +/** + * Similar to rmalloc(), guarantees that returned block is zeroed. + * + * @note Do not use for buffers (SOF_MEM_ZONE_BUFFER zone). + * rballoc(), rballoc_align() to allocate memory for buffers. + */ +void *rzalloc(enum mem_zone zone, uint32_t flags, uint32_t caps, size_t bytes); + +/** + * Allocates memory block from SOF_MEM_ZONE_BUFFER. + * @param flags Flags, see SOF_MEM_FLAG_... + * @param caps Capabilities, see SOF_MEM_CAPS_... + * @param bytes Size in bytes. + * @param alignment Alignment in bytes. + * @return Pointer to the allocated memory or NULL if failed. + */ +void *rballoc_align(uint32_t flags, uint32_t caps, size_t bytes, + uint32_t alignment); + +/** + * Similar to rballoc_align(), returns buffer aligned to PLATFORM_DCACHE_ALIGN. + */ +static inline void *rballoc(uint32_t flags, uint32_t caps, size_t bytes) +{ + return rballoc_align(flags, caps, bytes, PLATFORM_DCACHE_ALIGN); +} + +/** + * Changes size of the memory block allocated from SOF_MEM_ZONE_BUFFER. + * @param ptr Address of the block to resize. + * @param flags Flags, see SOF_MEM_FLAG_... + * @param caps Capabilities, see SOF_MEM_CAPS_... + * @param bytes New size in bytes. + * @param old_bytes Old size in bytes. + * @param alignment Alignment in bytes. + * @return Pointer to the resized memory of NULL if failed. + */ +void *rbrealloc_align(void *ptr, uint32_t flags, uint32_t caps, size_t bytes, + size_t old_bytes, uint32_t alignment); + +/** + * Similar to rballoc_align(), returns resized buffer aligned to + * PLATFORM_DCACHE_ALIGN. + */ +static inline void *rbrealloc(void *ptr, uint32_t flags, uint32_t caps, + size_t bytes, size_t old_bytes) +{ + return rbrealloc_align(ptr, flags, caps, bytes, old_bytes, + PLATFORM_DCACHE_ALIGN); +} + +/** + * Frees the memory block. + * @param ptr Pointer to the memory block. + * + * @note Blocks from SOF_MEM_ZONE_SYS cannot be freed, such a call causes + * panic. + */ +void rfree(void *ptr); + +/** + * Allocates memory block from the system heap reserved for the specified core. + * @param core Core id. + * @param bytes Size in bytes. + */ +void *rzalloc_core_sys(int core, size_t bytes); + +/** + * Calculates length of the null-terminated string. + * @param s String. + * @return Length of the string in bytes. + */ +int rstrlen(const char *s); + +/** + * Compares two strings, see man strcmp. + * @param s1 First string to compare. + * @param s2 Second string to compare. + * @return See man strcmp. + */ +int rstrcmp(const char *s1, const char *s2); + +/** @}*/ + +#endif /* __SOF_LIB_ALLOC_H__ */ diff --git a/posix/include/rtos/atomic.h b/posix/include/rtos/atomic.h new file mode 100644 index 000000000000..6d16b6b6c9e6 --- /dev/null +++ b/posix/include/rtos/atomic.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2018 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + */ + +#ifndef __SOF_ATOMIC_H__ +#define __SOF_ATOMIC_H__ + +#include +#include + +static inline void atomic_init(atomic_t *a, int32_t value) +{ + arch_atomic_init(a, value); +} + +static inline int32_t atomic_read(const atomic_t *a) +{ + return arch_atomic_read(a); +} + +static inline void atomic_set(atomic_t *a, int32_t value) +{ + arch_atomic_set(a, value); +} + +static inline int32_t atomic_add(atomic_t *a, int32_t value) +{ + return arch_atomic_add(a, value); +} + +static inline int32_t atomic_sub(atomic_t *a, int32_t value) +{ + return arch_atomic_sub(a, value); +} + +#endif /* __SOF_ATOMIC_H__ */ diff --git a/posix/include/rtos/bit.h b/posix/include/rtos/bit.h new file mode 100644 index 000000000000..3dde908c2d6b --- /dev/null +++ b/posix/include/rtos/bit.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2018 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + */ + +#ifndef __XTOS_RTOS_BIT_H__ +#define __XTOS_RTOS_BIT_H__ + +#if ASSEMBLY +#define BIT(b) (1 << (b)) +#else +#define BIT(b) (1UL << (b)) +#endif + +#define MASK(b_hi, b_lo) \ + (((1ULL << ((b_hi) - (b_lo) + 1ULL)) - 1ULL) << (b_lo)) +#define SET_BIT(b, x) (((x) & 1) << (b)) +#define SET_BITS(b_hi, b_lo, x) \ + (((x) & ((1ULL << ((b_hi) - (b_lo) + 1ULL)) - 1ULL)) << (b_lo)) +#define GET_BIT(b, x) \ + (((x) & (1ULL << (b))) >> (b)) +#define GET_BITS(b_hi, b_lo, x) \ + (((x) & MASK(b_hi, b_lo)) >> (b_lo)) + +#endif /* __XTOS_RTOS_BIT_H__ */ diff --git a/posix/include/rtos/cache.h b/posix/include/rtos/cache.h new file mode 100644 index 000000000000..914e61b52984 --- /dev/null +++ b/posix/include/rtos/cache.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + * + * Author: Tomasz Lauda + */ + +/** + * \file xtos/include/rtos/cache.h + * \brief Cache header file + * \authors Tomasz Lauda + */ + +#ifndef __SOF_LIB_CACHE_H__ +#define __SOF_LIB_CACHE_H__ + +#include + +/* writeback and invalidate data */ +#define CACHE_WRITEBACK_INV 0 + +/* invalidate data */ +#define CACHE_INVALIDATE 1 + +#endif /* __SOF_LIB_CACHE_H__ */ diff --git a/posix/include/rtos/clk.h b/posix/include/rtos/clk.h new file mode 100644 index 000000000000..e9a36796bc42 --- /dev/null +++ b/posix/include/rtos/clk.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + * Janusz Jankowski + */ + +#ifndef __SOF_LIB_CLK_H__ +#define __SOF_LIB_CLK_H__ + +#include +#include +#include +#include +#include + +struct timer; + +#define CLOCK_NOTIFY_PRE 0 +#define CLOCK_NOTIFY_POST 1 + +struct clock_notify_data { + uint32_t old_freq; + uint32_t old_ticks_per_msec; + uint32_t freq; + uint32_t ticks_per_msec; + uint32_t message; +}; + +struct freq_table { + uint32_t freq; + uint32_t ticks_per_msec; +}; + +struct clock_info { + uint32_t freqs_num; + const struct freq_table *freqs; + uint32_t default_freq_idx; + uint32_t current_freq_idx; + uint32_t lowest_freq_idx; /* lowest possible clock */ + uint32_t notification_id; + uint32_t notification_mask; + + /* persistent change clock value in active state, caller must hold clk_lock */ + int (*set_freq)(int clock, int freq_idx); + + /* temporary change clock - don't modify default clock settings */ + void (*low_power_mode)(int clock, bool enable); +}; + +uint32_t clock_get_freq(int clock); + +void clock_set_freq(int clock, uint32_t hz); + +void clock_low_power_mode(int clock, bool enable); + +uint64_t clock_ms_to_ticks(int clock, uint64_t ms); + +uint64_t clock_us_to_ticks(int clock, uint64_t us); + +uint64_t clock_ns_to_ticks(int clock, uint64_t ns); + +uint64_t clock_ticks_per_sample(int clock, uint32_t sample_rate); + +extern struct k_spinlock clk_lock; + +static inline k_spinlock_key_t clock_lock(void) +{ + return k_spin_lock(&clk_lock); +} + +static inline void clock_unlock(k_spinlock_key_t key) +{ + k_spin_unlock(&clk_lock, key); +} + +static inline struct clock_info *clocks_get(void) +{ + return sof_get()->clocks; +} + +#endif /* __SOF_LIB_CLK_H__ */ diff --git a/posix/include/rtos/idc.h b/posix/include/rtos/idc.h new file mode 100644 index 000000000000..d6dd69f3e9e9 --- /dev/null +++ b/posix/include/rtos/idc.h @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2018 Intel Corporation. All rights reserved. + * + * Author: Tomasz Lauda + */ + +/** + * \file include/rtos/idc.h + * \brief IDC header file + * \authors Tomasz Lauda + */ + +#ifndef __POSIX_RTOS_IDC_H__ +#define __POSIX_RTOS_IDC_H__ + +#include +#include +#include +#include +#include +#include +#include + +/** \brief IDC send blocking flag. */ +#define IDC_BLOCKING 0 + +/** \brief IDC send non-blocking flag. */ +#define IDC_NON_BLOCKING 1 + +/** \brief IDC send core power up flag. */ +#define IDC_POWER_UP 2 + +/** \brief IDC send core power down flag. */ +#define IDC_POWER_DOWN 3 + +/** \brief IDC send timeout in microseconds. */ +#define IDC_TIMEOUT 10000 + +/** \brief IDC task deadline. */ +#define IDC_DEADLINE 100 + +/** \brief ROM wake version parsed by ROM during core wake up. */ +#define IDC_ROM_WAKE_VERSION 0x2 + +/** \brief IDC message type. */ +#define IDC_TYPE_SHIFT 24 +#define IDC_TYPE_MASK 0x7f +#define IDC_TYPE(x) (((x) & IDC_TYPE_MASK) << IDC_TYPE_SHIFT) + +#define IDC_MSG_BIND IDC_TYPE(0xD) +#define IDC_MSG_UNBIND IDC_TYPE(0xE) +#define IDC_MSG_GET_ATTRIBUTE IDC_TYPE(0xF) + +/** \brief IDC pipeline set state message. */ +#define IDC_MSG_PPL_STATE IDC_TYPE(0xC) +#define IDC_PPL_STATE_PPL_ID_SHIFT 0 +#define IDC_PPL_STATE_PPL_ID_MASK MASK(23, 0) +#define IDC_PPL_STATE_PHASE_SHIFT 24 +#define IDC_PPL_STATE_PHASE_MASK MASK(27, 24) +#define IDC_PPL_STATE_PHASE_SET(x) (((x) << IDC_PPL_STATE_PHASE_SHIFT) & \ + IDC_PPL_STATE_PHASE_MASK) +#define IDC_PPL_STATE_PHASE_GET(x) (((x) & IDC_PPL_STATE_PHASE_MASK) >> \ + IDC_PPL_STATE_PHASE_SHIFT) +#define IDC_PPL_STATE_PHASE_PREPARE BIT(0) +#define IDC_PPL_STATE_PHASE_TRIGGER BIT(1) +#define IDC_PPL_STATE_PHASE_ONESHOT (IDC_PPL_STATE_PHASE_PREPARE | \ + IDC_PPL_STATE_PHASE_TRIGGER) + +#define IDC_MSG_PPL_STATE_EXT(_ppl_id, _action) \ + IDC_EXTENSION(((_ppl_id) & IDC_PPL_STATE_PPL_ID_MASK) | \ + IDC_PPL_STATE_PHASE_SET(_action)) + +/** \brief IDC message header. */ +#define IDC_HEADER_MASK 0xffffff +#define IDC_HEADER(x) ((x) & IDC_HEADER_MASK) + +/** \brief IDC message extension. */ +#define IDC_EXTENSION_MASK 0x3fffffff +#define IDC_EXTENSION(x) ((x) & IDC_EXTENSION_MASK) + +/** \brief IDC power up message. */ +#define IDC_MSG_POWER_UP (IDC_TYPE(0x1) | \ + IDC_HEADER(IDC_ROM_WAKE_VERSION)) +#define IDC_MSG_POWER_UP_EXT IDC_EXTENSION(SOF_TEXT_START >> 2) + +/** \brief IDC power down message. */ +#define IDC_MSG_POWER_DOWN IDC_TYPE(0x2) +#define IDC_MSG_POWER_DOWN_EXT IDC_EXTENSION(0x0) + +/** \brief IDC notify message. */ +#define IDC_MSG_NOTIFY IDC_TYPE(0x3) +#define IDC_MSG_NOTIFY_EXT IDC_EXTENSION(0x0) + +/** \brief IDC IPC processing message. */ +#define IDC_MSG_IPC IDC_TYPE(0x4) +#define IDC_MSG_IPC_EXT IDC_EXTENSION(0x0) + +/** \brief IDC component params message. */ +#define IDC_MSG_PARAMS IDC_TYPE(0x5) +#define IDC_MSG_PARAMS_EXT(x) IDC_EXTENSION(x) + +/** \brief IDC component prepare message. */ +#define IDC_MSG_PREPARE IDC_TYPE(0x6) +#define IDC_MSG_PREPARE_EXT(x) IDC_EXTENSION(x) + +/** \brief IDC component trigger message. */ +#define IDC_MSG_TRIGGER IDC_TYPE(0x7) +#define IDC_MSG_TRIGGER_EXT(x) IDC_EXTENSION(x) + +/** \brief IDC component reset message. */ +#define IDC_MSG_RESET IDC_TYPE(0x8) +#define IDC_MSG_RESET_EXT(x) IDC_EXTENSION(x) + +/** \brief IDC prepare D0ix message. */ +#define IDC_MSG_PREPARE_D0ix IDC_TYPE(0x9) +#define IDC_MSG_PREPARE_D0ix_EXT IDC_EXTENSION(0x0) + +/** \brief IDC secondary core crashed notify message. */ +#define IDC_MSG_SECONDARY_CORE_CRASHED IDC_TYPE(0xA) +#define IDC_MSG_SECONDARY_CORE_CRASHED_EXT(x) IDC_EXTENSION(x) + +/** \brief IDC process async msg */ +#define IDC_MSG_AMS IDC_TYPE(0xB) +#define IDC_MSG_AMS_EXT IDC_EXTENSION(0x0) + +#define IDC_HEADER_TO_AMS_SLOT_MASK(x) (x & 0xFFFF) + +/** \brief IDC_MSG_SECONDARY_CORE_CRASHED header fields. */ +#define IDC_SCC_CORE_SHIFT 0 +#define IDC_SCC_CORE_MASK 0xff +#define IDC_SCC_CORE(x) (((x) & IDC_SCC_CORE_MASK) << IDC_SCC_CORE_SHIFT) + +#define IDC_SCC_REASON_SHIFT 8 +#define IDC_SCC_REASON_MASK 0xff +#define IDC_SCC_REASON(x) (((x) & IDC_SCC_REASON_MASK) << IDC_SCC_REASON_SHIFT) + +/** \brief Secondary core crash reasons. */ +#define IDC_SCC_REASON_WATCHDOG 0x00 +#define IDC_SCC_REASON_EXCEPTION 0x01 + +/** \brief Decodes IDC message type. */ +#define iTS(x) (((x) >> IDC_TYPE_SHIFT) & IDC_TYPE_MASK) + +/** \brief Max IDC message payload size in bytes. */ +#define IDC_MAX_PAYLOAD_SIZE (DCACHE_LINE_SIZE * 2) + +/** \brief IDC free function flags */ +#define IDC_FREE_IRQ_ONLY BIT(0) /**< disable only irqs */ + +/** \brief IDC message payload. */ +struct idc_payload { + uint8_t data[IDC_MAX_PAYLOAD_SIZE]; +}; + +/** \brief IDC message. */ +struct idc_msg { + uint32_t header; /**< header value */ + uint32_t extension; /**< extension value */ + uint32_t core; /**< core id */ + uint32_t size; /**< payload size in bytes */ + void *payload; /**< pointer to payload data */ +}; + +/** \brief IDC data. */ +struct idc { + uint32_t busy_bit_mask; /**< busy interrupt mask */ + struct idc_msg received_msg; /**< received message */ + struct task idc_task; /**< IDC processing task */ + struct idc_payload *payload; + int irq; +}; + +/* idc trace context, used by multiple units */ +extern struct tr_ctx idc_tr; + +static inline struct idc_payload *idc_payload_get(struct idc *idc, + uint32_t core) +{ + return idc->payload + core; +} + +void idc_enable_interrupts(int target_core, int source_core); + +void idc_free(uint32_t flags); + +int platform_idc_init(void); + +int platform_idc_restore(void); + +enum task_state idc_do_cmd(void *data); + +void idc_cmd(struct idc_msg *msg); + +int idc_wait_in_blocking_mode(uint32_t target_core, bool (*cond)(int)); + +int idc_msg_status_get(uint32_t core); + +void idc_init_thread(void); + +#endif /* __POSIX_RTOS_IDC_H__ */ diff --git a/posix/include/rtos/init.h b/posix/include/rtos/init.h new file mode 100644 index 000000000000..7744d6b5b1f3 --- /dev/null +++ b/posix/include/rtos/init.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright(c) 2023 Intel Corporation. All rights reserved. + */ + +#ifndef __POSIX_RTOS_INIT_H__ +#define __POSIX_RTOS_INIT_H__ + +#define SOF_MODULE_INIT(name, init) + +#endif /* __POSIX_RTOS_INIT_H__ */ diff --git a/posix/include/rtos/interrupt.h b/posix/include/rtos/interrupt.h new file mode 100644 index 000000000000..839b4bef3ca3 --- /dev/null +++ b/posix/include/rtos/interrupt.h @@ -0,0 +1,217 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2018 Intel Corporation. All rights reserved. + * + * Author: Janusz Jankowski + */ + +#ifndef __SOF_DRIVERS_INTERRUPT_H__ +#define __SOF_DRIVERS_INTERRUPT_H__ + +#include + +#if !defined(__ASSEMBLER__) && !defined(LINKER) +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * \brief child IRQ descriptor for cascading IRQ controllers. + */ +struct irq_child { + int enable_count[CONFIG_CORE_COUNT]; /**< IRQ enable counter */ + struct list_item list; /**< head for IRQ descriptors, + * sharing this interrupt + */ +}; + +/** + * \brief interrupt client descriptor + */ +struct irq_desc { + int irq; /**< virtual IRQ number */ + void (*handler)(void *arg); /**< interrupt handler function */ + void *handler_arg; /**< interrupt handler argument */ + uint32_t cpu_mask; /**< a mask of CPUs on which this + * interrupt is enabled + */ + struct list_item irq_list; /**< to link to other irq_desc */ +}; + +/** + * \brief cascading IRQ controller operations. + */ +struct irq_cascade_ops { + void (*mask)(struct irq_desc *desc, uint32_t irq, + unsigned int cpu); /**< mask */ + void (*unmask)(struct irq_desc *desc, uint32_t irq, + unsigned int cpu); /**< unmask */ +}; + +/** + * \brief cascading interrupt controller descriptor. + */ +struct irq_cascade_desc { + const char *name; /**< name of the + * controller + */ + int irq_base; /**< first virtual IRQ + * number, assigned to + * this controller + */ + const struct irq_cascade_ops *ops; /**< cascading interrupt + * controller driver + * operations + */ + struct irq_desc desc; /**< the interrupt, that + * this controller is + * generating + */ + struct irq_cascade_desc *next; /**< link to the global + * list of interrupt + * controllers + */ + bool global_mask; /**< the controller + * cannot mask input + * interrupts per core + */ + struct k_spinlock lock; /**< protect child + * lists, enable and + * child counters + */ + int enable_count[CONFIG_CORE_COUNT]; /**< enabled child + * interrupt counter + */ + unsigned int num_children[CONFIG_CORE_COUNT]; /**< number of children + */ + struct irq_child child[PLATFORM_IRQ_CHILDREN]; /**< array of child + * lists - one per + * multiplexed IRQ + */ +}; + +/* A descriptor for cascading interrupt controller template */ +struct irq_cascade_tmpl { + const char *name; + const struct irq_cascade_ops *ops; + int irq; + void (*handler)(void *arg); + bool global_mask; +}; + +/** + * \brief Cascading interrupt controller root. + */ +struct cascade_root { + struct k_spinlock lock; /**< locking mechanism */ + struct irq_cascade_desc *list; /**< list of child cascade irqs */ + int last_irq; /**< last registered cascade irq */ +}; + +static inline struct cascade_root *cascade_root_get(void) +{ + return sof_get()->cascade_root; +} + +/* For i.MX, while building SOF with Zephyr use the interrupt_* + * functions from second level interrupt handling and IRQ_STEER. + */ +#if defined(__ZEPHYR__) && defined(CONFIG_IMX) +int mux_interrupt_get_irq(unsigned int irq, const char *cascade); +int mux_interrupt_register(uint32_t irq, void(*handler)(void *arg), void *arg); +void mux_interrupt_unregister(uint32_t irq, const void *arg); +uint32_t mux_interrupt_enable(uint32_t irq, void *arg); +uint32_t mux_interrupt_disable(uint32_t irq, void *arg); +#endif + +int interrupt_register(uint32_t irq, void(*handler)(void *arg), void *arg); +void interrupt_unregister(uint32_t irq, const void *arg); +uint32_t interrupt_enable(uint32_t irq, void *arg); +uint32_t interrupt_disable(uint32_t irq, void *arg); + +/* Zephyr compat */ +#if !defined(__ZEPHYR__) +#define arch_irq_lock() arch_interrupt_disable_mask(0xffffffff) +#endif + +void platform_interrupt_init(void); + +void platform_interrupt_set(uint32_t irq); +void platform_interrupt_clear(uint32_t irq, uint32_t mask); +uint32_t platform_interrupt_get_enabled(void); +void interrupt_mask(uint32_t irq, unsigned int cpu); +void interrupt_unmask(uint32_t irq, unsigned int cpu); + +/* + * On platforms, supporting cascading interrupts cascaded interrupt numbers + * are greater than or equal to PLATFORM_IRQ_HW_NUM + */ +#define interrupt_is_dsp_direct(irq) (!PLATFORM_IRQ_CHILDREN || \ + irq < PLATFORM_IRQ_HW_NUM) + +void interrupt_init(struct sof *sof); +int interrupt_cascade_register(const struct irq_cascade_tmpl *tmpl); +struct irq_cascade_desc *interrupt_get_parent(uint32_t irq); +int interrupt_get_irq(unsigned int irq, const char *cascade); + +static inline void interrupt_set(int irq) +{ + platform_interrupt_set(irq); +} + +static inline void interrupt_clear_mask(int irq, uint32_t mask) +{ + platform_interrupt_clear(irq, mask); +} + +static inline void interrupt_clear(int irq) +{ + interrupt_clear_mask(irq, 1); +} + +static inline uint32_t interrupt_global_disable(void) +{ + return arch_interrupt_global_disable(); +} + +static inline void interrupt_global_enable(uint32_t flags) +{ + arch_interrupt_global_enable(flags); +} + +#if CONFIG_LIBRARY + +/* temporary fix to remove build warning for testbench that will need shortly + * realigned when Zephyr native APIs are used. + */ +static inline void __irq_local_disable(unsigned long flags) {} +static inline void __irq_local_enable(unsigned long flags) {} + +/* disables all IRQ sources on current core - NO effect on library */ +#define irq_local_disable(flags) \ + do { \ + flags = 0; \ + __irq_local_disable(flags); \ + } while (0) + +/* re-enables IRQ sources on current core - NO effect on library*/ +#define irq_local_enable(flags) \ + __irq_local_enable(flags) + +#else +/* disables all IRQ sources on current core */ +#define irq_local_disable(flags) \ + (flags = interrupt_global_disable()) + +/* re-enables IRQ sources on current core */ +#define irq_local_enable(flags) \ + interrupt_global_enable(flags) +#endif +#endif +#endif /* __SOF_DRIVERS_INTERRUPT_H__ */ diff --git a/posix/include/rtos/kernel.h b/posix/include/rtos/kernel.h new file mode 100644 index 000000000000..5921d86b0012 --- /dev/null +++ b/posix/include/rtos/kernel.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 Intel Corporation. All rights reserved. + * + * Author: Jyri Sarha + */ + +#ifndef __POSIX_RTOS_KERNEL_H__ +#define __POSIX_RTOS_KERNEL_H__ + +#include + +#include + +#ifdef __ZEPHYR__ +#error "This file should only be included in XTOS builds." +#endif + +typedef uint32_t k_ticks_t; + +typedef struct { + k_ticks_t ticks; +} k_timeout_t; + +#define Z_TIMEOUT_TICKS(t) ((k_timeout_t) { .ticks = (t) }) + +#define Z_TIMEOUT_US(t) ((k_timeout_t) { .ticks = clock_us_to_ticks(PLATFORM_DEFAULT_CLOCK, t) }) + +#define Z_TIMEOUT_MS(t) ((k_timeout_t) { .ticks = clock_ms_to_ticks(PLATFORM_DEFAULT_CLOCK, t) }) + +static inline void k_sleep(k_timeout_t timeout) +{ + wait_delay(timeout.ticks); +} + +static inline void k_msleep(int32_t ms) +{ + wait_delay_ms(ms); +} + +static inline void k_usleep(int32_t us) +{ + wait_delay_us(us); +} + +#endif /* __POSIX_RTOS_KERNEL_H__ */ diff --git a/posix/include/rtos/mutex.h b/posix/include/rtos/mutex.h new file mode 100644 index 000000000000..16c773f4cae4 --- /dev/null +++ b/posix/include/rtos/mutex.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 Intel Corporation. All rights reserved. + * + */ + +/* + * Simple mutex implementation for SOF. + */ + +#ifndef __POSIX_RTOS_MUTEX_H +#define __POSIX_RTOS_MUTEX_H + +#include +#include +#include + +#define K_FOREVER ((k_timeout_t) { .ticks = 0xffffffff }) + +struct k_mutex { + struct k_spinlock lock; + k_spinlock_key_t key; +}; + +static inline int k_mutex_init(struct k_mutex *mutex) +{ + k_spinlock_init(&mutex->lock); + return 0; +} + +static inline int k_mutex_lock(struct k_mutex *mutex, k_timeout_t timeout) +{ + mutex->key = k_spin_lock(&mutex->lock); + return 0; +} + +static inline int k_mutex_unlock(struct k_mutex *mutex) +{ + k_spin_unlock(&mutex->lock, mutex->key); + return 0; +} + +#endif diff --git a/posix/include/rtos/panic.h b/posix/include/rtos/panic.h new file mode 100644 index 000000000000..65b06a1cab43 --- /dev/null +++ b/posix/include/rtos/panic.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright 2023 NXP + * Copyright(c) 2018 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + */ + +#ifndef __POSIX_RTOS_PANIC_H__ +#define __POSIX_RTOS_PANIC_H__ + +#include +#include +#include + +#ifdef __ZEPHYR__ +#error "This file should only be included in XTOS builds." +#endif /* __ZEPHYR__ */ + +#ifdef __clang_analyzer__ +#define SOF_NORETURN __attribute__((analyzer_noreturn)) +#elif __GNUC__ +#define SOF_NORETURN __attribute__((noreturn)) +#else +#define SOF_NORETURN +#endif + +#ifndef RELATIVE_FILE +#error "This file requires RELATIVE_FILE to be defined. "\ + "Add it to CMake's target with sof_append_relative_path_definitions." +#endif + +void dump_panicinfo(void *addr, struct sof_ipc_panic_info *panic_info); +void panic_dump(uint32_t p, struct sof_ipc_panic_info *panic_info, + uintptr_t *data) SOF_NORETURN; +void __panic(uint32_t p, char *filename, uint32_t linenum) SOF_NORETURN; + +/** panic dump filename and linenumber of the call + * + * \param x panic code defined in ipc/trace.h + */ +#define sof_panic(x) __panic((x), (RELATIVE_FILE), (__LINE__)) + +/* runtime assertion */ +#ifndef assert +#define assert(cond) (void)((cond) || (sof_panic(SOF_IPC_PANIC_ASSERT), 0)) +#endif + +#endif /* __POSIX_RTOS_PANIC_H__ */ diff --git a/posix/include/rtos/sof.h b/posix/include/rtos/sof.h new file mode 100644 index 000000000000..3cbb2e7bfefa --- /dev/null +++ b/posix/include/rtos/sof.h @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + */ + +#ifndef __POSIX_RTOS_SOF_H__ +#define __POSIX_RTOS_SOF_H__ + +#include +#include +#include + +struct cascade_root; +struct clock_info; +struct comp_driver_list; +struct dai_info; +struct dma_info; +struct dma_trace_data; +struct ipc; +struct ll_schedule_domain; +struct mm; +struct mn; +struct ams_shared_context; +struct notify_data; +struct pm_runtime_data; +struct sa; +struct timer; +struct trace; +struct pipeline_posn; +struct probe_pdata; + +/** + * \brief General firmware context. + * This structure holds all the global pointers, which can potentially + * be accessed by SMP code, hence it should be aligned to platform's + * data cache line size. Alignments in the both beginning and end are needed + * to avoid potential before and after data evictions. + */ +struct sof { + /* init data */ + int argc; + char **argv; + + /* ipc */ + struct ipc *ipc; + + /* system agent */ + struct sa *sa; + + /* DMA for Trace*/ + struct dma_trace_data *dmat; + + /* generic trace structure */ + struct trace *trace; + + /* platform clock information */ + struct clock_info *clocks; + + /* default platform timer */ + struct timer *platform_timer; + + /* cpu (arch) timers - 1 per core */ + struct timer *cpu_timers; + + /* timer domain for driving timer LL scheduler */ + struct ll_schedule_domain *platform_timer_domain; + + /* DMA domain for driving DMA LL scheduler */ + struct ll_schedule_domain *platform_dma_domain; + + /* memory map */ + struct mm *memory_map; + + /* runtime power management data */ + struct pm_runtime_data *prd; + +#ifdef CONFIG_AMS + /* asynchronous messaging service */ + struct ams_shared_context *ams_shared_ctx; +#endif + + /* shared notifier data */ + struct notify_data *notify_data; + + /* platform dai information */ + const struct dai_info *dai_info; + + /* platform DMA information */ + const struct dma_info *dma_info; + + /* cascading interrupt controller root */ + struct cascade_root *cascade_root; + + /* list of registered component drivers */ + struct comp_driver_list *comp_drivers; + + /* M/N dividers */ + struct mn *mn; + + /* probes */ + struct probe_pdata *probe; + + /* pipelines stream position */ + struct pipeline_posn *pipeline_posn; + +#ifdef CONFIG_LIBRARY_MANAGER + /* dynamically loaded libraries */ + struct ext_library *ext_library; +#endif + +#if CONFIG_IPC_MAJOR_4 + /* lock for fw_reg access */ + struct k_spinlock fw_reg_lock; +#endif + + __aligned(PLATFORM_DCACHE_ALIGN) int alignment[0]; +} __aligned(PLATFORM_DCACHE_ALIGN); + +struct sof *sof_get(void); + +#endif /* __POSIX_RTOS_SOF_H__ */ diff --git a/posix/include/rtos/spinlock.h b/posix/include/rtos/spinlock.h new file mode 100644 index 000000000000..beb20ab6e847 --- /dev/null +++ b/posix/include/rtos/spinlock.h @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + * Keyon Jie + */ + +/* + * Simple spinlock implementation for SOF. + */ + +#ifndef __POSIX_RTOS_SPINLOCK_H__ +#define __POSIX_RTOS_SPINLOCK_H__ + +#include +typedef uint32_t k_spinlock_key_t; +#include +#include + +#include + +/* + * Lock debugging provides a simple interface to debug deadlocks. The rmbox + * trace output will show an output :- + * + * 0xd70 [41.306406] delta [0.359638] lock eal + * 0xd80 [41.306409] delta [0.000002] value 0x00000000000001b7 + * 0xd90 [41.306411] delta [0.000002] value 0x0000000000000001 + * 0xda0 [41.306413] delta [0.000002] value 0x0000000001000348 + * + * "eal" indicates we are holding a lock with interrupts OFF. The next value + * is the line number of where the lock was acquired. The second number is the + * number of other locks held whilst this lock is held and the subsequent + * numbers list each lock and the line number of it's holder. e.g. to find + * the locks :- + * + * grep -rn lock --include *.c | grep 840 (search for lock at line 0x348) + * src/drivers/dw-dma.c:840: spinlock_init(&dma->lock); + * + * grep -rn lock --include *.c | grep 439 + * src/lib/alloc.c:439: k_spin_lock_irq(&memmap.lock, flags); + * + * Every lock entry and exit shows LcE and LcX in trace alongside the lock + * line numbers in hex. e.g. + * + * 0xfd60 [11032.730567] delta [0.000004] lock LcE + * 0xfd70 [11032.730569] delta [0.000002] value 0x00000000000000ae + * + * Deadlock can be confirmed in rmbox :- + * + * Debug log: + * debug: 0x0 (00) = 0xdead0007 (-559087609) |....| + * .... + * Error log: + * using 19.20MHz timestamp clock + * 0xc30 [26.247240] delta [26.245851] lock DED + * 0xc40 [26.247242] delta [0.000002] value 0x00000000000002b4 + * 0xc50 [26.247244] delta [0.000002] value 0x0000000000000109 + * + * DED means deadlock has been detected and the DSP is now halted. The first + * value after DEA is the line number where deadlock occurs and the second + * number is the line number where the lock is allocated. These can be grepped + * like above. + */ + +#if CONFIG_DEBUG_LOCKS + +#include +#include +#include +#include + +#define DBG_LOCK_USERS 8 +#define DBG_LOCK_TRIES 10000 + +extern uint32_t lock_dbg_atomic; +extern uint32_t lock_dbg_user[DBG_LOCK_USERS]; + +extern struct tr_ctx sl_tr; + +/* panic on deadlock */ +#define spin_try_lock_dbg(lock, line) \ + do { \ + int __tries; \ + for (__tries = DBG_LOCK_TRIES; __tries > 0; __tries--) { \ + if (arch_try_lock(lock)) \ + break; /* lock acquired */ \ + } \ + if (__tries == 0) { \ + tr_err_atomic(&sl_tr, "DED"); \ + tr_err_atomic(&sl_tr, "line: %d", line); \ + tr_err_atomic(&sl_tr, "user: %d", (lock)->user); \ + panic(SOF_IPC_PANIC_DEADLOCK); /* lock not acquired */ \ + } \ + } while (0) + +#if CONFIG_DEBUG_LOCKS_VERBOSE +#define spin_lock_log(lock, line) \ + do { \ + if (lock_dbg_atomic) { \ + int __i = 0; \ + int __count = lock_dbg_atomic >= DBG_LOCK_USERS \ + ? DBG_LOCK_USERS : lock_dbg_atomic; \ + tr_err_atomic(&sl_tr, "eal"); \ + tr_err_atomic(&sl_tr, "line: %d", line); \ + tr_err_atomic(&sl_tr, "dbg_atomic: %d", lock_dbg_atomic); \ + for (__i = 0; __i < __count; __i++) { \ + tr_err_atomic(&sl_tr, "value: %d", \ + (lock_dbg_atomic << 24) | \ + lock_dbg_user[__i]); \ + } \ + } \ + } while (0) + +#define spin_lock_dbg(line) \ + do { \ + tr_info(&sl_tr, "LcE"); \ + tr_info(&sl_tr, "line: %d", line); \ + } while (0) + +#define spin_unlock_dbg(line) \ + do { \ + tr_info(&sl_tr, "LcX"); \ + tr_info(&sl_tr, "line: %d", line); \ + } while (0) + +#else /* CONFIG_DEBUG_LOCKS_VERBOSE */ +#define spin_lock_log(lock, line) do {} while (0) +#define spin_lock_dbg(line) do {} while (0) +#define spin_unlock_dbg(line) do {} while (0) +#endif /* CONFIG_DEBUG_LOCKS_VERBOSE */ + +#else /* CONFIG_DEBUG_LOCKS */ + +#define trace_lock(__e) do {} while (0) +#define tracev_lock(__e) do {} while (0) + +#define spin_lock_dbg(line) do {} while (0) +#define spin_unlock_dbg(line) do {} while (0) + +#endif /* CONFIG_DEBUG_LOCKS */ + +/* all SMP spinlocks need init, nothing todo on UP */ +static inline void _spinlock_init(struct k_spinlock *lock, int line) +{ + arch_spinlock_init(lock); +#if CONFIG_DEBUG_LOCKS + lock->user = line; +#endif +} + +#define k_spinlock_init(lock) _spinlock_init(lock, __LINE__) + +/* disables all IRQ sources and takes lock - enter atomic context */ +k_spinlock_key_t _k_spin_lock_irq(struct k_spinlock *lock); +#define k_spin_lock(lock) _k_spin_lock_irq(lock) + +/* re-enables current IRQ sources and releases lock - leave atomic context */ +void _k_spin_unlock_irq(struct k_spinlock *lock, k_spinlock_key_t key, int line); +#define k_spin_unlock(lock, key) _k_spin_unlock_irq(lock, key, __LINE__) + +#endif /* __POSIX_RTOS_SPINLOCK_H__ */ diff --git a/posix/include/rtos/string.h b/posix/include/rtos/string.h new file mode 100644 index 000000000000..b3ca03f9ca4e --- /dev/null +++ b/posix/include/rtos/string.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2018 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + */ + +#ifndef __POSIX_RTOS_STRING_H__ +#define __POSIX_RTOS_STRING_H__ + +#include +#include + +/* C memcpy for arch that don't have arch_memcpy() */ +void cmemcpy(void *dest, void *src, size_t size); +int memcmp(const void *p, const void *q, size_t count); +int rstrlen(const char *s); +int rstrcmp(const char *s1, const char *s2); + +#if defined(arch_memcpy) +#define rmemcpy(dest, src, size) \ + arch_memcpy(dest, src, size) +#else +#define rmemcpy(dest, src, size) \ + cmemcpy(dest, src, size) +#endif + +#endif /* __POSIX_RTOS_STRING_H__ */ diff --git a/posix/include/rtos/task.h b/posix/include/rtos/task.h new file mode 100644 index 000000000000..5aca574a5787 --- /dev/null +++ b/posix/include/rtos/task.h @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + */ + +#ifndef __POSIX_RTOS_TASK_H__ +#define __POSIX_RTOS_TASK_H__ + +#include +#include +#include +#include +#include +#include +#include + +struct comp_dev; +struct sof; + +/** \brief Predefined LL task priorities. */ +#define SOF_TASK_PRI_HIGH 0 /* priority level 0 - high */ +#define SOF_TASK_PRI_MED 4 /* priority level 4 - medium */ +#define SOF_TASK_PRI_LOW 9 /* priority level 9 - low */ + +/** \brief Predefined EDF task deadlines. */ +#define SOF_TASK_DEADLINE_IDLE UINT64_MAX +#define SOF_TASK_DEADLINE_ALMOST_IDLE (SOF_TASK_DEADLINE_IDLE - 1) +#define SOF_TASK_DEADLINE_NOW 0 + +/** \brief Task counter initial value. */ +#define SOF_TASK_SKIP_COUNT 0xFFFFu + +/** \brief Task states. */ +enum task_state { + SOF_TASK_STATE_INIT = 0, + SOF_TASK_STATE_QUEUED, + SOF_TASK_STATE_PENDING, + SOF_TASK_STATE_RUNNING, + SOF_TASK_STATE_PREEMPTED, + SOF_TASK_STATE_COMPLETED, + SOF_TASK_STATE_FREE, + SOF_TASK_STATE_CANCEL, + SOF_TASK_STATE_RESCHEDULE, +}; + +/** \brief Task operations. */ +struct task_ops { + enum task_state (*run)(void *data); /**< task's main operation */ + void (*complete)(void *data); /**< executed on completion */ + uint64_t (*get_deadline)(void *data); /**< returns current deadline */ +}; + +/** \brief Task used by schedulers. */ +struct task { + uint64_t start; /**< start time in [ms] since now (LL only) */ + const struct sof_uuid_entry *uid; /**< Uuid */ + uint16_t type; /**< type of the task (LL or EDF) */ + uint16_t priority; /**< priority of the task (used by LL) */ + uint16_t core; /**< execution core */ + uint16_t flags; /**< custom flags */ + enum task_state state; /**< current state */ + void *data; /**< custom data passed to all ops */ + struct list_item list; /**< used by schedulers to hold tasks */ + void *priv_data; /**< task private data */ + struct task_ops ops; /**< task operations */ +#if defined(CONFIG_SCHEDULE_LOG_CYCLE_STATISTICS) + uint32_t cycles_sum; + uint32_t cycles_max; + uint32_t cycles_cnt; +#endif +#if CONFIG_PERFORMANCE_COUNTERS + struct perf_cnt_data pcd; +#endif +}; + +static inline bool task_is_active(struct task *task) +{ + switch (task->state) { + case SOF_TASK_STATE_QUEUED: + case SOF_TASK_STATE_PENDING: + case SOF_TASK_STATE_RUNNING: + case SOF_TASK_STATE_PREEMPTED: + case SOF_TASK_STATE_RESCHEDULE: + return true; + default: + return false; + } +} + +static inline enum task_state task_run(struct task *task) +{ + assert(task->ops.run); + + return task->ops.run(task->data); +} + +static inline void task_complete(struct task *task) +{ + if (task->ops.complete) + task->ops.complete(task->data); +} + +static inline uint64_t task_get_deadline(struct task *task) +{ + assert(task->ops.get_deadline); + + return task->ops.get_deadline(task->data); +} + +enum task_state task_main_primary_core(void *data); + +enum task_state task_main_secondary_core(void *data); + +void task_main_init(void); + +void task_main_free(void); + +int task_main_start(struct sof *sof); +int start_complete(void); + +#endif /* __POSIX_RTOS_TASK_H__ */ diff --git a/posix/include/rtos/timer.h b/posix/include/rtos/timer.h new file mode 100644 index 000000000000..b9756b66c87c --- /dev/null +++ b/posix/include/rtos/timer.h @@ -0,0 +1,132 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2018 Intel Corporation. All rights reserved. + * + * Author: Janusz Jankowski + */ + +#ifndef __SOF_DRIVERS_TIMER_H__ +#define __SOF_DRIVERS_TIMER_H__ + +#include +#include +#include +#include +#include +#include + +struct comp_dev; +struct sof_ipc_stream_posn; + +#define TIMER0 0 +#define TIMER1 1 +#define TIMER2 2 +#define TIMER3 3 +#define TIMER4 4 + +int timer_register(struct timer *timer, void (*handler)(void *arg), void *arg); +void timer_unregister(struct timer *timer, void *arg); +void timer_enable(struct timer *timer, void *arg, int core); +void timer_disable(struct timer *timer, void *arg, int core); + +static inline struct timer *timer_get(void) +{ + return sof_get()->platform_timer; +} + +static inline struct timer *cpu_timer_get(void) +{ + return &(sof_get()->cpu_timers[cpu_get_id()]); +} + +static inline int64_t timer_set(struct timer *timer, uint64_t ticks) +{ + return arch_timer_set(timer, ticks); +} + +void timer_set_ms(struct timer *timer, unsigned int ms); + +static inline void timer_clear(struct timer *timer) +{ + arch_timer_clear(timer); +} + +unsigned int timer_get_count(struct timer *timer); + +unsigned int timer_get_count_delta(struct timer *timer); + +static inline uint64_t timer_get_system(struct timer *timer) +{ + return arch_timer_get_system(timer); +} + +int64_t platform_timer_set(struct timer *timer, uint64_t ticks); +void platform_timer_clear(struct timer *timer); +uint64_t platform_timer_get(struct timer *timer); +uint64_t platform_timer_get_atomic(struct timer *timer); + +static inline uint64_t platform_safe_get_time(struct timer *timer) +{ + /* Default to something small but at least 1.0 microsecond so it + * does not look like an uninitialized zero; not even when the + * user does not request any microseconds decimals. See + * DEFAULT_CLOCK constant in logger.c + */ + return timer ? platform_timer_get(timer) : 50; +} + +void platform_timer_start(struct timer *timer); +void platform_timer_stop(struct timer *timer); + +static inline uint64_t k_ms_to_cyc_ceil64(uint64_t ms) +{ + return clock_ms_to_ticks(PLATFORM_DEFAULT_CLOCK, ms); +} + +static inline uint64_t k_us_to_cyc_ceil64(uint64_t us) +{ + return clock_us_to_ticks(PLATFORM_DEFAULT_CLOCK, us); +} + +static inline uint64_t k_ns_to_cyc_near64(uint64_t ns) +{ + return clock_ns_to_ticks(PLATFORM_DEFAULT_CLOCK, ns); +} + +static inline uint64_t k_cyc_to_ms_near64(uint64_t ticks) +{ + return ticks / clock_ms_to_ticks(PLATFORM_DEFAULT_CLOCK, 1); +} + +static inline uint64_t k_cyc_to_us_near64(uint64_t ticks) +{ + return ticks / clock_us_to_ticks(PLATFORM_DEFAULT_CLOCK, 1); +} + +static inline uint64_t sof_cycle_get_64(void) +{ + return platform_timer_get(timer_get()); +} + +static inline uint64_t sof_cycle_get_64_atomic(void) +{ + return platform_timer_get_atomic(timer_get()); +} + +static inline uint64_t sof_cycle_get_64_safe(void) +{ + return platform_safe_get_time(timer_get()); +} + +/* get timestamp for host stream DMA position */ +void platform_host_timestamp(struct comp_dev *host, + struct sof_ipc_stream_posn *posn); + +/* get timestamp for DAI stream DMA position */ +void platform_dai_timestamp(struct comp_dev *dai, + struct sof_ipc_stream_posn *posn); + +/* get current wallclock for componnent */ +void platform_dai_wallclock(struct comp_dev *dai, uint64_t *wallclock); + +#endif /* __SOF_DRIVERS_TIMER_H__ */ diff --git a/posix/include/rtos/wait.h b/posix/include/rtos/wait.h new file mode 100644 index 000000000000..b6874888a763 --- /dev/null +++ b/posix/include/rtos/wait.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + */ + +/* + * Simple wait for event completion and signaling with timeouts. + */ + +#ifndef __POSIX_RTOS_WAIT_H__ +#define __POSIX_RTOS_WAIT_H__ + +#include +#include + +#if !CONFIG_LIBRARY +#include +#include +#include +#include +#include +#include + +extern struct tr_ctx wait_tr; + +static inline void wait_for_interrupt(int level) +{ + LOG_MODULE_DECLARE(wait, CONFIG_SOF_LOG_LEVEL); + + tr_dbg(&wait_tr, "WFE"); +#if CONFIG_DEBUG_LOCKS + if (lock_dbg_atomic) + tr_err_atomic(&wait_tr, "atm"); +#endif + platform_wait_for_interrupt(level); + tr_dbg(&wait_tr, "WFX"); +} + +/** + * \brief Waits at least passed number of clocks. + * \param[in] number_of_clks Minimum number of clocks to wait. + */ +void wait_delay(uint64_t number_of_clks); + +/** + * \brief Waits at least passed number of milliseconds. + * \param[in] ms Minimum number of milliseconds to wait. + */ +void wait_delay_ms(uint64_t ms); + +/** + * \brief Waits at least passed number of microseconds. + * \param[in] us Minimum number of microseconds to wait. + */ +void wait_delay_us(uint64_t us); +#else +static inline void wait_delay(uint64_t number_of_clks) {} +static inline void wait_delay_ms(uint64_t ms) {} +static inline void wait_delay_us(uint64_t us) {} +#endif + +int poll_for_register_delay(uint32_t reg, uint32_t mask, + uint32_t val, uint64_t us); + +#endif /* __POSIX_RTOS_WAIT_H__ */ diff --git a/posix/include/sof/compiler_attributes.h b/posix/include/sof/compiler_attributes.h new file mode 100644 index 000000000000..bf88bfac4369 --- /dev/null +++ b/posix/include/sof/compiler_attributes.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + * + * Author: Karol Trzcinski + */ + +#ifdef __ZEPHYR__ + +/* Get __sparse_cache and __sparse_force definitions if __CHECKER__ is defined */ +#include + +#else + +#define __sparse_cache +#define __sparse_force + +#ifndef __packed +#define __packed __attribute__((packed)) +#endif + +#ifndef __unused +#define __unused __attribute__((unused)) +#endif + +#endif + +#ifndef __aligned +#define __aligned(x) __attribute__((__aligned__(x))) +#endif + +#ifndef __section +#define __section(x) __attribute__((section(x))) +#endif + +/* The fallthrough attribute is supported since GCC 7.0 + * and Clang 10.0.0. + * + * Note that Clang sets __GNUC__ == 4 so the GCC version + * test will not be true here, and must go through + * the Clang version test. + */ +#if ((defined(__GNUC__) && (__GNUC__ >= 7)) || \ + (defined(__clang__) && (__clang_major__ >= 10))) && !defined(__CHECKER__) + +#define COMPILER_FALLTHROUGH __attribute__((fallthrough)) + +#else + +#define COMPILER_FALLTHROUGH /* fallthrough */ + +#endif diff --git a/posix/include/sof/compiler_info.h b/posix/include/sof/compiler_info.h new file mode 100644 index 000000000000..9716575b7188 --- /dev/null +++ b/posix/include/sof/compiler_info.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + * + * Author: Karol Trzcinski + */ + +/** + * \file xtos/include/sof/compiler_info.h + * \brief Compiler version and name descriptor + * \author Karol Trzcinski + */ + +#ifndef __SOF_COMPILER_INFO_H__ +#define __SOF_COMPILER_INFO_H__ + +#include + +#endif /* __SOF_COMPILER_INFO_H__ */ diff --git a/posix/include/sof/init.h b/posix/include/sof/init.h new file mode 100644 index 000000000000..ce8522cd34ad --- /dev/null +++ b/posix/include/sof/init.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + */ + +#ifndef __SOF_INIT_H__ +#define __SOF_INIT_H__ + +struct sof; + +/* main firmware entry point - argc and argv not currently used */ +#ifndef CONFIG_ARCH_POSIX +int main(int argc, char *argv[]); +#endif + +#if CONFIG_MULTICORE + +int secondary_core_init(struct sof *sof); + +#endif /* CONFIG_MULTICORE */ + +int arch_init(void); + +#endif /* __SOF_INIT_H__ */ diff --git a/posix/include/sof/lib/agent.h b/posix/include/sof/lib/agent.h new file mode 100644 index 000000000000..6e70a4ce997d --- /dev/null +++ b/posix/include/sof/lib/agent.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2017 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + */ + +#ifndef __SOF_LIB_AGENT_H__ +#define __SOF_LIB_AGENT_H__ + +#include +#include +#include +#include +#include + +#include +#include + +struct sof; + +/* simple agent */ +struct sa { + uint64_t last_check; /* time of last activity checking */ + uint64_t panic_timeout; /* threshold of panic */ + uint64_t warn_timeout; /* threshold of warning */ +#if CONFIG_PERFORMANCE_COUNTERS + struct perf_cnt_data pcd; +#endif + struct task work; + atomic_t panic_cnt; /**< ref counter for panic_on_delay property */ + bool panic_on_delay; /**< emits panic on delay if true */ +}; + +#if CONFIG_HAVE_AGENT + +/** + * Enables or disables panic on agent delay. + * @param enabled True for panic enabling, false otherwise. + */ +static inline void sa_set_panic_on_delay(bool enabled) +{ + struct sa *sa = sof_get()->sa; + + if (enabled) + atomic_add(&sa->panic_cnt, 1); + else + atomic_sub(&sa->panic_cnt, 1); + + /* enable panic only if no refs */ + sa->panic_on_delay = !atomic_read(&sa->panic_cnt); + +} + +void sa_init(struct sof *sof, uint64_t timeout); +void sa_exit(struct sof *sof); + +#else + +static inline void sa_init(struct sof *sof, uint64_t timeout) { } +static inline void sa_exit(struct sof *sof) { } +static inline void sa_set_panic_on_delay(bool enabled) { } + +#endif + +#endif /* __SOF_LIB_AGENT_H__ */ diff --git a/posix/include/sof/lib/cpu.h b/posix/include/sof/lib/cpu.h new file mode 100644 index 000000000000..d53e15e7535a --- /dev/null +++ b/posix/include/sof/lib/cpu.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2018 Intel Corporation. All rights reserved. + * + * Author: Tomasz Lauda + */ + +/** + * \file xtos/include/sof/lib/cpu.h + * \brief CPU header file + * \authors Tomasz Lauda + */ + +#ifndef __SOF_LIB_CPU_H__ +#define __SOF_LIB_CPU_H__ +#ifndef __ZEPHYR__ + +#include + +#if !defined(__ASSEMBLER__) && !defined(LINKER) + +#include +#include + +/* let the compiler optimise when in single core mode */ +#if CONFIG_CORE_COUNT == 1 + +static inline int cpu_get_id(void) +{ + return 0; +} + +static inline bool cpu_is_primary(int id) +{ + return 1; +} + +static inline bool cpu_is_me(int id) +{ + return 1; +} + +#else + +static inline int cpu_get_id(void) +{ + return arch_cpu_get_id(); +} + +static inline bool cpu_is_primary(int id) +{ + return id == PLATFORM_PRIMARY_CORE_ID; +} + +static inline bool cpu_is_me(int id) +{ + return id == cpu_get_id(); +} +#endif + +static inline int cpu_enable_core(int id) +{ + return arch_cpu_enable_core(id); +} + +static inline void cpu_disable_core(int id) +{ + arch_cpu_disable_core(id); +} + +static inline int cpu_is_core_enabled(int id) +{ + return arch_cpu_is_core_enabled(id); +} + +static inline int cpu_enabled_cores(void) +{ + return arch_cpu_enabled_cores(); +} + +static inline int cpu_restore_secondary_cores(void) +{ + return arch_cpu_restore_secondary_cores(); +} + +static inline int cpu_secondary_cores_prepare_d0ix(void) +{ + return arch_cpu_secondary_cores_prepare_d0ix(); +} + +#endif +#endif +#endif /* __SOF_LIB_CPU_H__ */ diff --git a/posix/include/sof/lib/dai.h b/posix/include/sof/lib/dai.h new file mode 100644 index 000000000000..47677c19ae4c --- /dev/null +++ b/posix/include/sof/lib/dai.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + * Keyon Jie + */ + +/** + * \file xtos/include/sof/lib/dai.h + * \brief DAI Drivers definition + * \author Liam Girdwood + * \author Keyon Jie + */ + +#ifndef __SOF_LIB_DAI_H__ +#define __SOF_LIB_DAI_H__ + +#ifdef CONFIG_ZEPHYR_NATIVE_DRIVERS +#include +#else +#include +#endif + +struct ipc4_ipcgtw_cmd; + +static inline int ipcgtw_process_cmd(const struct ipc4_ipcgtw_cmd *cmd, + void *reply_payload, uint32_t *reply_payload_size) +{ + return 0; +} + +#endif /* __SOF_LIB_DAI_H__ */ diff --git a/posix/include/sof/lib/dma.h b/posix/include/sof/lib/dma.h new file mode 100644 index 000000000000..af9e4191cbbb --- /dev/null +++ b/posix/include/sof/lib/dma.h @@ -0,0 +1,589 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + * Keyon Jie + */ + +/** + * \file xtos/include/sof/lib/dma.h + * \brief DMA Drivers definition + * \author Liam Girdwood + * \author Keyon Jie + */ + +#ifndef __SOF_LIB_DMA_H__ +#define __SOF_LIB_DMA_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __ZEPHYR__ +#include +#include +#endif + +struct comp_buffer; + +/** \addtogroup sof_dma_drivers DMA Drivers + * DMA Drivers API specification. + * @{ + */ + +/* DMA direction bitmasks used to define DMA copy direction */ +#define DMA_DIR_MEM_TO_MEM BIT(0) /**< local memory copy */ +#define DMA_DIR_HMEM_TO_LMEM BIT(1) /**< host memory to local mem copy */ +#define DMA_DIR_LMEM_TO_HMEM BIT(2) /**< local mem to host mem copy */ +#define DMA_DIR_MEM_TO_DEV BIT(3) /**< local mem to dev copy */ +#define DMA_DIR_DEV_TO_MEM BIT(4) /**< dev to local mem copy */ +#define DMA_DIR_DEV_TO_DEV BIT(5) /**< dev to dev copy */ + +/* DMA capabilities bitmasks used to define the type of DMA */ +#define DMA_CAP_HDA BIT(0) /**< HDA DMA */ +#define DMA_CAP_GP_LP BIT(1) /**< GP LP DMA */ +#define DMA_CAP_GP_HP BIT(2) /**< GP HP DMA */ +#define DMA_CAP_BT BIT(3) /**< BT DMA */ +#define DMA_CAP_SP BIT(4) /**< SP DMA */ +#define DMA_CAP_DMIC BIT(5) /**< ACP DMA DMIC > */ +#define DMA_CAP_SP_VIRTUAL BIT(6) /**< SP VIRTUAL DMA */ +#define DMA_CAP_HS_VIRTUAL BIT(7) /**< HS VIRTUAL DMA */ + +/* DMA dev type bitmasks used to define the type of DMA */ + +#define DMA_DEV_HOST BIT(0) /**< connectable to host */ +#define DMA_DEV_HDA BIT(1) /**< connectable to HD/A link */ +#define DMA_DEV_SSP BIT(2) /**< connectable to SSP fifo */ +#define DMA_DEV_DMIC BIT(3) /**< connectable to DMIC fifo */ +#define DMA_DEV_SSI BIT(4) /**< connectable to SSI / SPI fifo */ +#define DMA_DEV_ALH BIT(5) /**< connectable to ALH link */ +#define DMA_DEV_SAI BIT(6) /**< connectable to SAI fifo */ +#define DMA_DEV_ESAI BIT(7) /**< connectable to ESAI fifo */ +#define DMA_DEV_BT BIT(8) /**< connectable to ACP BT I2S */ +#define DMA_DEV_SP BIT(9) /**< connectable to ACP SP I2S */ +#define DMA_DEV_AFE_MEMIF BIT(10) /**< connectable to AFE fifo */ +#define DMA_DEV_SP_VIRTUAL BIT(11) /**< connectable to ACP SP VIRTUAL I2S */ +#define DMA_DEV_HS_VIRTUAL BIT(12) /**< connectable to ACP HS VIRTUAL I2S */ + +/* DMA access privilege flag */ +#define DMA_ACCESS_EXCLUSIVE 1 +#define DMA_ACCESS_SHARED 0 + +/* DMA copy flags */ +#define DMA_COPY_BLOCKING BIT(0) +#define DMA_COPY_ONE_SHOT BIT(1) + +/* We will use this enum in cb handler to inform dma what + * action we need to perform. + */ +enum dma_cb_status { + DMA_CB_STATUS_RELOAD = 0, + DMA_CB_STATUS_END, +}; + +/* DMA interrupt commands */ +enum dma_irq_cmd { + DMA_IRQ_STATUS_GET = 0, + DMA_IRQ_CLEAR, + DMA_IRQ_MASK, + DMA_IRQ_UNMASK +}; + +#define DMA_CHAN_INVALID 0xFFFFFFFF +#define DMA_CORE_INVALID 0xFFFFFFFF + +/* Attributes have been ported to Zephyr. This condition is necessary until full support of + * CONFIG_SOF_ZEPHYR_STRICT_HEADERS. + */ +#ifndef CONFIG_ZEPHYR_NATIVE_DRIVERS +/* DMA attributes */ +#define DMA_ATTR_BUFFER_ALIGNMENT 0 +#define DMA_ATTR_COPY_ALIGNMENT 1 +#define DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT 2 +#define DMA_ATTR_BUFFER_PERIOD_COUNT 3 +#endif + +struct dma; + +/** + * \brief Element of SG list (as array item). + */ +struct dma_sg_elem { + uint32_t src; /**< source address */ + uint32_t dest; /**< destination address */ + uint32_t size; /**< size (in bytes) */ +}; + +/** + * \brief Data used in DMA callbacks. + */ +struct dma_cb_data { + struct dma_chan_data *channel; + struct dma_sg_elem elem; + enum dma_cb_status status; +}; + +/** + * \brief SG elem array. + */ +struct dma_sg_elem_array { + uint32_t count; /**< number of elements in elems */ + struct dma_sg_elem *elems; /**< elements */ +}; + +/* DMA physical SG params */ +struct dma_sg_config { + uint32_t src_width; /* in bytes */ + uint32_t dest_width; /* in bytes */ + uint32_t burst_elems; + uint32_t direction; + uint32_t src_dev; + uint32_t dest_dev; + uint32_t cyclic; /* circular buffer */ + uint64_t period; + struct dma_sg_elem_array elem_array; /* array of dma_sg elems */ + bool scatter; + bool irq_disabled; + /* true if configured DMA channel is the scheduling source */ + bool is_scheduling_source; +}; + +struct dma_chan_status { + uint32_t state; + uint32_t flags; + uint32_t w_pos; + uint32_t r_pos; + uint32_t timestamp; + + /* dma position info for ipc4 */ + void *ipc_posn_data; +}; + +/* DMA operations */ +struct dma_ops { + + struct dma_chan_data *(*channel_get)(struct dma *dma, + unsigned int req_channel); + void (*channel_put)(struct dma_chan_data *channel); + + int (*start)(struct dma_chan_data *channel); + int (*stop)(struct dma_chan_data *channel); + int (*stop_delayed)(struct dma_chan_data *channel); + int (*copy)(struct dma_chan_data *channel, int bytes, uint32_t flags); + int (*pause)(struct dma_chan_data *channel); + int (*release)(struct dma_chan_data *channel); + int (*status)(struct dma_chan_data *channel, + struct dma_chan_status *status, uint8_t direction); + + int (*set_config)(struct dma_chan_data *channel, + struct dma_sg_config *config); + + int (*probe)(struct dma *dma); + int (*remove)(struct dma *dma); + + int (*get_data_size)(struct dma_chan_data *channel, uint32_t *avail, + uint32_t *free); + + int (*get_attribute)(struct dma *dma, uint32_t type, uint32_t *value); + + int (*interrupt)(struct dma_chan_data *channel, enum dma_irq_cmd cmd); +}; + +/* DMA platform data */ +struct dma_plat_data { + uint32_t id; + uint32_t dir; /* bitmask of supported copy directions */ + uint32_t caps; /* bitmask of supported capabilities */ + uint32_t devs; /* bitmask of supported devs */ + uint32_t base; + uint32_t channels; + int irq; + const char *irq_name; + uint32_t chan_size; + const void *drv_plat_data; +#ifdef __ZEPHYR__ + uint32_t period_count; +#endif +}; + +struct dma { + struct dma_plat_data plat_data; + struct k_spinlock lock; /**< locking mechanism */ + int sref; /**< simple ref counter, guarded by lock */ + const struct dma_ops *ops; + atomic_t num_channels_busy; /* number of busy channels */ + struct dma_chan_data *chan; /* channels array */ +#ifdef __ZEPHYR__ + const struct device *z_dev; /* Zephyr driver */ +#endif + void *priv_data; +}; + +struct dma_chan_data { + struct dma *dma; + + uint32_t status; + uint32_t direction; + uint32_t desc_count; + uint32_t index; + uint32_t core; + uint64_t period; /* DMA channel's transfer period in us */ + /* true if this DMA channel is the scheduling source */ + bool is_scheduling_source; + + /* device specific data set by the device that requests the DMA channel */ + void *dev_data; + + void *priv_data; +}; + +struct dma_info { + struct dma *dma_array; + size_t num_dmas; +}; + +struct audio_stream; +typedef int (*dma_process_func)(const struct audio_stream __sparse_cache *source, + uint32_t ioffset, struct audio_stream __sparse_cache *sink, + uint32_t ooffset, uint32_t frames); + +/** + * \brief API to initialize a platform DMA controllers. + * + * \param[in] sof Pointer to firmware main context. + */ +int dmac_init(struct sof *sof); + +/** + * \brief API to request a platform DMAC. + * + * Users can request DMAC based on dev type, copy direction, capabilities + * and access privilege. + * For exclusive access, ret DMAC with no channels draining. + * For shared access, ret DMAC with the least number of channels draining. + */ +struct dma *dma_get(uint32_t dir, uint32_t caps, uint32_t dev, uint32_t flags); + +/** + * \brief API to release a platform DMAC. + * + * @param[in] dma DMAC to relese. + */ +void dma_put(struct dma *dma); + +#define dma_set_drvdata(dma, data) \ + (dma->priv_data = data) +#define dma_get_drvdata(dma) \ + dma->priv_data +#define dma_base(dma) \ + dma->plat_data.base +#define dma_irq(dma) \ + dma->plat_data.irq +#define dma_irq_name(dma) \ + dma->plat_data.irq_name +#define dma_chan_size(dma) \ + dma->plat_data.chan_size +#define dma_chan_base(dma, chan) \ + (dma->plat_data.base + chan * dma->plat_data.chan_size) +#define dma_chan_get_data(chan) \ + ((chan)->priv_data) +#define dma_chan_set_data(chan, data) \ + ((chan)->priv_data = data) + +/* DMA API + * Programming flow is :- + * + * 1) dma_channel_get() + * 2) notifier_register() + * 3) dma_set_config() + * 4) dma_start() + * ... DMA now running ... + * 5) dma_stop() + * 6) dma_stop_delayed() + * 7) dma_channel_put() + */ + +static inline struct dma_chan_data *dma_channel_get_legacy(struct dma *dma, + int req_channel) +{ + if (!dma || !dma->ops || !dma->ops->channel_get) + return NULL; + + struct dma_chan_data *chan = dma->ops->channel_get(dma, req_channel); + + return chan; +} + +static inline void dma_channel_put_legacy(struct dma_chan_data *channel) +{ + channel->dma->ops->channel_put(channel); +} + +static inline int dma_start_legacy(struct dma_chan_data *channel) +{ + return channel->dma->ops->start(channel); +} + +static inline int dma_stop_legacy(struct dma_chan_data *channel) +{ + if (channel->dma->ops->stop) + return channel->dma->ops->stop(channel); + + return 0; +} + +static inline int dma_stop_delayed_legacy(struct dma_chan_data *channel) +{ + if (channel->dma->ops->stop_delayed) + return channel->dma->ops->stop_delayed(channel); + + return 0; +} + +/** \defgroup sof_dma_copy_func static int dma_copy (struct dma_chan_data * channel, int bytes, uint32_t flags) + * + * This function is in a separate subgroup to solve a name clash with + * struct dma_copy {} + * @{ + */ +static inline int dma_copy_legacy(struct dma_chan_data *channel, int bytes, + uint32_t flags) +{ + return channel->dma->ops->copy(channel, bytes, flags); +} +/** @} */ + +static inline int dma_pause_legacy(struct dma_chan_data *channel) +{ + if (channel->dma->ops->pause) + return channel->dma->ops->pause(channel); + + return 0; +} + +static inline int dma_release_legacy(struct dma_chan_data *channel) +{ + if (channel->dma->ops->release) + return channel->dma->ops->release(channel); + + return 0; +} + +static inline int dma_status_legacy(struct dma_chan_data *channel, + struct dma_chan_status *status, uint8_t direction) +{ + return channel->dma->ops->status(channel, status, direction); +} + +static inline int dma_set_config_legacy(struct dma_chan_data *channel, + struct dma_sg_config *config) +{ + return channel->dma->ops->set_config(channel, config); +} + +static inline int dma_probe_legacy(struct dma *dma) +{ + return dma->ops->probe(dma); +} + +static inline int dma_remove_legacy(struct dma *dma) +{ + return dma->ops->remove(dma); +} + +static inline int dma_get_data_size_legacy(struct dma_chan_data *channel, + uint32_t *avail, uint32_t *free) +{ + return channel->dma->ops->get_data_size(channel, avail, free); +} + +static inline int dma_get_attribute_legacy(struct dma *dma, uint32_t type, + uint32_t *value) +{ + return dma->ops->get_attribute(dma, type, value); +} + +static inline int dma_interrupt_legacy(struct dma_chan_data *channel, + enum dma_irq_cmd cmd) +{ + return channel->dma->ops->interrupt(channel, cmd); +} + +/* DMA hardware register operations */ +static inline uint32_t dma_reg_read(struct dma *dma, uint32_t reg) +{ + return io_reg_read(dma_base(dma) + reg); +} + +static inline uint16_t dma_reg_read16(struct dma *dma, uint32_t reg) +{ + return io_reg_read16(dma_base(dma) + reg); +} + +static inline void dma_reg_write(struct dma *dma, uint32_t reg, uint32_t value) +{ + io_reg_write(dma_base(dma) + reg, value); +} + +static inline void dma_reg_write16(struct dma *dma, uint32_t reg, + uint16_t value) +{ + io_reg_write16(dma_base(dma) + reg, value); +} + +static inline void dma_reg_update_bits(struct dma *dma, uint32_t reg, + uint32_t mask, uint32_t value) +{ + io_reg_update_bits(dma_base(dma) + reg, mask, value); +} + +static inline uint32_t dma_chan_reg_read(struct dma_chan_data *channel, + uint32_t reg) +{ + return io_reg_read(dma_chan_base(channel->dma, channel->index) + reg); +} + +static inline uint16_t dma_chan_reg_read16(struct dma_chan_data *channel, + uint32_t reg) +{ + return io_reg_read16(dma_chan_base(channel->dma, channel->index) + reg); +} + +static inline void dma_chan_reg_write(struct dma_chan_data *channel, + uint32_t reg, uint32_t value) +{ + io_reg_write(dma_chan_base(channel->dma, channel->index) + reg, value); +} + +static inline void dma_chan_reg_write16(struct dma_chan_data *channel, + uint32_t reg, uint16_t value) +{ + io_reg_write16(dma_chan_base(channel->dma, channel->index) + reg, + value); +} + +static inline void dma_chan_reg_update_bits(struct dma_chan_data *channel, + uint32_t reg, uint32_t mask, + uint32_t value) +{ + io_reg_update_bits(dma_chan_base(channel->dma, channel->index) + reg, + mask, value); +} + +static inline void dma_chan_reg_update_bits16(struct dma_chan_data *channel, + uint32_t reg, uint16_t mask, + uint16_t value) +{ + io_reg_update_bits16(dma_chan_base(channel->dma, channel->index) + reg, + mask, value); +} + +static inline bool dma_is_scheduling_source(struct dma_chan_data *channel) +{ + return channel->is_scheduling_source; +} + +static inline void dma_sg_init(struct dma_sg_elem_array *ea) +{ + ea->count = 0; + ea->elems = NULL; +} + +int dma_sg_alloc(struct dma_sg_elem_array *ea, + enum mem_zone zone, + uint32_t direction, + uint32_t buffer_count, uint32_t buffer_bytes, + uintptr_t dma_buffer_addr, uintptr_t external_addr); + +void dma_sg_free(struct dma_sg_elem_array *ea); + +/** + * \brief Get the total size of SG buffer + * + * \param ea Array of SG elements. + * \return Size of the buffer. + */ +static inline uint32_t dma_sg_get_size(struct dma_sg_elem_array *ea) +{ + int i; + uint32_t size = 0; + + for (i = 0 ; i < ea->count; i++) + size += ea->elems[i].size; + + return size; +} + +struct audio_stream; +typedef void (*dma_process)(const struct audio_stream *, + struct audio_stream *, uint32_t); + +/* copies data from DMA buffer using provided processing function */ +int dma_buffer_copy_from(struct comp_buffer __sparse_cache *source, + struct comp_buffer __sparse_cache *sink, + dma_process_func process, uint32_t source_bytes); + +/* copies data to DMA buffer using provided processing function */ +int dma_buffer_copy_to(struct comp_buffer __sparse_cache *source, + struct comp_buffer __sparse_cache *sink, + dma_process_func process, uint32_t sink_bytes); + +/* + * Used when copying DMA buffer bytes into multiple sink buffers, one at a time using the provided + * conversion function. DMA buffer consume should be performed after the data has been copied + * to all sinks. + */ +int dma_buffer_copy_from_no_consume(struct comp_buffer __sparse_cache *source, + struct comp_buffer __sparse_cache *sink, + dma_process_func process, uint32_t source_bytes); + +/* generic DMA DSP <-> Host copier */ + +struct dma_copy { + struct dma_chan_data *chan; + struct dma *dmac; +}; + +/* init dma copy context */ +int dma_copy_new(struct dma_copy *dc); + +/* free dma copy context resources */ +static inline void dma_copy_free(struct dma_copy *dc) +{ + dma_channel_put_legacy(dc->chan); +} + +/* DMA copy data from host to DSP */ +int dma_copy_from_host(struct dma_copy *dc, struct dma_sg_config *host_sg, + int32_t host_offset, void *local_ptr, int32_t size); +int dma_copy_from_host_nowait(struct dma_copy *dc, + struct dma_sg_config *host_sg, + int32_t host_offset, void *local_ptr, + int32_t size); + +/* DMA copy data from DSP to host */ +int dma_copy_to_host(struct dma_copy *dc, struct dma_sg_config *host_sg, + int32_t host_offset, void *local_ptr, int32_t size); +int dma_copy_to_host_nowait(struct dma_copy *dc, struct dma_sg_config *host_sg, + int32_t host_offset, void *local_ptr, int32_t size); + + +int dma_copy_set_stream_tag(struct dma_copy *dc, uint32_t stream_tag); + +static inline const struct dma_info *dma_info_get(void) +{ + return sof_get()->dma_info; +} + +/** @}*/ + +#endif /* __SOF_LIB_DMA_H__ */ diff --git a/posix/include/sof/lib/io.h b/posix/include/sof/lib/io.h new file mode 100644 index 000000000000..07f1e5aa1fbe --- /dev/null +++ b/posix/include/sof/lib/io.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + */ + +#ifndef __XTOS_POSIX_LIB_IO_H__ +#define __XTOS_POSIX_LIB_IO_H__ + + +#include + +#if CONFIG_LIBRARY + +static inline uint32_t io_reg_read(uint32_t reg) { return 0; } +static inline void io_reg_write(uint32_t reg, uint32_t val) {} +static inline void io_reg_update_bits(uint32_t reg, uint32_t mask, + uint32_t value) {} +static inline uint16_t io_reg_read16(uint32_t reg) { return 0; } +static inline void io_reg_write16(uint32_t reg, uint16_t val) {} +static inline void io_reg_update_bits16(uint32_t reg, uint16_t mask, + uint16_t value) {} + +#else + +static inline uint32_t io_reg_read(uint32_t reg) +{ + return *((volatile uint32_t *)reg); +} + +static inline void io_reg_write(uint32_t reg, uint32_t val) +{ + *((volatile uint32_t *)reg) = val; +} + +static inline void io_reg_update_bits(uint32_t reg, uint32_t mask, + uint32_t value) +{ + io_reg_write(reg, (io_reg_read(reg) & (~mask)) | (value & mask)); +} + +static inline uint16_t io_reg_read16(uint32_t reg) +{ + return *((volatile uint16_t *)reg); +} + +static inline void io_reg_write16(uint32_t reg, uint16_t val) +{ + *((volatile uint16_t *)reg) = val; +} + +static inline uint64_t io_reg_read64(uint32_t reg) +{ + return (uint64_t)io_reg_read(reg) + + (((uint64_t)io_reg_read(reg + 4)) << 32); +} + +static inline void io_reg_write64(uint32_t reg, uint64_t val) +{ + *((volatile uint64_t *)reg) = val; +} + +static inline void io_reg_update_bits16(uint32_t reg, uint16_t mask, + uint16_t value) +{ + io_reg_write16(reg, (io_reg_read16(reg) & (~mask)) | (value & mask)); +} + +static inline uint8_t io_reg_read8(uint32_t reg) +{ + return *((volatile uint8_t *)reg); +} + +static inline void io_reg_write8(uint32_t reg, uint8_t val) +{ + *((volatile uint8_t *)reg) = val; +} + +static inline void io_reg_update_bits8(uint32_t reg, uint8_t mask, + uint8_t value) +{ + io_reg_write8(reg, (io_reg_read8(reg) & (~mask)) | (value & mask)); +} + +#endif + +#endif /* __XTOS_POSIX_LIB_IO_H__ */ diff --git a/posix/include/sof/lib/mailbox.h b/posix/include/sof/lib/mailbox.h new file mode 100644 index 000000000000..3d43a22e10ec --- /dev/null +++ b/posix/include/sof/lib/mailbox.h @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + * Xiuli Pan + */ + +#ifndef __SOF_LIB_MAILBOX_H__ +#define __SOF_LIB_MAILBOX_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define mailbox_get_exception_base() \ + MAILBOX_EXCEPTION_BASE + +#define mailbox_get_exception_size() \ + MAILBOX_EXCEPTION_SIZE + +#define mailbox_get_dspbox_base() \ + MAILBOX_DSPBOX_BASE + +#define mailbox_get_dspbox_size() \ + MAILBOX_DSPBOX_SIZE + +#define mailbox_get_hostbox_base() \ + MAILBOX_HOSTBOX_BASE + +#define mailbox_get_hostbox_size() \ + MAILBOX_HOSTBOX_SIZE + +#define mailbox_get_debug_base() \ + MAILBOX_DEBUG_BASE + +#define mailbox_get_debug_size() \ + MAILBOX_DEBUG_SIZE + +static inline +void mailbox_dspbox_write(size_t offset, const void *src, size_t bytes) +{ + int dsp_write_err __unused = memcpy_s((void *)(MAILBOX_DSPBOX_BASE + offset), + MAILBOX_DSPBOX_SIZE - offset, src, bytes); + + assert(!dsp_write_err); + dcache_writeback_region((__sparse_force void __sparse_cache *)(MAILBOX_DSPBOX_BASE + + offset), bytes); +} + +static inline +void mailbox_dspbox_read(void *dest, size_t dest_size, + size_t offset, size_t bytes) +{ + int dsp_read_err __unused; + + dcache_invalidate_region((__sparse_force void __sparse_cache *)(MAILBOX_DSPBOX_BASE + + offset), bytes); + dsp_read_err = memcpy_s(dest, dest_size, + (void *)(MAILBOX_DSPBOX_BASE + offset), bytes); + assert(!dsp_read_err); +} + +#if CONFIG_LIBRARY + +#define mailbox_hostbox_write(_offset, _src, _bytes) \ + memcpy((char *)ipc->comp_data + _offset, _src, _bytes) + +static inline uint64_t mailbox_sw_reg_read64(uint32_t offset) +{ + return 0; +} +#else + +static inline +void mailbox_hostbox_write(size_t offset, const void *src, size_t bytes) +{ + int host_write_err __unused = memcpy_s((void *)(MAILBOX_HOSTBOX_BASE + offset), + MAILBOX_HOSTBOX_SIZE - offset, src, bytes); + + assert(!host_write_err); + dcache_writeback_region((__sparse_force void __sparse_cache *)(MAILBOX_HOSTBOX_BASE + + offset), bytes); +} + +#endif + +static inline +void mailbox_hostbox_read(void *dest, size_t dest_size, + size_t offset, size_t bytes) +{ + int host_read_err __unused; + + dcache_invalidate_region((__sparse_force void __sparse_cache *)(MAILBOX_HOSTBOX_BASE + + offset), bytes); + host_read_err = memcpy_s(dest, dest_size, + (void *)(MAILBOX_HOSTBOX_BASE + offset), bytes); + assert(!host_read_err); +} + +static inline +void mailbox_stream_write(size_t offset, const void *src, size_t bytes) +{ + int stream_write_err __unused = memcpy_s((void *)(MAILBOX_STREAM_BASE + offset), + MAILBOX_STREAM_SIZE - offset, src, bytes); + + assert(!stream_write_err); + dcache_writeback_region((__sparse_force void __sparse_cache *)(MAILBOX_STREAM_BASE + + offset), bytes); +} + +#endif /* __SOF_LIB_MAILBOX_H__ */ diff --git a/posix/include/sof/lib/memory.h b/posix/include/sof/lib/memory.h new file mode 100644 index 000000000000..8fcbc1f9adbe --- /dev/null +++ b/posix/include/sof/lib/memory.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + * + * Author: Tomasz Lauda + */ + +#ifndef __SOF_LIB_MEMORY_H__ +#define __SOF_LIB_MEMORY_H__ + +#include + +#endif /* __SOF_LIB_MEMORY_H__ */ diff --git a/posix/include/sof/lib/mm_heap.h b/posix/include/sof/lib/mm_heap.h new file mode 100644 index 000000000000..7bdab176eb5f --- /dev/null +++ b/posix/include/sof/lib/mm_heap.h @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + * Keyon Jie + */ + +#ifndef __SOF_LIB_MM_HEAP_H__ +#define __SOF_LIB_MM_HEAP_H__ + +#include +#include +#include +#include +#include +#include + +#include +#include + +struct dma_copy; +struct dma_sg_config; + +struct mm_info { + uint32_t used; + uint32_t free; +}; + +struct block_hdr { + uint16_t size; /* size in blocks for continuous allocation */ + uint16_t used; /* usage flags for page */ + void *unaligned_ptr; /* align ptr */ +} __packed; + +struct block_map { + uint16_t block_size; /* size of block in bytes */ + uint16_t count; /* number of blocks in map */ + uint16_t free_count; /* number of free blocks */ + uint16_t first_free; /* index of first free block */ + struct block_hdr *block; /* base block header */ + uint32_t base; /* base address of space */ +}; + +#define BLOCK_DEF(sz, cnt, hdr) \ + {.block_size = sz, .count = cnt, .free_count = cnt, .block = hdr, \ + .first_free = 0} + +struct mm_heap { + uint32_t blocks; + struct block_map *map; +#if CONFIG_LIBRARY + unsigned long heap; +#else + uint32_t heap; +#endif + uint32_t size; + uint32_t caps; + struct mm_info info; +}; + +/* heap block memory map */ +struct mm { + /* system heap - used during init cannot be freed */ + struct mm_heap system[PLATFORM_HEAP_SYSTEM]; + /* system runtime heap - used for runtime system components */ + struct mm_heap system_runtime[PLATFORM_HEAP_SYSTEM_RUNTIME]; +#if CONFIG_CORE_COUNT > 1 + /* object shared between different cores - used during init cannot be freed */ + struct mm_heap system_shared[PLATFORM_HEAP_SYSTEM_SHARED]; + /* object shared between different cores */ + struct mm_heap runtime_shared[PLATFORM_HEAP_RUNTIME_SHARED]; +#endif + /* general heap for components */ + struct mm_heap runtime[PLATFORM_HEAP_RUNTIME]; + /* general component buffer heap */ + struct mm_heap buffer[PLATFORM_HEAP_BUFFER]; + + struct mm_info total; + uint32_t heap_trace_updated; /* updates that can be presented */ + struct k_spinlock lock; /* all allocs and frees are atomic */ +}; + +/* Heap save/restore contents and context for PM D0/D3 events */ +uint32_t mm_pm_context_size(void); + +/* heap initialisation */ +void init_heap(struct sof *sof); + +/* frees entire heap (supported for secondary core system heap atm) */ +void free_heap(enum mem_zone zone); + +/* status */ +void heap_trace_all(int force); +void heap_trace(struct mm_heap *heap, int size); + +#if CONFIG_DEBUG_MEMORY_USAGE_SCAN +/** Fetch runtime information about heap, like used and free memory space + * @param zone to check, see enum mem_zone. + * @param index heap index, eg. cpu core index for any *SYS* zone + * @param out output variable + * @return error code or zero + */ +int heap_info(enum mem_zone zone, int index, struct mm_info *out); +#endif + +/* retrieve memory map pointer */ +static inline struct mm *memmap_get(void) +{ + return sof_get()->memory_map; +} + +#endif /* __SOF_LIB_MM_HEAP_H__ */ diff --git a/posix/include/sof/lib/perf_cnt.h b/posix/include/sof/lib/perf_cnt.h new file mode 100644 index 000000000000..bddda9c8e06b --- /dev/null +++ b/posix/include/sof/lib/perf_cnt.h @@ -0,0 +1,188 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + * + * Author: Marcin Maka + */ + +/** + * \file xtos/include/sof/lib/perf_cnt.h + * \brief Simple performance counters + * \author Marcin Maka + */ + +#ifndef __SOF_LIB_PERF_CNT_H__ +#define __SOF_LIB_PERF_CNT_H__ + +#include + +struct perf_cnt_data { + uint32_t plat_ts; + uint32_t cpu_ts; + uint32_t plat_delta_last; + uint32_t plat_delta_peak; + uint32_t cpu_delta_last; + uint32_t cpu_delta_peak; + uint32_t cpu_delta_sum; + uint32_t sample_cnt; +}; + +#if CONFIG_PERFORMANCE_COUNTERS + +#define perf_cnt_trace(ctx, pcd) \ + tr_info(ctx, "perf plat last %u peak %u cpu last %u, peak %u", \ + (uint32_t)((pcd)->plat_delta_last), \ + (uint32_t)((pcd)->plat_delta_peak), \ + (uint32_t)((pcd)->cpu_delta_last), \ + (uint32_t)((pcd)->cpu_delta_peak)) + +/** \brief Clears performance counters data. */ +#define perf_cnt_clear(pcd) memset((pcd), 0, sizeof(struct perf_cnt_data)) + +/* NOTE: Zephyr's arch_timing_counter_get() might not be implemented + * for a particular platform. In this case let's fallback to use + * Zephyr's k_cycle_get_64(). This will result in both "platform" and + * "cpu" timestamps to be equal. + */ +#ifdef __ZEPHYR__ + #ifdef CONFIG_TIMING_FUNCTIONS + #define perf_cnt_get_cpu_ts arch_timing_counter_get + #else + #define perf_cnt_get_cpu_ts sof_cycle_get_64 + #endif /* CONFIG_TIMING_FUNCTIONS */ +#else + #define perf_cnt_get_cpu_ts() timer_get_system(cpu_timer_get()) +#endif /* __ZEPHYR__ */ + +/** \brief Initializes timestamps with current timer values. */ +#define perf_cnt_init(pcd) do { \ + (pcd)->plat_ts = sof_cycle_get_64(); \ + (pcd)->cpu_ts = perf_cnt_get_cpu_ts(); \ + } while (0) + +/* Trace macros that can be used as trace_m argument of the perf_cnt_stamp() + * to trace PCD values if the last arch timer reading exceeds the previous + * peak value. + * + * arg passed to perf_cnt_stamp() is forwarded to the trace_m() macro + * as the second argument. + */ + +/** \brief No trace when detecting peak value. */ +#define perf_trace_null(pcd, arg) + +/** \brief Simple trace, all values are printed, arg should be a tr_ctx address. + */ +#define perf_trace_simple(pcd, arg) perf_cnt_trace(arg, pcd) + +/* perf measurement windows size 2^x */ +#define PERF_CNT_CHECK_WINDOW_SIZE 10 +#define task_perf_avg_info(pcd, task_p, class) \ + tr_info(task_p, "perf_cycle task %p, %pU cpu avg %u peak %u",\ + class, (class)->uid, \ + (uint32_t)((pcd)->cpu_delta_sum), \ + (uint32_t)((pcd)->cpu_delta_peak)) +#define task_perf_cnt_avg(pcd, trace_m, arg, class) do { \ + (pcd)->cpu_delta_sum += (pcd)->cpu_delta_last; \ + if (++(pcd)->sample_cnt == 1 << PERF_CNT_CHECK_WINDOW_SIZE) { \ + (pcd)->cpu_delta_sum >>= PERF_CNT_CHECK_WINDOW_SIZE; \ + trace_m(pcd, arg, class); \ + (pcd)->cpu_delta_sum = 0; \ + (pcd)->sample_cnt = 0; \ + (pcd)->plat_delta_peak = 0; \ + (pcd)->cpu_delta_peak = 0; \ + } \ + } while (0) + +/** \brief Accumulates cpu timer delta samples calculated by perf_cnt_stamp(). + * + * If current sample count reaches the window size, compute the average and run trace_m. + * \param pcd Performance counters data. + * \param trace_m Trace function trace_m(pcd, arg) or trace macro if a + * more precise line number is desired in the logs. + * \param arg Argument passed to trace_m as arg. + */ +#define perf_cnt_average(pcd, trace_m, arg) do { \ + (pcd)->cpu_delta_sum += (pcd)->cpu_delta_last; \ + if (++(pcd)->sample_cnt == 1 << PERF_CNT_CHECK_WINDOW_SIZE) {\ + (pcd)->cpu_delta_sum >>= PERF_CNT_CHECK_WINDOW_SIZE; \ + trace_m(pcd, arg); \ + (pcd)->cpu_delta_sum = 0; \ + (pcd)->sample_cnt = 0; \ + (pcd)->plat_delta_peak = 0; \ + (pcd)->cpu_delta_peak = 0; \ + } \ + } while (0) + +/** \brief Reads the timers and computes delta to the previous readings. + * + * If current arch delta exceeds the previous peak value, trace_m is run. + * \param pcd Performance counters data. + * \param trace_m Trace function trace_m(pcd, arg) or trace macro if a + * more precise line number is desired in the logs. + * \param arg Argument passed to trace_m as arg. + */ +#define perf_cnt_stamp(pcd, trace_m, arg) do { \ + uint32_t plat_ts = \ + (uint32_t)sof_cycle_get_64(); \ + uint32_t cpu_ts = \ + (uint32_t)perf_cnt_get_cpu_ts(); \ + if (plat_ts > (pcd)->plat_ts) \ + (pcd)->plat_delta_last = plat_ts - (pcd)->plat_ts; \ + else \ + (pcd)->plat_delta_last = UINT32_MAX - (pcd)->plat_ts \ + + plat_ts; \ + if (cpu_ts > (pcd)->cpu_ts) \ + (pcd)->cpu_delta_last = cpu_ts - (pcd)->cpu_ts; \ + else \ + (pcd)->cpu_delta_last = UINT32_MAX - (pcd)->cpu_ts \ + + cpu_ts;\ + if ((pcd)->plat_delta_last > (pcd)->plat_delta_peak) \ + (pcd)->plat_delta_peak = (pcd)->plat_delta_last; \ + if ((pcd)->cpu_delta_last > (pcd)->cpu_delta_peak) { \ + (pcd)->cpu_delta_peak = (pcd)->cpu_delta_last; \ + trace_m(pcd, arg); \ + } \ + } while (0) + +/** + * For simple performance measurement and optimization in development stage, + * tic-toc api is provided. Performance data are traced at each tok call, + * to allow fast clocks usage deviation estimation. Example: + * + * \code{.c} + * void foo(struct comp_dev *dev) { + * static struct perf_cnt_data pcd; + * + * perf_tic(&pcd); + * bar(); + * perf_toc(&pcd, dev); + * } + * \endcode + */ + +/** \brief Save start timestamp in pcd structure + * + * \param pcd Performance counters data. + */ +#define perf_tic(pcd) \ + perf_cnt_init(pcd) + +/** \brief Save start timestamp in pcd structure + * + * \param pcd Performance counters data. + * \param comp Component used to get corresponding trace context. + */ +#define perf_toc(pcd, comp) do { \ + perf_cnt_stamp(pcd, perf_trace_null, NULL); \ + perf_trace_simple(pcd, trace_comp_get_tr_ctx(comp)); \ + } while (0) + +#else +#define perf_cnt_clear(pcd) +#define perf_cnt_init(pcd) +#define perf_cnt_stamp(pcd, trace_m, arg) +#define perf_cnt_average(pcd, trace_m, arg) +#endif + +#endif /* __SOF_LIB_PERF_CNT_H__ */ diff --git a/posix/include/sof/lib/pm_runtime.h b/posix/include/sof/lib/pm_runtime.h new file mode 100644 index 000000000000..c0a24116e629 --- /dev/null +++ b/posix/include/sof/lib/pm_runtime.h @@ -0,0 +1,176 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2018 Intel Corporation. All rights reserved. + * + * Author: Tomasz Lauda + * Janusz Jankowski + */ + +/** + * \file xtos/include/sof/lib/pm_runtime.h + * \brief Runtime power management header file + * \author Tomasz Lauda + */ + +#ifndef __SOF_LIB_PM_RUNTIME_H__ +#define __SOF_LIB_PM_RUNTIME_H__ + +#include +#include +#include +#include +#include +#include + +/** \addtogroup pm_runtime PM Runtime + * PM runtime specification. + * @{ + */ + +/* PM runtime flags */ + +#define RPM_ASYNC 0x01 /**< Request is asynchronous */ + +/** \brief Runtime power management context */ +enum pm_runtime_context { + PM_RUNTIME_HOST_DMA_L1 = 0, /**< Host DMA L1 */ + SSP_CLK, /**< SSP Clock */ + SSP_POW, /**< SSP Power */ + DMIC_CLK, /**< DMIC Clock */ + DMIC_POW, /**< DMIC Power */ + DW_DMAC_CLK, /**< DW DMAC Clock */ + CORE_MEMORY_POW, /**< Core Memory power */ + CORE_HP_CLK, /**< High Performance Clock*/ + PM_RUNTIME_DSP /**< DSP */ +}; + +/** \brief Runtime power management data. */ +struct pm_runtime_data { + struct k_spinlock lock; /**< lock mechanism */ + void *platform_data; /**< platform specific data */ +#if CONFIG_DSP_RESIDENCY_COUNTERS + struct r_counters_data *r_counters; /**< diagnostic DSP residency counters */ +#endif +}; + +#if CONFIG_DSP_RESIDENCY_COUNTERS +/** + * \brief DSP residency counters + * R0, R1, R2 are DSP residency counters which can be used differently + * based on platform implementation. + * In general R0 is the highest power consumption state while R2 is + * the lowest power consumption state. See platform specific pm_runtime.h + * for the platform HW specific mapping. + */ +enum dsp_r_state { + r0_r_state = 0, + r1_r_state, + r2_r_state +}; + +/** \brief Diagnostic DSP residency counters data */ +struct r_counters_data { + enum dsp_r_state cur_r_state; /**< current dsp_r_state */ + uint64_t ts; /**< dsp_r_state timestamp */ +}; +#endif + +/** + * \brief Initializes runtime power management. + */ +void pm_runtime_init(struct sof *sof); + +/** + * \brief Retrieves power management resource (async). + * + * \param[in] context Type of power management context. + * \param[in] index Index of the device. + */ +void pm_runtime_get(enum pm_runtime_context context, uint32_t index); + +/** + * \brief Retrieves power management resource. + * + * \param[in] context Type of power management context. + * \param[in] index Index of the device. + */ +void pm_runtime_get_sync(enum pm_runtime_context context, uint32_t index); + +/** + * \brief Releases power management resource (async). + * + * \param[in] context Type of power management context. + * \param[in] index Index of the device. + */ +void pm_runtime_put(enum pm_runtime_context context, uint32_t index); + +/** + * \brief Releases power management resource. + * + * \param[in] context Type of power management context. + * \param[in] index Index of the device. + */ +void pm_runtime_put_sync(enum pm_runtime_context context, uint32_t index); + +/** + * \brief Enables power management operations for the resource. + * + * \param[in] context Type of power management context. + * \param[in] index Index of the device. + */ +void pm_runtime_enable(enum pm_runtime_context context, uint32_t index); + +/** + * \brief Disables power management operations for the resource. + * + * \param[in] context Type of power management context. + * \param[in] index Index of the device. + */ +void pm_runtime_disable(enum pm_runtime_context context, uint32_t index); + +/** + * \brief Reports state of the power managed resource. + * + * @param context Type of power management context. + * @param index Index of the resource. + * + * @return true if the resource is active or pm disabled, false otherwise. + */ +bool pm_runtime_is_active(enum pm_runtime_context context, uint32_t index); + +/** + * \brief Retrieves pointer to runtime power management data. + * + * @return Runtime power management data pointer. + */ +static inline struct pm_runtime_data *pm_runtime_data_get(void) +{ + return sof_get()->prd; +} + +#if CONFIG_DSP_RESIDENCY_COUNTERS +/** + * \brief Initializes DSP residency counters. + * + * \param[in] context Type of power management context. + */ +void init_dsp_r_state(enum dsp_r_state); + +/** + * \brief Reports DSP residency state. + * + * \param[in] new state + */ +void report_dsp_r_state(enum dsp_r_state); + +/** + * \brief Retrieves current DSP residency state. + * + * @return active DSP residency state + */ +enum dsp_r_state get_dsp_r_state(void); +#endif + +/** @}*/ + +#endif /* __SOF_LIB_PM_RUNTIME_H__ */ diff --git a/posix/include/sof/lib/shim.h b/posix/include/sof/lib/shim.h new file mode 100644 index 000000000000..518880f1f953 --- /dev/null +++ b/posix/include/sof/lib/shim.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + * + * Author: Tomasz Lauda + */ + +#ifndef __SOF_LIB_SHIM_H__ +#define __SOF_LIB_SHIM_H__ + +#include + +#endif /* __SOF_LIB_SHIM_H__ */ diff --git a/posix/include/sof/list.h b/posix/include/sof/list.h new file mode 100644 index 000000000000..a81576fb5e68 --- /dev/null +++ b/posix/include/sof/list.h @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + * Keyon Jie + */ + +#ifndef __SOF_LIST_H__ +#define __SOF_LIST_H__ + +/* Really simple list manipulation */ + +struct list_item; + +struct list_item { + struct list_item *next; + struct list_item *prev; +}; + +/* a static list head initialiser */ +#define LIST_INIT(head) {&head, &head} + +/* initialise list before any use - list will point to itself */ +static inline void list_init(struct list_item *list) +{ + list->next = list; + list->prev = list; +} + +/* add new item to the start or head of the list */ +static inline void list_item_prepend(struct list_item *item, + struct list_item *list) +{ + struct list_item *next = list->next; + + next->prev = item; + item->next = next; + item->prev = list; + list->next = item; +} + +/* add new item to the end or tail of the list */ +static inline void list_item_append(struct list_item *item, + struct list_item *list) +{ + struct list_item *tail = list->prev; + + tail->next = item; + item->next = list; + item->prev = tail; + list->prev = item; +} + +/* delete item from the list leaves deleted list item + *in undefined state list_is_empty will return true + */ +static inline void list_item_del(struct list_item *item) +{ + item->next->prev = item->prev; + item->prev->next = item->next; + list_init(item); +} + +/* is list item the last item in list ? */ +static inline int list_item_is_last(struct list_item *item, + struct list_item *list) +{ + return item->next == list; +} + +/* is list empty ? */ +#define list_is_empty(item) \ + ((item)->next == item) + +#define __list_object(item, type, offset) \ + ((type *)((char *)(item) - (offset))) + +/* get the container object of the list item */ +#define list_item(item, type, member) \ + __list_object(item, type, offsetof(type, member)) + +/* get the container object of the first item in the list */ +#define list_first_item(list, type, member) \ + __list_object((list)->next, type, offsetof(type, member)) + +/* get the next container object in the list */ +#define list_next_item(object, member) \ + list_item((object)->member.next, typeof(*(object)), member) + +/* list iterator */ +#define list_for_item(item, list) \ + for (item = (list)->next; item != (list); item = item->next) + +/* list iterator */ +#define list_for_item_prev(item, list) \ + for (item = (list)->prev; item != (list); item = item->prev) + +/* list iterator - safe to delete items */ +#define list_for_item_safe(item, tmp, list) \ + for (item = (list)->next, tmp = item->next;\ + item != (list); \ + item = tmp, tmp = item->next) + +/** + * Re-links the list when head address changed (list moved). + * @param new_list New address of the head. + * @param old_list Old address of the head. + */ +static inline void list_relink(struct list_item *new_list, + struct list_item *old_list) +{ + struct list_item *li; + + if (new_list->next == old_list) { + list_init(new_list); + } else { + list_for_item(li, new_list) + if (li->next == old_list) + li->next = new_list; /* for stops here */ + list_for_item_prev(li, new_list) + if (li->prev == old_list) + li->prev = new_list; /* for stops here */ + } +} + +#endif /* __SOF_LIST_H__ */ diff --git a/rimage b/rimage deleted file mode 160000 index 4fb9fe00575b..000000000000 --- a/rimage +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4fb9fe00575bc2e9f14570803d811987fb27f010 diff --git a/scripts/cmake/git-submodules.cmake b/scripts/cmake/git-submodules.cmake index 5b486e4af87c..56c559491b90 100644 --- a/scripts/cmake/git-submodules.cmake +++ b/scripts/cmake/git-submodules.cmake @@ -1,11 +1,17 @@ # SPDX-License-Identifier: BSD-3-Clause -find_package(Git) -set(RIMAGE_CMAKE "${SOF_ROOT_SOURCE_DIRECTORY}/rimage/CMakeLists.txt") +set(RIMAGE_SUBMODULE "${SOF_ROOT_SOURCE_DIRECTORY}/rimage") +if(EXISTS "${RIMAGE_SUBMODULE}/CMakeLists.txt") + message(WARNING + "${RIMAGE_SUBMODULE} is deprecated and ignored" + ) +endif() +find_package(Git) +set(TOMLC99_MAKE "${SOF_ROOT_SOURCE_DIRECTORY}/tools/rimage/tomlc99/Makefile") if(GIT_FOUND AND EXISTS "${SOF_ROOT_SOURCE_DIRECTORY}/.git") - if(EXISTS "${RIMAGE_CMAKE}") + if(EXISTS "${TOMLC99_MAKE}") # As incredible as it sounds, some people run neither # "git status" nor "git diff" every few minutes and not @@ -36,10 +42,10 @@ if(GIT_FOUND AND EXISTS "${SOF_ROOT_SOURCE_DIRECTORY}/.git") NOT CONFIG_LIBRARY) message(FATAL_ERROR -"${RIMAGE_CMAKE} not found. You should have used 'git clone --recursive'. \ +"${TOMLC99_MAKE} not found. You should have used 'git clone --recursive'. \ To fix this existing git clone run: -git submodule update --init --merge --recursive +git submodule update --init --merge tools/rimage/tomlc99 ") - endif() # rimage/CMakeLists.txt + endif() # tomlc99/Makefile endif() # .git/ diff --git a/scripts/fuzz.sh b/scripts/fuzz.sh index d999beeb476a..47bd565d40ab 100755 --- a/scripts/fuzz.sh +++ b/scripts/fuzz.sh @@ -49,14 +49,14 @@ main() { setup + BUILD_ONLY=false # Parse "$@". getopts stops after '--' - while getopts "ho:t:c:b" opt; do + while getopts "ho:t:b" opt; do case "$opt" in h) print_help; exit 0;; o) FUZZER_STDOUT="$OPTARG";; t) TEST_DURATION="$OPTARG";; - b) BUILD_ONLY=1;; - c) OVERLAY="$OPTARG";; + b) BUILD_ONLY=true;; *) print_help; exit 1;; esac done @@ -80,15 +80,11 @@ main() -DCONFIG_ASAN=y ) - if [ ! -z $OVERLAY ]; then - overlay_config=$(xargs -a "$SOF_TOP/app/$OVERLAY" printf -- "-D%s ") - fi - west build -d build-fuzz -b native_posix "$SOF_TOP"/app/ -- \ - "${fuzz_configs[@]}" "$overlay_config" "$@" + "${fuzz_configs[@]}" "$@" - if [ $BUILD_ONLY -eq 1 ]; then - exit + if $BUILD_ONLY; then + exit 0 fi mkdir -p ./fuzz_corpus diff --git a/scripts/rebuild-testbench.sh b/scripts/rebuild-testbench.sh index 620b15dbeb26..bc70456f90ad 100755 --- a/scripts/rebuild-testbench.sh +++ b/scripts/rebuild-testbench.sh @@ -2,7 +2,7 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2020, Mohana Datta Yelugoti -# fail on any errors +# stop on most errors set -e # Defaults @@ -15,6 +15,7 @@ print_usage() cat <] -p Build testbench binary for xt-run for selected platform, e.g. -p tgl + When omitted, perform a BUILD_TYPE=native, compile-only check. -f Build testbench with compiler provided by fuzzer (default path: $HOME/sof/work/AFL/afl-gcc) -j number of parallel make/ninja jobs. Defaults to /usr/bin/nproc. @@ -78,7 +79,7 @@ setup_xtensa_tools_build() export CC=$tools_bin/$compiler export LD=$tools_bin/xt-ld export OBJDUMP=$tools_bin/xt-objdump - export LDFLAGS="-mlsp=sim -Wl,-LE $testbench_sections" + export LDFLAGS="-mlsp=sim $testbench_sections" export XTENSA_CORE } @@ -139,7 +140,7 @@ main() done rebuild_testbench - + printf '\n' testbench_usage } diff --git a/scripts/xtensa-build-all.sh b/scripts/xtensa-build-all.sh index e8cae4417964..e54298dcd56a 100755 --- a/scripts/xtensa-build-all.sh +++ b/scripts/xtensa-build-all.sh @@ -20,6 +20,9 @@ SUPPORTED_PLATFORMS=( "${DEFAULT_PLATFORMS[@]}" ) # Waiting for container work in progress SUPPORTED_PLATFORMS+=( mt8188 ) +# Container work is in progress +SUPPORTED_PLATFORMS+=( acp_6_3 ) + BUILD_ROM=no BUILD_DEBUG=no BUILD_FORCE_UP=no @@ -242,6 +245,13 @@ do HOST="xtensa-vangogh-elf" XTENSA_TOOLS_VERSION="RI-2019.1-linux" ;; + acp_6_3) + PLATFORM="acp_6_3" + ARCH="xtensa" + XTENSA_CORE="ACP_6_3_HiFi5_PROD_Linux" + HOST="xtensa-acp_6_3-elf" + XTENSA_TOOLS_VERSION="RI-2021.6-linux" + ;; mt8186) PLATFORM="mt8186" XTENSA_CORE="hifi5_7stg_I64D128" diff --git a/scripts/xtensa-build-zephyr.py b/scripts/xtensa-build-zephyr.py index 8a2b3532708a..0d8e28921c3d 100755 --- a/scripts/xtensa-build-zephyr.py +++ b/scripts/xtensa-build-zephyr.py @@ -176,9 +176,6 @@ def parse_args(): help="List of platforms to build") parser.add_argument("-d", "--debug", required=False, action="store_true", help="Shortcut for: -o sof/app/debug_overlay.conf") - parser.add_argument("-i", "--ipc", required=False, choices=["IPC4"], - help="""Applies --overlay /ipc4_overlay.conf -and a different rimage config. Valid only for IPC3 platforms supporting IPC4 too.""") # NO SOF release will ever user the option --fw-naming. # This option is only for disguising SOF IPC4 as CAVS IPC4 and only in cases where # the kernel 'ipc_type' expects CAVS IPC4. In this way, developers and CI can test @@ -265,10 +262,6 @@ def parse_args(): if not args.use_platform_subdir: args.use_platform_subdir=True warnings.warn("The option '--fw-naming AVS' has to be used with '--use-platform-subdir'. Enable '--use-platform-subdir' automatically.") - if args.ipc != "IPC4": - args.ipc="IPC4" - warnings.warn("The option '--fw-naming AVS' has to be used with '-i IPC4'. Enable '-i IPC4' automatically.") - def execute_command(*run_args, **run_kwargs): """[summary] Provides wrapper for subprocess.run that prints @@ -519,7 +512,7 @@ def clean_staging(platform): # for now we must stick to `sof/rimage/[tomlc99]` for # backwards-compatibility with XTOS platforms and git submodules, see more # detailed comments in west.yml -RIMAGE_SOURCE_DIR = west_top / "sof" / "rimage" +RIMAGE_SOURCE_DIR = west_top / "sof" / "tools" / "rimage" def rimage_west_configuration(platform_dict, dest_dir): @@ -570,14 +563,11 @@ def rimage_west_configuration(platform_dict, dest_dir): def build_rimage(): - # Detect non-west rimage duplicates, example: git submdule - # SOF_TOP/rimage = sof2/rimage - nested_rimage = pathlib.Path(SOF_TOP, "rimage") - if nested_rimage.is_dir() and not nested_rimage.samefile(RIMAGE_SOURCE_DIR): - raise RuntimeError( - f"""Two rimage source directories found. - Move non-west {nested_rimage} out of west workspace {west_top}. - See output of 'west list'.""" + old_rimage_loc = SOF_TOP / "rimage" + # Don't warn on empty directories + if ( old_rimage_loc / "CMakeLists.txt" ).exists(): + warnings.warn(f"""{old_rimage_loc} is now ignored, + new location is {RIMAGE_SOURCE_DIR}""" ) rimage_dir_name = RIMAGE_BUILD_DIR.name # CMake build rimage module @@ -626,7 +616,7 @@ def rimage_options(platform_dict): # test_00_01_load_fw_and_check_version opts.append(("-b", "1")) - if args.ipc == "IPC4": + if platform_dict.get("IPC4_RIMAGE_DESC", None) is not None: rimage_desc = platform_dict["IPC4_RIMAGE_DESC"] else: rimage_desc = platform_dict["name"] + ".toml" @@ -725,13 +715,6 @@ def build_platforms(): if args.debug: overlays.append(str(pathlib.Path(SOF_TOP, "app", "debug_overlay.conf"))) - # The '-i IPC4' is a shortcut for '-o path_to_ipc4_overlay' (and more), we - # are good if both are provided, because it's no harm to merge the same - # overlay twice. - if args.ipc == "IPC4": - overlays.append(str(pathlib.Path(SOF_TOP, "app", "overlays", platform, - platform_dict["IPC4_CONFIG_OVERLAY"]))) - if overlays: overlays = ";".join(overlays) build_cmd.append(f"-DOVERLAY_CONFIG={overlays}") diff --git a/smex/CMakeLists.txt b/smex/CMakeLists.txt index 5d198832f472..23eeb3a775f3 100644 --- a/smex/CMakeLists.txt +++ b/smex/CMakeLists.txt @@ -28,7 +28,7 @@ target_link_options(smex PRIVATE target_include_directories(smex PRIVATE "${SOF_ROOT_SOURCE_DIRECTORY}/src/include" - "${SOF_ROOT_SOURCE_DIRECTORY}/rimage/src/include" + "${SOF_ROOT_SOURCE_DIRECTORY}/tools/rimage/src/include" ) # TODO: smex should not need RTOS headers: FIX. diff --git a/smex/elf.c b/smex/elf.c index bd088716691d..0d0e976dcb8a 100644 --- a/smex/elf.c +++ b/smex/elf.c @@ -17,7 +17,7 @@ static int elf_read_sections(struct elf_module *module, bool verbose) { Elf32_Ehdr *hdr = &module->hdr; - Elf32_Shdr *section = module->section; + Elf32_Shdr *section; size_t count; int i, ret; uint32_t valid = (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR); @@ -27,7 +27,7 @@ static int elf_read_sections(struct elf_module *module, bool verbose) if (ret < 0) { fprintf(stderr, "error: can't seek to %s section header %d\n", module->elf_file, ret); - return ret; + return -errno; } /* allocate space for each section header */ @@ -41,7 +41,7 @@ static int elf_read_sections(struct elf_module *module, bool verbose) if (count != hdr->shnum) { fprintf(stderr, "error: failed to read %s section header %d\n", module->elf_file, -errno); - return -errno; + return count < 0 ? -errno : -ENODATA; } /* read in strings */ @@ -56,7 +56,7 @@ static int elf_read_sections(struct elf_module *module, bool verbose) if (ret < 0) { fprintf(stderr, "error: can't seek to %s stringss %d\n", module->elf_file, ret); - return ret; + return -errno; } count = fread(module->strings, 1, section[hdr->shstrndx].size, @@ -64,7 +64,7 @@ static int elf_read_sections(struct elf_module *module, bool verbose) if (count != section[hdr->shstrndx].size) { fprintf(stderr, "error: failed to read %s strings %d\n", module->elf_file, -errno); - return -errno; + return count < 0 ? -errno : -ENODATA; } module->bss_index = elf_find_section(module, ".bss"); @@ -128,7 +128,7 @@ static int elf_read_sections(struct elf_module *module, bool verbose) static int elf_read_programs(struct elf_module *module, bool verbose) { Elf32_Ehdr *hdr = &module->hdr; - Elf32_Phdr *prg = module->prg; + Elf32_Phdr *prg; size_t count; int i, ret; @@ -137,7 +137,7 @@ static int elf_read_programs(struct elf_module *module, bool verbose) if (ret < 0) { fprintf(stderr, "error: cant seek to %s program header %d\n", module->elf_file, ret); - return ret; + return -errno; } /* allocate space for programs */ @@ -151,7 +151,7 @@ static int elf_read_programs(struct elf_module *module, bool verbose) if (count != hdr->phnum) { fprintf(stderr, "error: failed to read %s program header %d\n", module->elf_file, -errno); - return -errno; + return count < 0 ? -errno : -ENODATA; } /* check each program */ @@ -191,7 +191,7 @@ static int elf_read_hdr(struct elf_module *module, bool verbose) if (count != 1) { fprintf(stderr, "error: failed to read %s elf header %d\n", module->elf_file, -errno); - return -errno; + return count < 0 ? -errno : -ENODATA; } if (!verbose) @@ -398,6 +398,7 @@ int elf_find_section(const struct elf_module *module, const char *name) ret = fseek(module->fd, section->off, SEEK_SET); if (ret < 0) { fprintf(stderr, "error: cant seek to string section %d\n", ret); + ret = -errno; goto out; } @@ -405,13 +406,20 @@ int elf_find_section(const struct elf_module *module, const char *name) if (count != section->size) { fprintf(stderr, "error: can't read string section %d\n", -errno); - ret = -errno; + ret = count < 0 ? -errno : -ENODATA; goto out; } + buffer[section->size - 1] = '\0'; /* find section with name */ for (i = 0; i < hdr->shnum; i++) { s = &module->section[i]; + if (s->name >= section->size) { + fprintf(stderr, "error: invalid section name string index %d\n", s->name); + ret = -EINVAL; + goto out; + } + if (!strcmp(name, buffer + s->name)) { ret = i; goto out; @@ -431,8 +439,8 @@ int elf_read_section(const struct elf_module *module, const char *section_name, const Elf32_Shdr **dst_section, void **dst_buff) { const Elf32_Shdr *section; - int section_index = -1; - int read; + int section_index; + int ret; section_index = elf_find_section(module, section_name); if (section_index < 0) { @@ -451,17 +459,25 @@ int elf_read_section(const struct elf_module *module, const char *section_name, return -ENOMEM; /* fill buffer with section content */ - fseek(module->fd, section->off, SEEK_SET); - read = fread(*dst_buff, 1, section->size, module->fd); - if (read != section->size) { - fprintf(stderr, - "error: can't read %s section %d\n", section_name, - -errno); - free(*dst_buff); - return -errno; + ret = fseek(module->fd, section->off, SEEK_SET); + if (ret) { + fprintf(stderr, "error: can't seek to %s section %d\n", section_name, -errno); + ret = -errno; + goto error; + } + + ret = fread(*dst_buff, 1, section->size, module->fd); + if (ret != section->size) { + fprintf(stderr, "error: can't read %s section %d\n", section_name, -errno); + ret = ret < 0 ? -errno : -ENODATA; + goto error; } return section->size; + +error: + free(*dst_buff); + return ret; } int elf_read_module(struct elf_module *module, const char *name, bool verbose) @@ -479,12 +495,16 @@ int elf_read_module(struct elf_module *module, const char *name, bool verbose) /* get file size */ ret = fseek(module->fd, 0, SEEK_END); - if (ret < 0) + if (ret < 0) { + ret = -errno; goto hdr_err; + } module->file_size = ftell(module->fd); ret = fseek(module->fd, 0, SEEK_SET); - if (ret < 0) + if (ret < 0) { + ret = -errno; goto hdr_err; + } /* read in elf header */ ret = elf_read_hdr(module, verbose); diff --git a/src/arch/host/CMakeLists.txt b/src/arch/host/CMakeLists.txt index 39b0ea640bd4..75314f00f556 100644 --- a/src/arch/host/CMakeLists.txt +++ b/src/arch/host/CMakeLists.txt @@ -5,10 +5,9 @@ target_include_directories(sof_public_headers INTERFACE ${PROJECT_SOURCE_DIR}/sr target_include_directories(sof_public_headers INTERFACE ${PROJECT_SOURCE_DIR}/src/platform/library/include) include(CheckCCompilerFlag) -# TODO: library should not need RTOS headers: FIX. if (NOT CONFIG_SOF_ZEPHYR_STRICT_HEADERS) target_include_directories(sof_public_headers INTERFACE - ${PROJECT_SOURCE_DIR}/xtos/include + ${PROJECT_SOURCE_DIR}/posix/include ) endif() @@ -19,8 +18,9 @@ if (supports_implicit_fallthrough) endif() # C & ASM flags -target_compile_options(sof_options INTERFACE -g -O3 -fPIC -DPIC -Wall -Werror -Wmissing-prototypes - ${implicit_fallthrough} -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -Wpointer-arith +target_compile_options(sof_options INTERFACE -g -O3 -fPIC -DPIC -std=c99 -std=gnu99 -fgnu89-inline + -Wall -Werror -Wmissing-prototypes ${implicit_fallthrough} -Wno-pointer-to-int-cast + -Wno-int-to-pointer-cast -Wpointer-arith -DCONFIG_LIBRARY "-imacros${CONFIG_H_PATH}") if(NOT BUILD_UNIT_TESTS_HOST) diff --git a/src/arch/host/configs/library_defconfig b/src/arch/host/configs/library_defconfig index 6de2eef3333f..071e30808f3c 100644 --- a/src/arch/host/configs/library_defconfig +++ b/src/arch/host/configs/library_defconfig @@ -3,6 +3,7 @@ CONFIG_COMP_CROSSOVER=y CONFIG_COMP_DCBLOCK=y CONFIG_COMP_DRC=y CONFIG_COMP_FIR=y +CONFIG_COMP_GOOGLE_RTC_AUDIO_PROCESSING=y CONFIG_COMP_IIR=y CONFIG_COMP_MFCC=y CONFIG_COMP_MODULE_ADAPTER=y @@ -11,6 +12,7 @@ CONFIG_COMP_MUX=y CONFIG_COMP_SEL=y CONFIG_COMP_SRC=y CONFIG_COMP_SRC_IPC4_FULL_MATRIX=y +CONFIG_COMP_STUBS=y CONFIG_COMP_TDFB=y CONFIG_COMP_VOLUME=y CONFIG_COMP_VOLUME_LINEAR_RAMP=y diff --git a/src/arch/host/configs/plugin_ipc4_defconfig b/src/arch/host/configs/plugin_ipc4_defconfig new file mode 100644 index 000000000000..43529dc87726 --- /dev/null +++ b/src/arch/host/configs/plugin_ipc4_defconfig @@ -0,0 +1,22 @@ +CONFIG_IPC_MAJOR_4=y +CONFIG_LIBRARY=y +CONFIG_TRACEV=y +CONFIG_DEBUG_MEMORY_USAGE_SCAN=n +CONFIG_COMP_CROSSOVER=y +CONFIG_COMP_DRC=y +CONFIG_COMP_MULTIBAND_DRC=y +CONFIG_COMP_SRC=y +CONFIG_COMP_SRC_IPC4_FULL_MATRIX=y +CONFIG_COMP_MFCC=y +CONFIG_COMP_GAIN=y +CONFIG_COMP_VOLUME_WINDOWS_FADE=y +CONFIG_COMP_MODULES_SO=y +CONFIG_COMP_MODULE_ADAPTER=y +CONFIG_COMP_MIXER=y +CONFIG_IPC4_GATEWAY=n +CONFIG_COMP_DAI_GROUP=n +CONFIG_FORMAT_S16LE=y +CONFIG_FORMAT_S32LE=y +CONFIG_FORMAT_S24LE=y +CONFIG_COMP_PEAK_VOL=n +CONFIG_COMP_MODULE_SHARED_LIBRARY_BUILD=y diff --git a/src/arch/host/include/arch/debug/panic.h b/src/arch/host/include/arch/debug/panic.h index 67fb04aa70eb..85f47a5ecbbc 100644 --- a/src/arch/host/include/arch/debug/panic.h +++ b/src/arch/host/include/arch/debug/panic.h @@ -5,7 +5,7 @@ * Author: Tomasz Lauda */ -#ifdef __XTOS_RTOS_PANIC_H__ +#ifdef __POSIX_RTOS_PANIC_H__ #ifndef __ARCH_DEBUG_PANIC_H__ #define __ARCH_DEBUG_PANIC_H__ @@ -21,4 +21,4 @@ static inline void arch_dump_regs(void *dump_buf, uintptr_t stack_ptr, #error "This file shouldn't be included from outside of XTOS's rtos/panic.h" -#endif /* __XTOS_RTOS_PANIC_H__ */ +#endif /* __POSIX_RTOS_PANIC_H__ */ diff --git a/src/arch/host/include/arch/drivers/idc.h b/src/arch/host/include/arch/drivers/idc.h index 73719e55f2b8..3f3e67b89d76 100644 --- a/src/arch/host/include/arch/drivers/idc.h +++ b/src/arch/host/include/arch/drivers/idc.h @@ -5,7 +5,7 @@ * Author: Tomasz Lauda */ -#ifdef __XTOS_RTOS_IDC_H__ +#ifdef __POSIX_RTOS_IDC_H__ #ifndef __ARCH_DRIVERS_IDC_H__ #define __ARCH_DRIVERS_IDC_H__ @@ -16,4 +16,4 @@ #error "This file shouldn't be included from outside of XTOS's rtos/idc.h" -#endif /* __XTOS_RTOS_IDC_H__ */ +#endif /* __POSIX_RTOS_IDC_H__ */ diff --git a/src/arch/host/include/arch/schedule/task.h b/src/arch/host/include/arch/schedule/task.h index 5c6cbf102744..2b89d264e0a6 100644 --- a/src/arch/host/include/arch/schedule/task.h +++ b/src/arch/host/include/arch/schedule/task.h @@ -11,7 +11,7 @@ * \authors Liam Girdwood */ -#ifdef __XTOS_RTOS_TASK_H__ +#ifdef __POSIX_RTOS_TASK_H__ #ifndef __ARCH_SCHEDULE_TASK_H__ #define __ARCH_SCHEDULE_TASK_H__ @@ -20,6 +20,6 @@ #else -#error "This file shouldn't be included from outside of XTOS's rtos/task.h" +#error "This file shouldn't be included from outside of XTOS's posix/task.h" -#endif /* __XTOS_RTOS_TASK_H__ */ +#endif /* __POSIX_RTOS_TASK_H__ */ diff --git a/src/arch/host/include/arch/spinlock.h b/src/arch/host/include/arch/spinlock.h index 273133490e72..360cb72bdb1f 100644 --- a/src/arch/host/include/arch/spinlock.h +++ b/src/arch/host/include/arch/spinlock.h @@ -6,7 +6,7 @@ */ /* TODO: this needs fixed as part of the "host does not need rtos headers work" */ -#ifdef __XTOS_RTOS_SPINLOCK_H__ +#ifdef __POSIX_RTOS_SPINLOCK_H__ #ifndef __ARCH_SPINLOCK_H__ #define __ARCH_SPINLOCK_H__ diff --git a/src/arch/host/include/arch/string.h b/src/arch/host/include/arch/string.h index 166b417173f0..125f7bf555a6 100644 --- a/src/arch/host/include/arch/string.h +++ b/src/arch/host/include/arch/string.h @@ -5,7 +5,7 @@ * Author: Liam Girdwood */ -#ifdef __XTOS_RTOS_STRING_H__ +#ifdef __POSIX_RTOS_STRING_H__ #ifndef __ARCH_STRING_H__ #define __ARCH_STRING_H__ diff --git a/src/arch/xtensa/CMakeLists.txt b/src/arch/xtensa/CMakeLists.txt index 474be5988727..45d6782cc22e 100644 --- a/src/arch/xtensa/CMakeLists.txt +++ b/src/arch/xtensa/CMakeLists.txt @@ -16,6 +16,8 @@ elseif(CONFIG_REMBRANDT) set(platform_folder amd/rembrandt) elseif(CONFIG_VANGOGH) set(platform_folder amd/vangogh) +elseif(CONFIG_ACP_6_3) + set(platform_folder amd/acp_6_3) elseif(CONFIG_MT8186) set(platform_folder mt8186) elseif(CONFIG_MT8188) @@ -330,7 +332,7 @@ add_custom_target( ExternalProject_Add(rimage_ep DEPENDS check_version_h - SOURCE_DIR "${PROJECT_SOURCE_DIR}/rimage" + SOURCE_DIR "${RIMAGE_TOP}" PREFIX "${PROJECT_BINARY_DIR}/rimage_ep" BINARY_DIR "${PROJECT_BINARY_DIR}/rimage_ep/build" EXCLUDE_FROM_ALL TRUE @@ -386,7 +388,7 @@ if(MEU_PATH OR DEFINED MEU_NO_SIGN) # Don't sign with rimage run_rimage COMMAND ${PROJECT_BINARY_DIR}/rimage_ep/build/rimage -o sof-${fw_name}.ri - -c "${PROJECT_SOURCE_DIR}/rimage/config/${fw_name}.toml" + -c "${RIMAGE_TOP}/config/${fw_name}.toml" -s ${MEU_OFFSET} -k ${RIMAGE_PRIVATE_KEY} -i ${RIMAGE_IMR_TYPE} @@ -427,7 +429,7 @@ else() # sign with rimage run_rimage COMMAND ${PROJECT_BINARY_DIR}/rimage_ep/build/rimage -o sof-${fw_name}.ri - -c "${PROJECT_SOURCE_DIR}/rimage/config/${fw_name}.toml" + -c "${RIMAGE_TOP}/config/${fw_name}.toml" -k ${RIMAGE_PRIVATE_KEY} -i ${RIMAGE_IMR_TYPE} -f ${SOF_MAJOR}.${SOF_MINOR}.${SOF_MICRO} @@ -472,7 +474,7 @@ add_custom_target( # NXP set(UNSIGNED_RI imx8 imx8x imx8m imx8ulp) # AMD -list(APPEND UNSIGNED_RI rn rmb vangogh) +list(APPEND UNSIGNED_RI rn rmb vangogh acp_6_3) # MediaTek list(APPEND UNSIGNED_RI mt8186 mt8188 mt8195) diff --git a/src/arch/xtensa/configs/acp_6_3_defconfig b/src/arch/xtensa/configs/acp_6_3_defconfig new file mode 100644 index 000000000000..4a4646306ba4 --- /dev/null +++ b/src/arch/xtensa/configs/acp_6_3_defconfig @@ -0,0 +1,36 @@ +CONFIG_ACP_6_3=y +CONFIG_RIMAGE_SIGNING_SCHEMA="acp_6_3" +CONFIG_TRACE_CHANNEL=7 +CONFIG_WRAP_ACTUAL_POSITION=y +CONFIG_AMD_BT=n +CONFIG_AMD_SP=n +CONFIG_CORE_COUNT=1 +CONFIG_LP_MEMORY_BANKS=0 +CONFIG_HP_MEMORY_BANKS=10 +CONFIG_FORMAT_CONVERT_HIFI3=n +CONFIG_LP_SRAM=n +CONFIG_HAVE_AGENT=n +CONFIG_COMP_VOLUME=n +CONFIG_COMP_SRC=n +CONFIG_COMP_FIR=n +CONFIG_COMP_IIR=n +CONFIG_COMP_DCBLOCK=n +CONFIG_COMP_CROSSOVER=n +CONFIG_COMP_DRC=n +CONFIG_COMP_MULTIBAND_DRC=n +CONFIG_COMP_TONE=n +CONFIG_COMP_SWITCH=n +CONFIG_COMP_KPB=n +CONFIG_MAXIM_DSM=n +CONFIG_COMP_ASRC=n +CONFIG_COMP_IGO_NR=n +CONFIG_COMP_COPIER=n +CONFIG_COMP_RTNR=n +CONFIG_COMP_ARIA=n +CONFIG_COMP_BASEFW_IPC4=n +CONFIG_COMP_UP_DOWN_MIXER=n +CONFIG_COMP_DCBLOCK=n +CONFIG_COMP_TDFB=n +#CONFIG_COMP_MUX=n +CONFIG_COMP_SEL=n +CONFIG_COMP_MIXER=n diff --git a/src/audio/CMakeLists.txt b/src/audio/CMakeLists.txt index f35dd917eae0..425756f7e4d5 100644 --- a/src/audio/CMakeLists.txt +++ b/src/audio/CMakeLists.txt @@ -6,7 +6,7 @@ elseif(CONFIG_IPC_MAJOR_4) set(mixer_src mixin_mixout/mixin_mixout.c mixin_mixout/mixin_mixout_generic.c mixin_mixout/mixin_mixout_hifi3.c) endif() -if((NOT CONFIG_LIBRARY) OR CONFIG_LIBRARY_STATIC) +if(NOT CONFIG_COMP_MODULE_SHARED_LIBRARY_BUILD) add_local_sources(sof host-legacy.c component.c @@ -17,6 +17,7 @@ if((NOT CONFIG_LIBRARY) OR CONFIG_LIBRARY_STATIC) audio_stream.c channel_map.c ) + if(CONFIG_COMP_BLOB) add_local_sources(sof data_blob.c) endif() @@ -62,7 +63,7 @@ if((NOT CONFIG_LIBRARY) OR CONFIG_LIBRARY_STATIC) dai-legacy.c ) endif() - if(CONFIG_COMP_KPB) + if(CONFIG_COMP_KPB AND NOT CONFIG_LIBRARY_STATIC) add_local_sources(sof kpb.c ) @@ -89,7 +90,7 @@ if((NOT CONFIG_LIBRARY) OR CONFIG_LIBRARY_STATIC) if(CONFIG_COMP_RTNR) add_subdirectory(rtnr) endif() - if(CONFIG_COMP_BASEFW_IPC4) + if(CONFIG_COMP_BASEFW_IPC4 AND NOT CONFIG_LIBRARY) add_local_sources(sof base_fw.c ) @@ -125,6 +126,11 @@ add_local_sources(sof component.c data_blob.c buffer.c + source_api_helper.c + sink_api_helper.c + sink_source_utils.c + audio_stream.c + channel_map.c ) # Audio Modules with various optimizaitons @@ -168,11 +174,14 @@ set(sof_audio_modules mixer volume src asrc eq-fir eq-iir dcblock crossover tdfb # sources for each module if(CONFIG_IPC_MAJOR_3) set(volume_sources volume/volume.c volume/volume_generic.c volume/volume_ipc3.c) + set(src_sources src/src.c src/src_ipc3.c src/src_generic.c) + set(eq-iir_sources eq_iir/eq_iir_ipc3.c eq_iir/eq_iir_generic.c) elseif(CONFIG_IPC_MAJOR_4) set(volume_sources volume/volume.c volume/volume_generic.c volume/volume_ipc4.c) + set(src_sources src/src.c src/src_ipc4.c src/src_generic.c) + set(eq-iir_sources eq_iir/eq_iir_ipc4.c eq_iir/eq_iir_generic.c) endif() set(mixer_sources ${mixer_src}) -set(src_sources src/src.c src/src_generic.c) set(asrc_sources asrc/asrc.c asrc/asrc_farrow.c asrc/asrc_farrow_generic.c) set(eq-fir_sources eq_fir/eq_fir.c eq_fir/eq_fir_generic.c) set(eq-iir_sources eq_iir/eq_iir.c) diff --git a/src/audio/Kconfig b/src/audio/Kconfig index be2ff5f360b2..b05957a835d3 100644 --- a/src/audio/Kconfig +++ b/src/audio/Kconfig @@ -2,6 +2,8 @@ menu "Audio components" +rsource "volume/Kconfig" + config COMP_BASEFW_IPC4 bool "BASEFW component" default y @@ -124,6 +126,18 @@ config COMP_SRC help Select for SRC component +config COMP_SRC_LITE + bool "SRC_LITE component" + default y + help + Select for SRC_LITE component + which only supports a subset of conversions + supported by the SRC module: + 48 -> 16kHz + 44.1 -> 16 kHz + 32 -> 16 kHz + 44.1 -> 48 + config COMP_STUBS bool "Build all selected third-party (3P) components with stubs" default n @@ -209,7 +223,8 @@ config COMP_TONE default n select CORDIC_FIXED help - Select for Tone component + Select for Tone component. + Warning: This component is deprecated and will be removed from SOF v2.8. config COMP_MIXER bool "Mixer component" @@ -702,4 +717,12 @@ config WRAP_ACTUAL_POSITION It is not necessary that on wrap, the buffer position would be zero.At wrap, in some cases based on the period size, the frame may not exactly be at the end of the buffer and roll over for some bytes from the beginning of the buffer. + +config COMP_MODULE_SHARED_LIBRARY_BUILD + bool "Build SOF modules as shared libraries" + default n + help + Select if you want to build modules as shared objects that can be used to run + pipelines on the host with the testbench or the ALSA plugin. + endmenu diff --git a/src/audio/aria/aria.c b/src/audio/aria/aria.c index 9d9c16c9c1d9..d338ae22743e 100644 --- a/src/audio/aria/aria.c +++ b/src/audio/aria/aria.c @@ -4,7 +4,6 @@ // // Author: Adrian Bonislawski -#include #include #include #include @@ -20,13 +19,15 @@ #include #include #include -#include #include #include #include #include #include #include +#include "aria.h" + +#define ARIA_SET_ATTENUATION 1 LOG_MODULE_REGISTER(aria, CONFIG_SOF_LOG_LEVEL); @@ -46,11 +47,17 @@ static size_t get_required_emory(size_t chan_cnt, size_t smpl_group_cnt) return ALIGN_UP(num_of_ms * chan_cnt * smpl_group_cnt, 2) * sizeof(int32_t); } +static void aria_set_gains(struct aria_data *cd) +{ + int i; + + for (i = 0; i < ARIA_MAX_GAIN_STATES; ++i) + cd->gains[i] = (1ULL << (32 - cd->att - 1)) - 1; +} + static int aria_algo_init(struct aria_data *cd, void *buffer_desc, size_t att, size_t chan_cnt, size_t smpl_group_cnt) { - size_t idx; - cd->chan_cnt = chan_cnt; cd->smpl_group_cnt = smpl_group_cnt; /* ensures buffer size is aligned to 8 bytes */ @@ -62,8 +69,7 @@ static int aria_algo_init(struct aria_data *cd, void *buffer_desc, cd->data_end = cd->data_addr + cd->buff_size; cd->buff_pos = 0; - for (idx = 0; idx < ARIA_MAX_GAIN_STATES; ++idx) - cd->gains[idx] = (1ULL << (32 - cd->att - 1)) - 1; + aria_set_gains(cd); memset((void *)cd->data_addr, 0, sizeof(int32_t) * cd->buff_size); cd->gain_state = 0; @@ -72,8 +78,8 @@ static int aria_algo_init(struct aria_data *cd, void *buffer_desc, } static inline void aria_process_data(struct processing_module *mod, - struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + struct audio_stream *source, + struct audio_stream *sink, size_t frames) { struct aria_data *cd = module_get_private_data(mod); @@ -153,24 +159,19 @@ static int aria_free(struct processing_module *mod) static void aria_set_stream_params(struct comp_buffer *buffer, struct processing_module *mod) { - struct comp_buffer __sparse_cache *buffer_c; const struct ipc4_audio_format *audio_fmt = &mod->priv.cfg.base_cfg.audio_fmt; - buffer_c = buffer_acquire(buffer); - - ipc4_update_buffer_format(buffer_c, audio_fmt); + ipc4_update_buffer_format(buffer, audio_fmt); #ifdef ARIA_GENERIC - audio_stream_init_alignment_constants(1, 1, &buffer_c->stream); + audio_stream_init_alignment_constants(1, 1, &buffer->stream); #else - audio_stream_init_alignment_constants(8, 1, &buffer_c->stream); + audio_stream_init_alignment_constants(8, 1, &buffer->stream); #endif - - buffer_release(buffer_c); } static int aria_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { int ret; struct comp_buffer *source, *sink; @@ -254,12 +255,35 @@ static int aria_process(struct processing_module *mod, return 0; } -static struct module_interface aria_interface = { - .init = aria_init, +static int aria_set_config(struct processing_module *mod, uint32_t param_id, + enum module_cfg_fragment_position pos, uint32_t data_offset_size, + const uint8_t *fragment, size_t fragment_size, uint8_t *response, + size_t response_size) +{ + struct aria_data *cd = module_get_private_data(mod); + + if (param_id == ARIA_SET_ATTENUATION) { + if (fragment_size != sizeof(uint32_t)) { + comp_err(mod->dev, "Illegal fragment_size = %d", fragment_size); + return -EINVAL; + } + memcpy_s(&cd->att, sizeof(uint32_t), fragment, sizeof(uint32_t)); + aria_set_gains(cd); + } else { + comp_err(mod->dev, "Illegal param_id = %d", param_id); + return -EINVAL; + } + + return 0; +} + +static const struct module_interface aria_interface = { + .init = aria_init, .prepare = aria_prepare, .process_audio_stream = aria_process, .reset = aria_reset, - .free = aria_free + .free = aria_free, + .set_configuration = aria_set_config, }; DECLARE_MODULE_ADAPTER(aria_interface, aria_comp_uuid, aria_comp_tr); diff --git a/src/include/sof/audio/aria/aria.h b/src/audio/aria/aria.h similarity index 89% rename from src/include/sof/audio/aria/aria.h rename to src/audio/aria/aria.h index 64e34e09c86b..98cba48f93c0 100644 --- a/src/include/sof/audio/aria/aria.h +++ b/src/audio/aria/aria.h @@ -6,7 +6,7 @@ */ /** - * \file audio/aria/aria.h + * \file aria.h * \brief Aria component header file * \authors Adrian Bonislawski */ @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -48,14 +49,14 @@ * \brief aria get data function interface */ typedef void (*aria_get_data_func)(struct processing_module *mod, - struct audio_stream __sparse_cache *sink, int frames); + struct audio_stream *sink, int frames); struct aria_data; /** * \brief Aria gain processing function */ void aria_algo_calc_gain(struct aria_data *cd, size_t gain_idx, - struct audio_stream __sparse_cache *source, int frames); + struct audio_stream *source, int frames); aria_get_data_func aria_algo_get_data_func(struct processing_module *mod); @@ -92,4 +93,9 @@ struct aria_data { extern const uint8_t INDEX_TAB[]; +struct ipc4_aria_module_cfg { + struct ipc4_base_module_cfg base_cfg; + uint32_t attenuation; +} __packed __aligned(8); + #endif /* __SOF_AUDIO_ARIA_H__ */ diff --git a/src/audio/aria/aria_generic.c b/src/audio/aria/aria_generic.c index cc0f90b2de2e..0fca86f44548 100644 --- a/src/audio/aria/aria_generic.c +++ b/src/audio/aria/aria_generic.c @@ -2,8 +2,7 @@ // // Copyright(c) 2023 Intel Corporation. All rights reserved. -#include -#include +#include "aria.h" #ifdef ARIA_GENERIC @@ -20,7 +19,7 @@ const uint8_t INDEX_TAB[] = { }; inline void aria_algo_calc_gain(struct aria_data *cd, size_t gain_idx, - struct audio_stream __sparse_cache *source, int frames) + struct audio_stream *source, int frames) { int32_t max_data = 0; int32_t sample_abs; @@ -50,7 +49,7 @@ inline void aria_algo_calc_gain(struct aria_data *cd, size_t gain_idx, } void aria_algo_get_data(struct processing_module *mod, - struct audio_stream __sparse_cache *sink, int frames) + struct audio_stream *sink, int frames) { struct aria_data *cd = module_get_private_data(mod); int32_t step, in_sample; diff --git a/src/audio/aria/aria_hifi3.c b/src/audio/aria/aria_hifi3.c index 17e356b968bc..e296db7ff863 100644 --- a/src/audio/aria/aria_hifi3.c +++ b/src/audio/aria/aria_hifi3.c @@ -2,7 +2,7 @@ // // Copyright(c) 2021 Intel Corporation. All rights reserved. -#include +#include "aria.h" #ifdef ARIA_HIFI3 #include @@ -21,7 +21,7 @@ const uint8_t INDEX_TAB[] = { }; inline void aria_algo_calc_gain(struct aria_data *cd, size_t gain_idx, - struct audio_stream __sparse_cache *source, int frames) + struct audio_stream *source, int frames) { /* detecting maximum value in data chunk */ ae_int32x2 in_sample; @@ -61,7 +61,7 @@ inline void aria_algo_calc_gain(struct aria_data *cd, size_t gain_idx, } void aria_algo_get_data_odd_channel(struct processing_module *mod, - struct audio_stream __sparse_cache *sink, + struct audio_stream *sink, int frames) { struct aria_data *cd = module_get_private_data(mod); @@ -118,7 +118,7 @@ void aria_algo_get_data_odd_channel(struct processing_module *mod, } void aria_algo_get_data_even_channel(struct processing_module *mod, - struct audio_stream __sparse_cache *sink, + struct audio_stream *sink, int frames) { struct aria_data *cd = module_get_private_data(mod); diff --git a/src/audio/asrc/asrc.c b/src/audio/asrc/asrc.c index 6f25e15129c5..fae2cc1f08b9 100644 --- a/src/audio/asrc/asrc.c +++ b/src/audio/asrc/asrc.c @@ -48,8 +48,8 @@ #define COEF_C2 Q_CONVERT_FLOAT(0.99, 30) typedef void (*asrc_proc_func)(struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, int *consumed, int *produced); @@ -122,8 +122,8 @@ static inline void src_inc_wrap_s16(int16_t **ptr, int16_t *end, size_t size) /* A fast copy function for same in and out rate */ static void src_copy_s32(struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, int *n_read, int *n_written) { struct comp_data *cd = comp_get_drvdata(dev); @@ -194,8 +194,8 @@ static void src_copy_s32(struct comp_dev *dev, } static void src_copy_s16(struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, int *n_read, int *n_written) { struct comp_data *cd = comp_get_drvdata(dev); @@ -534,7 +534,6 @@ static int asrc_params(struct comp_dev *dev, { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; int err; comp_info(dev, "asrc_params()"); @@ -554,25 +553,19 @@ static int asrc_params(struct comp_dev *dev, sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - #if CONFIG_IPC_MAJOR_4 /* update the source/sink buffer formats. Sink rate will be modified below */ - ipc4_update_buffer_format(source_c, &cd->ipc_config.base.audio_fmt); - ipc4_update_buffer_format(sink_c, &cd->ipc_config.base.audio_fmt); + ipc4_update_buffer_format(sourceb, &cd->ipc_config.base.audio_fmt); + ipc4_update_buffer_format(sinkb, &cd->ipc_config.base.audio_fmt); #endif /* Don't change sink rate if value from IPC is 0 (auto detect) */ if (asrc_get_sink_rate(&cd->ipc_config)) - audio_stream_set_rate(&sink_c->stream, asrc_get_sink_rate(&cd->ipc_config)); + audio_stream_set_rate(&sinkb->stream, asrc_get_sink_rate(&cd->ipc_config)); /* set source/sink_frames/rate */ - cd->source_rate = audio_stream_get_rate(&source_c->stream); - cd->sink_rate = audio_stream_get_rate(&sink_c->stream); - - buffer_release(sink_c); - buffer_release(source_c); + cd->source_rate = audio_stream_get_rate(&sourceb->stream); + cd->sink_rate = audio_stream_get_rate(&sinkb->stream); if (!cd->sink_rate) { comp_err(dev, "asrc_params(), zero sink rate"); @@ -604,7 +597,6 @@ static int asrc_params(struct comp_dev *dev, static int asrc_dai_find(struct comp_dev *dev, struct comp_data *cd) { struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; int pid; /* Get current pipeline ID and walk to find the DAI */ @@ -615,9 +607,7 @@ static int asrc_dai_find(struct comp_dev *dev, struct comp_data *cd) do { sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sinkb); - dev = sink_c->sink; - buffer_release(sink_c); + dev = sinkb->sink; if (!dev) { comp_cl_err(&comp_asrc, "At end, no DAI found."); @@ -635,9 +625,7 @@ static int asrc_dai_find(struct comp_dev *dev, struct comp_data *cd) do { sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - source_c = buffer_acquire(sourceb); - dev = source_c->source; - buffer_release(source_c); + dev = sourceb->source; if (!dev) { comp_cl_err(&comp_asrc, "At beginning, no DAI found."); @@ -681,8 +669,11 @@ static int asrc_dai_stop_timestamp(struct comp_data *cd) return -EINVAL; } -static int asrc_dai_get_timestamp(struct comp_data *cd, - struct timestamp_data *tsd) +#if CONFIG_ZEPHYR_NATIVE_DRIVERS + static int asrc_dai_get_timestamp(struct comp_data *cd, struct dai_ts_data *tsd) +#else + static int asrc_dai_get_timestamp(struct comp_data *cd, struct timestamp_data *tsd) +#endif { if (!cd->dai_dev) return -EINVAL; @@ -722,7 +713,6 @@ static int asrc_prepare(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; uint32_t source_period_bytes; uint32_t sink_period_bytes; int sample_bytes; @@ -748,23 +738,20 @@ static int asrc_prepare(struct comp_dev *dev) sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - /* get source data format and period bytes */ - cd->source_format = audio_stream_get_frm_fmt(&source_c->stream); - source_period_bytes = audio_stream_period_bytes(&source_c->stream, + cd->source_format = audio_stream_get_frm_fmt(&sourceb->stream); + source_period_bytes = audio_stream_period_bytes(&sourceb->stream, cd->source_frames); /* get sink data format and period bytes */ - cd->sink_format = audio_stream_get_frm_fmt(&sink_c->stream); - sink_period_bytes = audio_stream_period_bytes(&sink_c->stream, + cd->sink_format = audio_stream_get_frm_fmt(&sinkb->stream); + sink_period_bytes = audio_stream_period_bytes(&sinkb->stream, cd->sink_frames); - if (audio_stream_get_size(&sink_c->stream) < + if (audio_stream_get_size(&sinkb->stream) < dev->ipc_config.periods_sink * sink_period_bytes) { comp_err(dev, "asrc_prepare(): sink buffer size %d is insufficient < %d * %d", - audio_stream_get_size(&sink_c->stream), dev->ipc_config.periods_sink, + audio_stream_get_size(&sinkb->stream), dev->ipc_config.periods_sink, sink_period_bytes); ret = -ENOMEM; goto err; @@ -783,7 +770,7 @@ static int asrc_prepare(struct comp_dev *dev) } /* ASRC supports S16_LE, S24_4LE and S32_LE formats */ - switch (audio_stream_get_frm_fmt(&source_c->stream)) { + switch (audio_stream_get_frm_fmt(&sourceb->stream)) { case SOF_IPC_FRAME_S16_LE: cd->asrc_func = src_copy_s16; break; @@ -801,7 +788,7 @@ static int asrc_prepare(struct comp_dev *dev) } /* Allocate input and output data buffer for ASRC processing */ - frame_bytes = audio_stream_frame_bytes(&source_c->stream); + frame_bytes = audio_stream_frame_bytes(&sourceb->stream); cd->buf_size = (cd->source_frames_max + cd->sink_frames_max) * frame_bytes; @@ -815,8 +802,8 @@ static int asrc_prepare(struct comp_dev *dev) goto err; } - sample_bytes = frame_bytes / audio_stream_get_channels(&source_c->stream); - for (i = 0; i < audio_stream_get_channels(&source_c->stream); i++) { + sample_bytes = frame_bytes / audio_stream_get_channels(&sourceb->stream); + for (i = 0; i < audio_stream_get_channels(&sourceb->stream); i++) { cd->ibuf[i] = cd->buf + i * sample_bytes; cd->obuf[i] = cd->ibuf[i] + cd->source_frames_max * frame_bytes; } @@ -824,7 +811,7 @@ static int asrc_prepare(struct comp_dev *dev) /* Get required size and allocate memory for ASRC */ sample_bits = sample_bytes * 8; ret = asrc_get_required_size(dev, &cd->asrc_size, - audio_stream_get_channels(&source_c->stream), + audio_stream_get_channels(&sourceb->stream), sample_bits); if (ret) { comp_err(dev, "asrc_prepare(), get_required_size_bytes failed"); @@ -850,7 +837,7 @@ static int asrc_prepare(struct comp_dev *dev) fs_sec = cd->source_rate; } - ret = asrc_initialise(dev, cd->asrc_obj, audio_stream_get_channels(&source_c->stream), + ret = asrc_initialise(dev, cd->asrc_obj, audio_stream_get_channels(&sourceb->stream), fs_prim, fs_sec, ASRC_IOF_INTERLEAVED, ASRC_IOF_INTERLEAVED, ASRC_BM_LINEAR, cd->frames, sample_bits, @@ -886,9 +873,6 @@ static int asrc_prepare(struct comp_dev *dev) goto err_free_asrc; } - buffer_release(sink_c); - buffer_release(source_c); - return 0; err_free_asrc: @@ -901,15 +885,17 @@ static int asrc_prepare(struct comp_dev *dev) cd->buf = NULL; err: - buffer_release(sink_c); - buffer_release(source_c); comp_set_state(dev, COMP_TRIGGER_RESET); return ret; } static int asrc_control_loop(struct comp_dev *dev, struct comp_data *cd) { +#if CONFIG_ZEPHYR_NATIVE_DRIVERS + struct dai_ts_data tsd; +#else struct timestamp_data tsd; +#endif int64_t tmp; int32_t delta_sample; int32_t delta_ts; @@ -978,8 +964,8 @@ static int asrc_control_loop(struct comp_dev *dev, struct comp_data *cd) return 0; } -static void asrc_process(struct comp_dev *dev, struct comp_buffer __sparse_cache *source, - struct comp_buffer __sparse_cache *sink) +static void asrc_process(struct comp_dev *dev, struct comp_buffer *source, + struct comp_buffer *sink) { struct comp_data *cd = comp_get_drvdata(dev); int consumed = 0; @@ -1005,7 +991,6 @@ static int asrc_copy(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *source, *sink; - struct comp_buffer __sparse_cache *source_c, *sink_c; int frames_src; int frames_snk; int ret; @@ -1022,11 +1007,8 @@ static int asrc_copy(struct comp_dev *dev) sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(source); - sink_c = buffer_acquire(sink); - - frames_src = audio_stream_get_avail_frames(&source_c->stream); - frames_snk = audio_stream_get_free_frames(&sink_c->stream); + frames_src = audio_stream_get_avail_frames(&source->stream); + frames_snk = audio_stream_get_free_frames(&sink->stream); if (cd->mode == ASRC_OM_PULL) { /* Let ASRC access max number of source frames in pull mode. @@ -1052,10 +1034,7 @@ static int asrc_copy(struct comp_dev *dev) } if (cd->source_frames && cd->sink_frames) - asrc_process(dev, source_c, sink_c); - - buffer_release(sink_c); - buffer_release(source_c); + asrc_process(dev, source, sink); return 0; } diff --git a/src/audio/audio_stream.c b/src/audio/audio_stream.c index 96f02cff8b90..2a1a7a05e64a 100644 --- a/src/audio/audio_stream.c +++ b/src/audio/audio_stream.c @@ -6,21 +6,17 @@ #include #include -static size_t audio_stream_get_free_size(struct sof_sink __sparse_cache *sink) +static size_t audio_stream_get_free_size(struct sof_sink *sink) { - struct audio_stream __sparse_cache *audio_stream = - attr_container_of(sink, struct audio_stream __sparse_cache, - sink_api, __sparse_cache); + struct audio_stream *audio_stream = container_of(sink, struct audio_stream, sink_api); return audio_stream_get_free_bytes(audio_stream); } -static int audio_stream_get_buffer(struct sof_sink __sparse_cache *sink, size_t req_size, +static int audio_stream_get_buffer(struct sof_sink *sink, size_t req_size, void **data_ptr, void **buffer_start, size_t *buffer_size) { - struct audio_stream __sparse_cache *audio_stream = - attr_container_of(sink, struct audio_stream __sparse_cache, - sink_api, __sparse_cache); + struct audio_stream *audio_stream = container_of(sink, struct audio_stream, sink_api); if (req_size > audio_stream_get_free_size(sink)) return -ENODATA; @@ -32,47 +28,37 @@ static int audio_stream_get_buffer(struct sof_sink __sparse_cache *sink, size_t return 0; } -static int audio_stream_commit_buffer(struct sof_sink __sparse_cache *sink, size_t commit_size) +static int audio_stream_commit_buffer(struct sof_sink *sink, size_t commit_size) { - struct audio_stream __sparse_cache *audio_stream = - attr_container_of(sink, struct audio_stream __sparse_cache, - sink_api, __sparse_cache); - struct comp_buffer __sparse_cache *buffer_c = - attr_container_of(audio_stream, struct comp_buffer __sparse_cache, - stream, __sparse_cache); + struct audio_stream *audio_stream = container_of(sink, struct audio_stream, sink_api); + struct comp_buffer *buffer = container_of(audio_stream, struct comp_buffer, stream); if (commit_size) { - buffer_stream_writeback(buffer_c, commit_size); + buffer_stream_writeback(buffer, commit_size); audio_stream_produce(audio_stream, commit_size); } return 0; } -static size_t audio_stream_get_data_available(struct sof_source __sparse_cache *source) +static size_t audio_stream_get_data_available(struct sof_source *source) { - struct audio_stream __sparse_cache *audio_stream = - attr_container_of(source, struct audio_stream __sparse_cache, - source_api, __sparse_cache); + struct audio_stream *audio_stream = container_of(source, struct audio_stream, source_api); return audio_stream_get_avail_bytes(audio_stream); } -static int audio_stream_get_data(struct sof_source __sparse_cache *source, size_t req_size, - void **data_ptr, void **buffer_start, size_t *buffer_size) +static int audio_stream_get_data(struct sof_source *source, size_t req_size, + void const **data_ptr, void const **buffer_start, + size_t *buffer_size) { - struct audio_stream __sparse_cache *audio_stream = - attr_container_of(source, struct audio_stream __sparse_cache, - source_api, __sparse_cache); - - struct comp_buffer __sparse_cache *buffer_c = - attr_container_of(audio_stream, struct comp_buffer __sparse_cache, - stream, __sparse_cache); + struct audio_stream *audio_stream = container_of(source, struct audio_stream, source_api); + struct comp_buffer *buffer = container_of(audio_stream, struct comp_buffer, stream); if (req_size > audio_stream_get_data_available(source)) return -ENODATA; - buffer_stream_invalidate(buffer_c, req_size); + buffer_stream_invalidate(buffer, req_size); /* get circular buffer parameters */ *data_ptr = audio_stream->r_ptr; @@ -81,11 +67,9 @@ static int audio_stream_get_data(struct sof_source __sparse_cache *source, size_ return 0; } -static int audio_stream_release_data(struct sof_source __sparse_cache *source, size_t free_size) +static int audio_stream_release_data(struct sof_source *source, size_t free_size) { - struct audio_stream __sparse_cache *audio_stream = - attr_container_of(source, struct audio_stream __sparse_cache, - source_api, __sparse_cache); + struct audio_stream *audio_stream = container_of(source, struct audio_stream, source_api); if (free_size) audio_stream_consume(audio_stream, free_size); @@ -93,54 +77,42 @@ static int audio_stream_release_data(struct sof_source __sparse_cache *source, s return 0; } -static int audio_stream_set_ipc_params_source(struct sof_source __sparse_cache *source, +static int audio_stream_set_ipc_params_source(struct sof_source *source, struct sof_ipc_stream_params *params, bool force_update) { - struct audio_stream __sparse_cache *audio_stream = - attr_container_of(source, struct audio_stream __sparse_cache, - source_api, __sparse_cache); - struct comp_buffer __sparse_cache *buffer = - attr_container_of(audio_stream, struct comp_buffer __sparse_cache, - stream, __sparse_cache); + struct audio_stream *audio_stream = container_of(source, struct audio_stream, source_api); + struct comp_buffer *buffer = container_of(audio_stream, struct comp_buffer, stream); return buffer_set_params(buffer, params, force_update); } -static int audio_stream_set_ipc_params_sink(struct sof_sink __sparse_cache *sink, +static int audio_stream_set_ipc_params_sink(struct sof_sink *sink, struct sof_ipc_stream_params *params, bool force_update) { - struct audio_stream __sparse_cache *audio_stream = - attr_container_of(sink, struct audio_stream __sparse_cache, - sink_api, __sparse_cache); - struct comp_buffer __sparse_cache *buffer = - attr_container_of(audio_stream, struct comp_buffer __sparse_cache, - stream, __sparse_cache); + struct audio_stream *audio_stream = container_of(sink, struct audio_stream, sink_api); + struct comp_buffer *buffer = container_of(audio_stream, struct comp_buffer, stream); return buffer_set_params(buffer, params, force_update); } -static int audio_stream_source_set_alignment_constants(struct sof_source __sparse_cache *source, +static int audio_stream_source_set_alignment_constants(struct sof_source *source, const uint32_t byte_align, const uint32_t frame_align_req) { - struct audio_stream __sparse_cache *audio_stream = - attr_container_of(source, struct audio_stream __sparse_cache, - source_api, __sparse_cache); + struct audio_stream *audio_stream = container_of(source, struct audio_stream, source_api); audio_stream_init_alignment_constants(byte_align, frame_align_req, audio_stream); return 0; } -static int audio_stream_sink_set_alignment_constants(struct sof_sink __sparse_cache *sink, +static int audio_stream_sink_set_alignment_constants(struct sof_sink *sink, const uint32_t byte_align, const uint32_t frame_align_req) { - struct audio_stream __sparse_cache *audio_stream = - attr_container_of(sink, struct audio_stream __sparse_cache, - sink_api, __sparse_cache); + struct audio_stream *audio_stream = container_of(sink, struct audio_stream, sink_api); audio_stream_init_alignment_constants(byte_align, frame_align_req, audio_stream); @@ -163,24 +135,15 @@ static const struct sink_ops audio_stream_sink_ops = { .set_alignment_constants = audio_stream_sink_set_alignment_constants }; -void audio_stream_init(struct audio_stream __sparse_cache *audio_stream, - void *buff_addr, uint32_t size) +void audio_stream_init(struct audio_stream *audio_stream, void *buff_addr, uint32_t size) { audio_stream->size = size; audio_stream->addr = buff_addr; audio_stream->end_addr = (char *)audio_stream->addr + size; - /* set the default alignment info. - * set byte_align as 1 means no alignment limit on byte. - * set frame_align as 1 means no alignment limit on frame. - */ - audio_stream_init_alignment_constants(1, 1, audio_stream); - source_init(audio_stream_get_source(audio_stream), &audio_stream_source_ops, - (__sparse_force struct sof_audio_stream_params *) &audio_stream->runtime_stream_params); sink_init(audio_stream_get_sink(audio_stream), &audio_stream_sink_ops, - (__sparse_force struct sof_audio_stream_params *) &audio_stream->runtime_stream_params); audio_stream_reset(audio_stream); } diff --git a/src/audio/base_fw.c b/src/audio/base_fw.c index 05e99194e608..ce7b5ca7778e 100644 --- a/src/audio/base_fw.c +++ b/src/audio/base_fw.c @@ -51,7 +51,7 @@ static int basefw_config(uint32_t *data_offset, char *data) tuple = tlv_next(tuple); tlv_value_uint32_set(tuple, IPC4_SLOW_CLOCK_FREQ_HZ_FW_CFG, - clock_get_freq(CPU_LPRO_FREQ_IDX)); + clock_get_freq(CPU_LOWEST_FREQ_IDX)); tuple = tlv_next(tuple); tlv_value_uint32_set(tuple, IPC4_SLOW_CLOCK_FREQ_HZ_FW_CFG, IPC4_ALH_CAVS_1_8); diff --git a/src/audio/buffer.c b/src/audio/buffer.c index c9c86cf8dc61..02f6c9da0777 100644 --- a/src/audio/buffer.c +++ b/src/audio/buffer.c @@ -27,10 +27,10 @@ DECLARE_SOF_RT_UUID("buffer", buffer_uuid, 0x42544c92, 0x8e92, 0x4e41, 0xb6, 0x79, 0x34, 0x51, 0x9f, 0x1c, 0x1d, 0x28); DECLARE_TR_CTX(buffer_tr, SOF_UUID(buffer_uuid), LOG_LEVEL_INFO); -struct comp_buffer *buffer_alloc(uint32_t size, uint32_t caps, uint32_t flags, uint32_t align) +struct comp_buffer *buffer_alloc(uint32_t size, uint32_t caps, uint32_t flags, uint32_t align, + bool is_shared) { struct comp_buffer *buffer; - struct comp_buffer __sparse_cache *buffer_c; void *stream_addr; tr_dbg(&buffer_tr, "buffer_alloc()"); @@ -42,16 +42,19 @@ struct comp_buffer *buffer_alloc(uint32_t size, uint32_t caps, uint32_t flags, u return NULL; } - /* - * allocate new buffer, align the allocation size to a cache line for - * the coherent API - */ - buffer = coherent_init_thread(struct comp_buffer, c); + /* allocate new buffer */ + enum mem_zone zone = is_shared ? SOF_MEM_ZONE_RUNTIME_SHARED : SOF_MEM_ZONE_RUNTIME; + + buffer = rzalloc(zone, 0, SOF_MEM_CAPS_RAM, sizeof(*buffer)); + if (!buffer) { tr_err(&buffer_tr, "buffer_alloc(): could not alloc structure"); return NULL; } + CORE_CHECK_STRUCT_INIT(buffer, is_shared); + + buffer->is_shared = is_shared; stream_addr = rballoc_align(0, caps, size, align); if (!stream_addr) { rfree(buffer); @@ -61,26 +64,11 @@ struct comp_buffer *buffer_alloc(uint32_t size, uint32_t caps, uint32_t flags, u } /* From here no more uncached access to the buffer object, except its list headers */ - buffer_c = buffer_acquire(buffer); - audio_stream_set_addr(&buffer_c->stream, stream_addr); - buffer_init(buffer_c, size, caps); - - audio_stream_set_underrun(&buffer_c->stream, !!(flags & SOF_BUF_UNDERRUN_PERMITTED)); - audio_stream_set_overrun(&buffer_c->stream, !!(flags & SOF_BUF_OVERRUN_PERMITTED)); - - buffer_release(buffer_c); - - /* - * The buffer hasn't yet been marked as shared, hence buffer_release() - * hasn't written back and invalidated the cache. Therefore we have to - * do this manually now before adding to the lists. Buffer list - * structures are always accessed uncached and they're never modified at - * run-time, i.e. buffers are never relinked. So we have to make sure, - * that what we have written into buffer's cache is in RAM before - * modifying that RAM bypassing cache, and that after this cache is - * re-loaded again. - */ - dcache_writeback_invalidate_region(uncache_to_cache(buffer), sizeof(*buffer)); + audio_stream_set_addr(&buffer->stream, stream_addr); + buffer_init(buffer, size, caps); + + audio_stream_set_underrun(&buffer->stream, !!(flags & SOF_BUF_UNDERRUN_PERMITTED)); + audio_stream_set_overrun(&buffer->stream, !!(flags & SOF_BUF_OVERRUN_PERMITTED)); list_init(&buffer->source_list); list_init(&buffer->sink_list); @@ -88,9 +76,10 @@ struct comp_buffer *buffer_alloc(uint32_t size, uint32_t caps, uint32_t flags, u return buffer; } -void buffer_zero(struct comp_buffer __sparse_cache *buffer) +void buffer_zero(struct comp_buffer *buffer) { buf_dbg(buffer, "stream_zero()"); + CORE_CHECK_STRUCT(buffer); bzero(audio_stream_get_addr(&buffer->stream), audio_stream_get_size(&buffer->stream)); if (buffer->caps & SOF_MEM_CAPS_DMA) @@ -99,10 +88,12 @@ void buffer_zero(struct comp_buffer __sparse_cache *buffer) audio_stream_get_size(&buffer->stream)); } -int buffer_set_size(struct comp_buffer __sparse_cache *buffer, uint32_t size, uint32_t alignment) +int buffer_set_size(struct comp_buffer *buffer, uint32_t size, uint32_t alignment) { void *new_ptr = NULL; + CORE_CHECK_STRUCT(buffer); + /* validate request */ if (size == 0) { buf_err(buffer, "resize size = %u is invalid", size); @@ -135,12 +126,14 @@ int buffer_set_size(struct comp_buffer __sparse_cache *buffer, uint32_t size, ui return 0; } -int buffer_set_params(struct comp_buffer __sparse_cache *buffer, +int buffer_set_params(struct comp_buffer *buffer, struct sof_ipc_stream_params *params, bool force_update) { int ret; int i; + CORE_CHECK_STRUCT(buffer); + if (!params) { buf_err(buffer, "buffer_set_params(): !params"); return -EINVAL; @@ -164,10 +157,11 @@ int buffer_set_params(struct comp_buffer __sparse_cache *buffer, return 0; } -bool buffer_params_match(struct comp_buffer __sparse_cache *buffer, +bool buffer_params_match(struct comp_buffer *buffer, struct sof_ipc_stream_params *params, uint32_t flag) { assert(params); + CORE_CHECK_STRUCT(buffer); if ((flag & BUFF_PARAMS_FRAME_FMT) && audio_stream_get_frm_fmt(&buffer->stream) != params->frame_fmt) @@ -191,6 +185,8 @@ void buffer_free(struct comp_buffer *buffer) .buffer = buffer, }; + CORE_CHECK_STRUCT(buffer); + if (!buffer) return; @@ -203,22 +199,10 @@ void buffer_free(struct comp_buffer *buffer) notifier_unregister_all(NULL, buffer); rfree(buffer->stream.addr); - coherent_free_thread(buffer, c); + rfree(buffer); } -/* - * comp_update_buffer_produce() and comp_update_buffer_consume() send - * NOTIFIER_ID_BUFFER_PRODUCE and NOTIFIER_ID_BUFFER_CONSUME notifier events - * respectively. The only recipient of those notifications is probes. The - * target for those notifications is always the current core, therefore notifier - * callbacks will be called synchronously from notifier_event() calls. Therefore - * we cannot pass unlocked buffer pointers to probes, because if they try to - * acquire the buffer, that can cause a deadlock. In general locked objects - * shouldn't be passed to potentially asynchronous contexts, but here we have no - * choice but to use our knowledge of the local notifier behaviour and pass - * locked buffers to notification recipients. - */ -void comp_update_buffer_produce(struct comp_buffer __sparse_cache *buffer, uint32_t bytes) +void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes) { struct buffer_cb_transact cb_data = { .buffer = buffer, @@ -240,8 +224,7 @@ void comp_update_buffer_produce(struct comp_buffer __sparse_cache *buffer, uint3 audio_stream_produce(&buffer->stream, bytes); - /* Notifier looks for the pointer value to match it against registration */ - notifier_event(cache_to_uncache(buffer), NOTIFIER_ID_BUFFER_PRODUCE, + notifier_event(buffer, NOTIFIER_ID_BUFFER_PRODUCE, NOTIFIER_TARGET_CORE_LOCAL, &cb_data, sizeof(cb_data)); #if CONFIG_SOF_LOG_DBG_BUFFER @@ -257,7 +240,7 @@ void comp_update_buffer_produce(struct comp_buffer __sparse_cache *buffer, uint3 #endif } -void comp_update_buffer_consume(struct comp_buffer __sparse_cache *buffer, uint32_t bytes) +void comp_update_buffer_consume(struct comp_buffer *buffer, uint32_t bytes) { struct buffer_cb_transact cb_data = { .buffer = buffer, @@ -265,6 +248,8 @@ void comp_update_buffer_consume(struct comp_buffer __sparse_cache *buffer, uint3 .transaction_begin_address = audio_stream_get_rptr(&buffer->stream), }; + CORE_CHECK_STRUCT(buffer); + /* return if no bytes */ if (!bytes) { #if CONFIG_SOF_LOG_DBG_BUFFER @@ -279,7 +264,7 @@ void comp_update_buffer_consume(struct comp_buffer __sparse_cache *buffer, uint3 audio_stream_consume(&buffer->stream, bytes); - notifier_event(cache_to_uncache(buffer), NOTIFIER_ID_BUFFER_CONSUME, + notifier_event(buffer, NOTIFIER_ID_BUFFER_CONSUME, NOTIFIER_TARGET_CORE_LOCAL, &cb_data, sizeof(cb_data)); #if CONFIG_SOF_LOG_DBG_BUFFER @@ -303,30 +288,8 @@ void comp_update_buffer_consume(struct comp_buffer __sparse_cache *buffer, uint3 void buffer_attach(struct comp_buffer *buffer, struct list_item *head, int dir) { struct list_item *list = buffer_comp_list(buffer, dir); - struct list_item __sparse_cache *needs_sync; - bool further_buffers_exist; - - /* - * There can already be buffers on the target list. If we just link this - * buffer, we modify the first buffer's list header via uncached alias, - * so its cached copy can later be written back, overwriting the - * modified header. FIXME: this is still a problem with different cores. - */ - further_buffers_exist = !list_is_empty(head); - needs_sync = uncache_to_cache(head->next); - if (further_buffers_exist) - dcache_writeback_region(needs_sync, sizeof(struct list_item)); - /* The cache line can be prefetched here, invalidate it after prepending */ + CORE_CHECK_STRUCT(buffer); list_item_prepend(list, head); - if (further_buffers_exist) - dcache_invalidate_region(needs_sync, sizeof(struct list_item)); -#if CONFIG_INTEL - /* - * Until now the buffer object wasn't in cache, but uncached access to it could have - * triggered a cache prefetch. Drop that cache line to avoid using stale data in it. - */ - dcache_invalidate_region(uncache_to_cache(list), sizeof(*list)); -#endif } /* @@ -335,32 +298,7 @@ void buffer_attach(struct comp_buffer *buffer, struct list_item *head, int dir) */ void buffer_detach(struct comp_buffer *buffer, struct list_item *head, int dir) { - struct list_item __sparse_cache *needs_sync_prev, *needs_sync_next; - bool buffers_after_exist, buffers_before_exist; struct list_item *buf_list = buffer_comp_list(buffer, dir); - - /* - * There can be more buffers linked together with this one, that will - * still be staying on their respective pipelines and might get used via - * their cached aliases. If we just unlink this buffer, we modify their - * list header via uncached alias, so their cached copy can later be - * written back, overwriting the modified header. FIXME: this is still a - * problem with different cores. - */ - buffers_after_exist = head != buf_list->next; - buffers_before_exist = head != buf_list->prev; - needs_sync_prev = uncache_to_cache(buf_list->prev); - needs_sync_next = uncache_to_cache(buf_list->next); - if (buffers_after_exist) - dcache_writeback_region(needs_sync_next, sizeof(struct list_item)); - if (buffers_before_exist) - dcache_writeback_region(needs_sync_prev, sizeof(struct list_item)); - dcache_writeback_region(uncache_to_cache(buf_list), sizeof(*buf_list)); - /* buffers before or after can be prefetched here */ + CORE_CHECK_STRUCT(buffer); list_item_del(buf_list); - dcache_invalidate_region(uncache_to_cache(buf_list), sizeof(*buf_list)); - if (buffers_after_exist) - dcache_invalidate_region(needs_sync_next, sizeof(struct list_item)); - if (buffers_before_exist) - dcache_invalidate_region(needs_sync_prev, sizeof(struct list_item)); } diff --git a/src/audio/chain_dma.c b/src/audio/chain_dma.c index b8cf7ded072a..25cec633728a 100644 --- a/src/audio/chain_dma.c +++ b/src/audio/chain_dma.c @@ -238,12 +238,9 @@ static enum task_state chain_task_run(void *data) * mode task will update read position based on transferred data size to avoid * overwriting valid data and write position by half buffer size. */ - struct comp_buffer __sparse_cache *buffer_c = buffer_acquire(cd->dma_buffer); - const size_t buff_size = audio_stream_get_size(&buffer_c->stream); + const size_t buff_size = audio_stream_get_size(&cd->dma_buffer->stream); const size_t half_buff_size = buff_size / 2; - buffer_release(buffer_c); - if (!cd->first_data_received && host_avail_bytes > half_buff_size) { ret = dma_reload(cd->chan_link->dma->z_dev, cd->chan_link->index, 0, 0, @@ -510,7 +507,6 @@ static int chain_task_init(struct comp_dev *dev, uint8_t host_dma_id, uint8_t li uint32_t fifo_size) { struct chain_dma_data *cd = comp_get_drvdata(dev); - struct comp_buffer __sparse_cache *buffer_c; uint32_t addr_align; size_t buff_size; void *buff_addr; @@ -588,8 +584,8 @@ static int chain_task_init(struct comp_dev *dev, uint8_t host_dma_id, uint8_t li } fifo_size = ALIGN_UP_INTERNAL(fifo_size, addr_align); - - cd->dma_buffer = buffer_alloc(fifo_size, SOF_MEM_CAPS_DMA, 0, addr_align); + /* allocate not shared buffer */ + cd->dma_buffer = buffer_alloc(fifo_size, SOF_MEM_CAPS_DMA, 0, addr_align, false); if (!cd->dma_buffer) { comp_err(dev, "chain_task_init(): failed to alloc dma buffer"); @@ -598,11 +594,9 @@ static int chain_task_init(struct comp_dev *dev, uint8_t host_dma_id, uint8_t li } /* clear dma buffer */ - buffer_c = buffer_acquire(cd->dma_buffer); - buffer_zero(buffer_c); - buff_addr = audio_stream_get_addr(&buffer_c->stream); - buff_size = audio_stream_get_size(&buffer_c->stream); - buffer_release(buffer_c); + buffer_zero(cd->dma_buffer); + buff_addr = audio_stream_get_addr(&cd->dma_buffer->stream); + buff_size = audio_stream_get_size(&cd->dma_buffer->stream); ret = chain_init(dev, buff_addr, buff_size); if (ret < 0) { diff --git a/src/audio/component.c b/src/audio/component.c index 51e6b4250f9b..e51f8ec461b2 100644 --- a/src/audio/component.c +++ b/src/audio/component.c @@ -158,8 +158,8 @@ void sys_comp_init(struct sof *sof) k_spinlock_init(&sof->comp_drivers->lock); } -void comp_get_copy_limits(struct comp_buffer __sparse_cache *source, - struct comp_buffer __sparse_cache *sink, +void comp_get_copy_limits(struct comp_buffer *source, + struct comp_buffer *sink, struct comp_copy_limits *cl) { cl->frames = audio_stream_avail_frames(&source->stream, &sink->stream); @@ -169,8 +169,8 @@ void comp_get_copy_limits(struct comp_buffer __sparse_cache *source, cl->sink_bytes = cl->frames * cl->sink_frame_bytes; } -void comp_get_copy_limits_frame_aligned(const struct comp_buffer __sparse_cache *source, - const struct comp_buffer __sparse_cache *sink, +void comp_get_copy_limits_frame_aligned(const struct comp_buffer *source, + const struct comp_buffer *sink, struct comp_copy_limits *cl) { cl->frames = audio_stream_avail_frames_aligned(&source->stream, &sink->stream); @@ -182,8 +182,8 @@ void comp_get_copy_limits_frame_aligned(const struct comp_buffer __sparse_cache #ifdef STREAMCOPY_HIFI3 -int audio_stream_copy(const struct audio_stream __sparse_cache *source, uint32_t ioffset, - struct audio_stream __sparse_cache *sink, uint32_t ooffset, uint32_t samples) +int audio_stream_copy(const struct audio_stream *source, uint32_t ioffset, + struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int ssize = audio_stream_sample_bytes(source); /* src fmt == sink fmt */ ae_int16x4 *src = (ae_int16x4 *)((int8_t *)audio_stream_get_rptr(source) + ioffset * ssize); @@ -227,8 +227,8 @@ int audio_stream_copy(const struct audio_stream __sparse_cache *source, uint32_t #else -int audio_stream_copy(const struct audio_stream __sparse_cache *source, uint32_t ioffset, - struct audio_stream __sparse_cache *sink, uint32_t ooffset, uint32_t samples) +int audio_stream_copy(const struct audio_stream *source, uint32_t ioffset, + struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int ssize = audio_stream_sample_bytes(source); /* src fmt == sink fmt */ uint8_t *src = audio_stream_wrap(source, (uint8_t *)audio_stream_get_rptr(source) + @@ -279,7 +279,7 @@ void cir_buf_copy(void *src, void *src_addr, void *src_end, void *dst, } void audio_stream_copy_from_linear(const void *linear_source, int ioffset, - struct audio_stream __sparse_cache *sink, int ooffset, + struct audio_stream *sink, int ooffset, unsigned int samples) { int ssize = audio_stream_sample_bytes(sink); /* src fmt == sink fmt */ @@ -300,7 +300,7 @@ void audio_stream_copy_from_linear(const void *linear_source, int ioffset, } } -void audio_stream_copy_to_linear(const struct audio_stream __sparse_cache *source, int ioffset, +void audio_stream_copy_to_linear(const struct audio_stream *source, int ioffset, void *linear_sink, int ooffset, unsigned int samples) { int ssize = audio_stream_sample_bytes(source); /* src fmt == sink fmt */ @@ -328,9 +328,25 @@ int comp_copy(struct comp_dev *dev) assert(dev->drv->ops.copy); - /* copy only if we are the owner of the LL component */ - if (dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL && - cpu_is_me(dev->ipc_config.core)) { + /* copy only if we are the owner of component OR this is DP component + * + * DP components (modules) require two stage processing: + * + * LL_mod -> [comp_buffer -> dp_queue] -> dp_mod -> [dp_queue -> comp_buffer] -> LL_mod + * + * - in first step (it means - now) the pipeline must copy source data from comp_buffer + * to dp_queue and result data from dp_queue to comp_buffer + * + * - second step will be performed by a thread specific to the DP module - DP module + * will take data from input dpQueue (using source API) , process it + * and put in output DP queue (using sink API) + * + * this allows the current pipeline structure to see a DP module as a "normal" LL + * + * to be removed when pipeline 2.0 is ready + */ + if (cpu_is_me(dev->ipc_config.core) || + dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) { #if CONFIG_PERFORMANCE_COUNTERS perf_cnt_init(&dev->pcd); #endif diff --git a/src/audio/copier/copier.c b/src/audio/copier/copier.c index ae03226be8c1..0bb2306d2a6e 100644 --- a/src/audio/copier/copier.c +++ b/src/audio/copier/copier.c @@ -178,8 +178,8 @@ static int copier_free(struct processing_module *mod) static int copier_params(struct processing_module *mod); static int copier_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct copier_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; @@ -266,7 +266,6 @@ static int copier_comp_trigger(struct comp_dev *dev, int cmd) struct sof_ipc_stream_posn posn; struct comp_dev *dai_copier; struct comp_buffer *buffer; - struct comp_buffer __sparse_cache *buffer_c; uint32_t latency; int ret; @@ -358,10 +357,8 @@ static int copier_comp_trigger(struct comp_dev *dev, int cmd) } buffer = list_first_item(&dai_copier->bsource_list, struct comp_buffer, sink_list); - buffer_c = buffer_acquire(buffer); pipe_reg.stream_start_offset = posn.dai_posn + - latency * audio_stream_get_size(&buffer_c->stream); - buffer_release(buffer_c); + latency * audio_stream_get_size(&buffer->stream); pipe_reg.stream_end_offset = 0; mailbox_sw_regs_write(cd->pipeline_reg_offset, &pipe_reg, sizeof(pipe_reg)); } else if (cmd == COMP_TRIGGER_PAUSE) { @@ -384,9 +381,7 @@ static int copier_comp_trigger(struct comp_dev *dev, int cmd) } buffer = list_first_item(&dai_copier->bsource_list, struct comp_buffer, sink_list); - buffer_c = buffer_acquire(buffer); - pipe_reg.stream_start_offset += latency * audio_stream_get_size(&buffer_c->stream); - buffer_release(buffer_c); + pipe_reg.stream_start_offset += latency * audio_stream_get_size(&buffer->stream); mailbox_sw_regs_write(cd->pipeline_reg_offset, &pipe_reg.stream_start_offset, sizeof(pipe_reg.stream_start_offset)); } @@ -396,8 +391,8 @@ static int copier_comp_trigger(struct comp_dev *dev, int cmd) static int do_conversion_copy(struct comp_dev *dev, struct copier_data *cd, - struct comp_buffer __sparse_cache *src, - struct comp_buffer __sparse_cache *sink, + struct comp_buffer *src, + struct comp_buffer *sink, struct comp_copy_limits *processed_data) { int i; @@ -423,10 +418,9 @@ static int do_conversion_copy(struct comp_dev *dev, } static int copier_copy_to_sinks(struct copier_data *cd, struct comp_dev *dev, - struct comp_buffer __sparse_cache *src_c, + struct comp_buffer *src_c, struct comp_copy_limits *processed_data) { - struct comp_buffer __sparse_cache *sink_c; struct list_item *sink_list; struct comp_buffer *sink; int ret = 0; @@ -436,14 +430,12 @@ static int copier_copy_to_sinks(struct copier_data *cd, struct comp_dev *dev, struct comp_dev *sink_dev; sink = container_of(sink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); - sink_dev = sink_c->sink; + sink_dev = sink->sink; processed_data->sink_bytes = 0; if (sink_dev->state == COMP_STATE_ACTIVE) { - ret = do_conversion_copy(dev, cd, src_c, sink_c, processed_data); + ret = do_conversion_copy(dev, cd, src_c, sink, processed_data); cd->output_total_data_processed += processed_data->sink_bytes; } - buffer_release(sink_c); if (ret < 0) { comp_err(dev, "failed to copy buffer for comp %x", dev->ipc_config.id); @@ -466,26 +458,23 @@ static int copier_module_copy(struct processing_module *mod, struct output_stream_buffer *output_buffers, int num_output_buffers) { struct copier_data *cd = module_get_private_data(mod); - struct comp_buffer __sparse_cache *src_c; + struct comp_buffer *src_c; struct comp_copy_limits processed_data; int i; if (!num_input_buffers || !num_output_buffers) return 0; - src_c = attr_container_of(input_buffers[0].data, struct comp_buffer __sparse_cache, - stream, __sparse_cache); + src_c = container_of(input_buffers[0].data, struct comp_buffer, stream); processed_data.source_bytes = 0; /* convert format and copy to each active sink */ for (i = 0; i < num_output_buffers; i++) { - struct comp_buffer __sparse_cache *sink_c; + struct comp_buffer *sink_c; struct comp_dev *sink_dev; - sink_c = attr_container_of(output_buffers[i].data, - struct comp_buffer __sparse_cache, - stream, __sparse_cache); + sink_c = container_of(output_buffers[i].data, struct comp_buffer, stream); sink_dev = sink_c->sink; processed_data.sink_bytes = 0; if (sink_dev->state == COMP_STATE_ACTIVE) { @@ -518,7 +507,6 @@ static int copier_module_copy(struct processing_module *mod, static int copier_multi_endpoint_dai_copy(struct copier_data *cd, struct comp_dev *dev) { - struct comp_buffer __sparse_cache *src_c, *sink_c; struct comp_copy_limits processed_data; struct comp_buffer *src; int ret; @@ -532,9 +520,7 @@ static int copier_multi_endpoint_dai_copy(struct copier_data *cd, struct comp_de if (ret < 0) return ret; - src_c = buffer_acquire(cd->multi_endpoint_buffer); - ret = copier_copy_to_sinks(cd, dev, src_c, &processed_data); - buffer_release(src_c); + ret = copier_copy_to_sinks(cd, dev, cd->multi_endpoint_buffer, &processed_data); return ret; } @@ -546,24 +532,18 @@ static int copier_multi_endpoint_dai_copy(struct copier_data *cd, struct comp_de } src = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - src_c = buffer_acquire(src); /* gateway(s) on output */ - sink_c = buffer_acquire(cd->multi_endpoint_buffer); - ret = do_conversion_copy(dev, cd, src_c, sink_c, &processed_data); - buffer_release(sink_c); - + ret = do_conversion_copy(dev, cd, src, cd->multi_endpoint_buffer, &processed_data); if (ret < 0) - goto err; + return ret; ret = dai_zephyr_multi_endpoint_copy(cd->dd, dev, cd->multi_endpoint_buffer, cd->endpoint_num); if (!ret) { - comp_update_buffer_consume(src_c, processed_data.source_bytes); + comp_update_buffer_consume(src, processed_data.source_bytes); cd->input_total_data_processed += processed_data.source_bytes; } -err: - buffer_release(src_c); return ret; } @@ -649,7 +629,6 @@ static int copier_set_sink_fmt(struct comp_dev *dev, const void *data, const struct ipc4_copier_config_set_sink_format *sink_fmt = data; struct processing_module *mod = comp_get_drvdata(dev); struct copier_data *cd = module_get_private_data(mod); - struct comp_buffer __sparse_cache *sink_c; struct list_item *sink_list; struct comp_buffer *sink; @@ -686,16 +665,12 @@ static int copier_set_sink_fmt(struct comp_dev *dev, const void *data, int sink_id; sink = container_of(sink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); - sink_id = IPC4_SINK_QUEUE_ID(sink_c->id); + sink_id = IPC4_SINK_QUEUE_ID(sink->id); if (sink_id == sink_fmt->sink_id) { - ipc4_update_buffer_format(sink_c, &sink_fmt->sink_fmt); - buffer_release(sink_c); + ipc4_update_buffer_format(sink, &sink_fmt->sink_fmt); break; } - - buffer_release(sink_c); } return 0; @@ -943,7 +918,11 @@ static int copier_dai_ts_start_op(struct comp_dev *dev) return dai_common_ts_start(dd, dev); } +#if CONFIG_ZEPHYR_NATIVE_DRIVERS +static int copier_dai_ts_get_op(struct comp_dev *dev, struct dai_ts_data *tsd) +#else static int copier_dai_ts_get_op(struct comp_dev *dev, struct timestamp_data *tsd) +#endif { struct processing_module *mod = comp_get_drvdata(dev); struct copier_data *cd = module_get_private_data(mod); @@ -1003,8 +982,8 @@ static struct module_endpoint_ops copier_endpoint_ops = { .trigger = copier_comp_trigger }; -static struct module_interface copier_interface = { - .init = copier_init, +static const struct module_interface copier_interface = { + .init = copier_init, .prepare = copier_prepare, .process_audio_stream = copier_process, .reset = copier_reset, diff --git a/src/audio/copier/copier_dai.c b/src/audio/copier/copier_dai.c index 31b832b81d01..8704d3aacb59 100644 --- a/src/audio/copier/copier_dai.c +++ b/src/audio/copier/copier_dai.c @@ -310,9 +310,9 @@ int copier_dai_prepare(struct comp_dev *dev, struct copier_data *cd) return 0; } -static int copy_single_channel_c16(const struct audio_stream __sparse_cache *src, +static int copy_single_channel_c16(const struct audio_stream *src, unsigned int src_channel, - struct audio_stream __sparse_cache *dst, + struct audio_stream *dst, unsigned int dst_channel, unsigned int frame_count) { int16_t *r_ptr = (int16_t *)audio_stream_get_rptr(src) + src_channel; @@ -351,9 +351,9 @@ static int copy_single_channel_c16(const struct audio_stream __sparse_cache *src return 0; } -static int copy_single_channel_c32(const struct audio_stream __sparse_cache *src, +static int copy_single_channel_c32(const struct audio_stream *src, unsigned int src_channel, - struct audio_stream __sparse_cache *dst, + struct audio_stream *dst, unsigned int dst_channel, unsigned int frame_count) { int32_t *r_ptr = (int32_t *)audio_stream_get_rptr(src) + src_channel; @@ -395,7 +395,6 @@ static int copy_single_channel_c32(const struct audio_stream __sparse_cache *src int copier_dai_params(struct copier_data *cd, struct comp_dev *dev, struct sof_ipc_stream_params *params, int dai_index) { - struct comp_buffer __sparse_cache *buf_c; struct sof_ipc_stream_params demuxed_params = *params; const struct ipc4_audio_format *in_fmt = &cd->config.base.audio_fmt; const struct ipc4_audio_format *out_fmt = &cd->config.out_fmt; @@ -438,15 +437,11 @@ int copier_dai_params(struct copier_data *cd, struct comp_dev *dev, if (ret < 0) return ret; - buf_c = buffer_acquire(cd->dd[dai_index]->dma_buffer); for (j = 0; j < SOF_IPC_MAX_CHANNELS; j++) - buf_c->chmap[j] = (cd->chan_map[dai_index] >> j * 4) & 0xf; - buffer_release(buf_c); + cd->dd[dai_index]->dma_buffer->chmap[j] = (cd->chan_map[dai_index] >> j * 4) & 0xf; /* set channel copy func */ - buf_c = buffer_acquire(cd->multi_endpoint_buffer); - container_size = audio_stream_sample_bytes(&buf_c->stream); - buffer_release(buf_c); + container_size = audio_stream_sample_bytes(&cd->multi_endpoint_buffer->stream); switch (container_size) { case 2: diff --git a/src/audio/copier/copier_generic.c b/src/audio/copier/copier_generic.c index c610d05a049d..e8ac1e111510 100644 --- a/src/audio/copier/copier_generic.c +++ b/src/audio/copier/copier_generic.c @@ -22,7 +22,7 @@ LOG_MODULE_DECLARE(copier, CONFIG_SOF_LOG_LEVEL); #include int apply_attenuation(struct comp_dev *dev, struct copier_data *cd, - struct comp_buffer __sparse_cache *sink, int frame) + struct comp_buffer *sink, int frame) { int i; int n; @@ -62,7 +62,6 @@ void copier_update_params(struct copier_data *cd, struct comp_dev *dev, struct sof_ipc_stream_params *params) { struct comp_buffer *sink, *source; - struct comp_buffer __sparse_cache *sink_c, *source_c; struct list_item *sink_list; memset(params, 0, sizeof(*params)); @@ -85,13 +84,10 @@ void copier_update_params(struct copier_data *cd, struct comp_dev *dev, int j; sink = container_of(sink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); - j = IPC4_SINK_QUEUE_ID(sink_c->id); + j = IPC4_SINK_QUEUE_ID(sink->id); - ipc4_update_buffer_format(sink_c, &cd->out_fmt[j]); - - buffer_release(sink_c); + ipc4_update_buffer_format(sink, &cd->out_fmt[j]); } /* @@ -102,12 +98,9 @@ void copier_update_params(struct copier_data *cd, struct comp_dev *dev, struct ipc4_audio_format *in_fmt; source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - source_c = buffer_acquire(source); in_fmt = &cd->config.base.audio_fmt; - ipc4_update_buffer_format(source_c, in_fmt); - - buffer_release(source_c); + ipc4_update_buffer_format(source, in_fmt); } /* update params for the DMA buffer */ @@ -140,7 +133,6 @@ int create_endpoint_buffer(struct comp_dev *dev, enum sof_ipc_frame valid_fmt; struct sof_ipc_buffer ipc_buf; struct comp_buffer *buffer; - struct comp_buffer __sparse_cache *buffer_c; uint32_t buf_size; uint32_t chan_map; int i; @@ -204,24 +196,22 @@ int create_endpoint_buffer(struct comp_dev *dev, ipc_buf.size = buf_size; ipc_buf.comp.pipeline_id = config->pipeline_id; ipc_buf.comp.core = config->core; - - buffer = buffer_new(&ipc_buf); + /* allocate not shared buffer */ + buffer = buffer_new(&ipc_buf, false); if (!buffer) return -ENOMEM; - buffer_c = buffer_acquire(buffer); - audio_stream_set_channels(&buffer_c->stream, copier_cfg->base.audio_fmt.channels_count); - audio_stream_set_rate(&buffer_c->stream, copier_cfg->base.audio_fmt.sampling_frequency); - audio_stream_set_frm_fmt(&buffer_c->stream, config->frame_fmt); - audio_stream_set_valid_fmt(&buffer_c->stream, valid_fmt); - audio_stream_set_buffer_fmt(&buffer_c->stream, + audio_stream_set_channels(&buffer->stream, copier_cfg->base.audio_fmt.channels_count); + audio_stream_set_rate(&buffer->stream, copier_cfg->base.audio_fmt.sampling_frequency); + audio_stream_set_frm_fmt(&buffer->stream, config->frame_fmt); + audio_stream_set_valid_fmt(&buffer->stream, valid_fmt); + audio_stream_set_buffer_fmt(&buffer->stream, copier_cfg->base.audio_fmt.interleaving_style); for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) - buffer_c->chmap[i] = (chan_map >> i * 4) & 0xf; + buffer->chmap[i] = (chan_map >> i * 4) & 0xf; - buffer_c->hw_params_configured = true; - buffer_release(buffer_c); + buffer->hw_params_configured = true; if (create_multi_endpoint_buffer) cd->multi_endpoint_buffer = buffer; diff --git a/src/audio/copier/copier_hifi.c b/src/audio/copier/copier_hifi.c index de6a8606aa7b..a419a4aee431 100644 --- a/src/audio/copier/copier_hifi.c +++ b/src/audio/copier/copier_hifi.c @@ -21,7 +21,7 @@ LOG_MODULE_REGISTER(copier_hifi, CONFIG_SOF_LOG_LEVEL); int apply_attenuation(struct comp_dev *dev, struct copier_data *cd, - struct comp_buffer __sparse_cache *sink, int frame) + struct comp_buffer *sink, int frame) { int i; int n; diff --git a/src/audio/copier/copier_host.c b/src/audio/copier/copier_host.c index 35456ed4dec1..30eda757bf80 100644 --- a/src/audio/copier/copier_host.c +++ b/src/audio/copier/copier_host.c @@ -246,7 +246,6 @@ void copier_host_dma_cb(struct comp_dev *dev, size_t bytes) { struct processing_module *mod = comp_get_drvdata(dev); struct copier_data *cd = module_get_private_data(mod); - struct comp_buffer __sparse_cache *sink, *source; int ret, frames; comp_dbg(dev, "copier_host_dma_cb() %p", dev); @@ -263,18 +262,13 @@ void copier_host_dma_cb(struct comp_dev *dev, size_t bytes) * playback scenario. */ if (cd->attenuation && dev->direction == SOF_IPC_STREAM_PLAYBACK) { - source = buffer_acquire(cd->hd->dma_buffer); - sink = buffer_acquire(cd->hd->local_buffer); - frames = bytes / audio_stream_frame_bytes(&source->stream); + frames = bytes / audio_stream_frame_bytes(&cd->hd->dma_buffer->stream); - ret = apply_attenuation(dev, cd, sink, frames); + ret = apply_attenuation(dev, cd, cd->hd->local_buffer, frames); if (ret < 0) comp_dbg(dev, "copier_host_dma_cb() apply attenuation failed! %d", ret); - buffer_stream_writeback(sink, bytes); - - buffer_release(source); - buffer_release(sink); + buffer_stream_writeback(cd->hd->local_buffer, bytes); } } diff --git a/src/audio/copier/copier_ipcgtw.c b/src/audio/copier/copier_ipcgtw.c index 967467f098ad..ed3350042ff7 100644 --- a/src/audio/copier/copier_ipcgtw.c +++ b/src/audio/copier/copier_ipcgtw.c @@ -37,7 +37,7 @@ static struct comp_dev *find_ipcgtw_by_node_id(union ipc4_connector_node_id node } static inline void audio_stream_copy_bytes_from_linear(const void *linear_source, - struct audio_stream __sparse_cache *sink, + struct audio_stream *sink, unsigned int bytes) { const uint8_t *src = (const uint8_t *)linear_source; @@ -55,7 +55,7 @@ static inline void audio_stream_copy_bytes_from_linear(const void *linear_source } static inline -void audio_stream_copy_bytes_to_linear(const struct audio_stream __sparse_cache *source, +void audio_stream_copy_bytes_to_linear(const struct audio_stream *source, void *linear_sink, unsigned int bytes) { uint8_t *src = audio_stream_wrap(source, audio_stream_get_rptr(source)); @@ -93,7 +93,6 @@ int copier_ipcgtw_process(const struct ipc4_ipcgtw_cmd *cmd, const struct ipc4_ipc_gateway_cmd_data *in; struct comp_dev *dev; struct comp_buffer *buf; - struct comp_buffer __sparse_cache *buf_c; uint32_t data_size; struct ipc4_ipc_gateway_cmd_data_reply *out; @@ -110,15 +109,12 @@ int copier_ipcgtw_process(const struct ipc4_ipcgtw_cmd *cmd, buf = get_buffer(dev); - if (buf) { - buf_c = buffer_acquire(buf); - } else { + if (!buf) { /* NOTE: this func is called from IPC processing task and can be potentially * called before pipeline start even before buffer has been attached. In such * case do not report error but return 0 bytes available for GET_DATA and * 0 bytes free for SET_DATA. */ - buf_c = NULL; comp_warn(dev, "copier_ipcgtw_process(): no buffer found"); } @@ -126,13 +122,13 @@ int copier_ipcgtw_process(const struct ipc4_ipcgtw_cmd *cmd, switch (cmd->primary.r.cmd) { case IPC4_IPCGWCMD_GET_DATA: - if (buf_c) { + if (buf) { data_size = MIN(cmd->extension.r.data_size, SOF_IPC_MSG_MAX_SIZE - 4); - data_size = MIN(data_size, audio_stream_get_avail_bytes(&buf_c->stream)); - buffer_stream_invalidate(buf_c, data_size); - audio_stream_copy_bytes_to_linear(&buf_c->stream, out->payload, data_size); - comp_update_buffer_consume(buf_c, data_size); - out->u.size_avail = audio_stream_get_avail_bytes(&buf_c->stream); + data_size = MIN(data_size, audio_stream_get_avail_bytes(&buf->stream)); + buffer_stream_invalidate(buf, data_size); + audio_stream_copy_bytes_to_linear(&buf->stream, out->payload, data_size); + comp_update_buffer_consume(buf, data_size); + out->u.size_avail = audio_stream_get_avail_bytes(&buf->stream); *reply_payload_size = data_size + 4; } else { out->u.size_avail = 0; @@ -141,18 +137,18 @@ int copier_ipcgtw_process(const struct ipc4_ipcgtw_cmd *cmd, break; case IPC4_IPCGWCMD_SET_DATA: - if (buf_c) { + if (buf) { data_size = MIN(cmd->extension.r.data_size, - audio_stream_get_free_bytes(&buf_c->stream)); + audio_stream_get_free_bytes(&buf->stream)); dcache_invalidate_region((__sparse_force void __sparse_cache *) MAILBOX_HOSTBOX_BASE, data_size + offsetof(struct ipc4_ipc_gateway_cmd_data, payload)); - audio_stream_copy_bytes_from_linear(in->payload, &buf_c->stream, + audio_stream_copy_bytes_from_linear(in->payload, &buf->stream, data_size); - buffer_stream_writeback(buf_c, data_size); - comp_update_buffer_produce(buf_c, data_size); + buffer_stream_writeback(buf, data_size); + comp_update_buffer_produce(buf, data_size); out->u.size_consumed = data_size; *reply_payload_size = 4; } else { @@ -163,20 +159,16 @@ int copier_ipcgtw_process(const struct ipc4_ipcgtw_cmd *cmd, case IPC4_IPCGWCMD_FLUSH_DATA: *reply_payload_size = 0; - if (buf_c) - audio_stream_reset(&buf_c->stream); + if (buf) + audio_stream_reset(&buf->stream); break; default: comp_err(dev, "copier_ipcgtw_process(): unexpected cmd: %u", (unsigned int)cmd->primary.r.cmd); - if (buf_c) - buffer_release(buf_c); return -EINVAL; } - if (buf_c) - buffer_release(buf_c); return 0; } @@ -184,7 +176,6 @@ int copier_ipcgtw_params(struct ipcgtw_data *ipcgtw_data, struct comp_dev *dev, struct sof_ipc_stream_params *params) { struct comp_buffer *buf; - struct comp_buffer __sparse_cache *buf_c; int err; comp_dbg(dev, "ipcgtw_params()"); @@ -196,9 +187,7 @@ int copier_ipcgtw_params(struct ipcgtw_data *ipcgtw_data, struct comp_dev *dev, } /* resize buffer to size specified in IPC gateway config blob */ - buf_c = buffer_acquire(buf); - err = buffer_set_size(buf_c, ipcgtw_data->buf_size, 0); - buffer_release(buf_c); + err = buffer_set_size(buf, ipcgtw_data->buf_size, 0); if (err < 0) { comp_err(dev, "ipcgtw_params(): failed to resize buffer to %u bytes", @@ -214,10 +203,7 @@ void copier_ipcgtw_reset(struct comp_dev *dev) struct comp_buffer *buf = get_buffer(dev); if (buf) { - struct comp_buffer __sparse_cache *buf_c = buffer_acquire(buf); - - audio_stream_reset(&buf_c->stream); - buffer_release(buf_c); + audio_stream_reset(&buf->stream); } else { comp_warn(dev, "ipcgtw_reset(): no buffer found"); } diff --git a/src/audio/crossover/crossover.c b/src/audio/crossover/crossover.c index 029e2fcbf74c..4e89a9d05042 100644 --- a/src/audio/crossover/crossover.c +++ b/src/audio/crossover/crossover.c @@ -133,7 +133,6 @@ static int crossover_assign_sinks(struct processing_module *mod, struct sof_crossover_config *config = cd->config; struct comp_dev *dev = mod->dev; struct comp_buffer *sink; - struct comp_buffer __sparse_cache *sink_c; struct list_item *sink_list; int num_sinks = 0; int i; @@ -143,14 +142,12 @@ static int crossover_assign_sinks(struct processing_module *mod, unsigned int sink_id, state; sink = container_of(sink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); #if CONFIG_IPC_MAJOR_4 sink_id = cd->output_pin_index[j]; #else - sink_id = sink_c->pipeline_id; + sink_id = sink->pipeline_id; #endif - state = sink_c->sink->state; - buffer_release(sink_c); + state = sink->sink->state; if (state != dev->state) { j++; continue; @@ -486,7 +483,6 @@ static int crossover_check_sink_assign(struct processing_module *mod, { struct comp_dev *dev = mod->dev; struct comp_buffer *sink; - struct comp_buffer __sparse_cache *sink_c; struct list_item *sink_list; int num_assigned_sinks = 0; uint8_t assigned_sinks[SOF_CROSSOVER_MAX_STREAMS] = {0}; @@ -496,9 +492,7 @@ static int crossover_check_sink_assign(struct processing_module *mod, unsigned int pipeline_id; sink = container_of(sink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); - pipeline_id = sink_c->pipeline_id; - buffer_release(sink_c); + pipeline_id = sink->pipeline_id; i = crossover_get_stream_index(mod, config, pipeline_id); if (i < 0) { @@ -623,7 +617,7 @@ static int crossover_process_audio_stream(struct processing_module *mod, bool enabled_buffers[PLATFORM_MAX_STREAMS] = { false }; struct comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - struct audio_stream __sparse_cache *source = input_buffers[0].data; + struct audio_stream *source = input_buffers[0].data; uint32_t num_sinks; uint32_t num_assigned_sinks = 0; /* The frames count to process from module adapter applies for source buffer and @@ -691,7 +685,6 @@ static int crossover_process_audio_stream(struct processing_module *mod, static void crossover_params(struct processing_module *mod) { struct sof_ipc_stream_params *params = mod->stream_params; - struct comp_buffer __sparse_cache *sink_c, *source_c; struct comp_buffer *sinkb, *sourceb; struct list_item *sink_list; struct comp_dev *dev = mod->dev; @@ -702,15 +695,11 @@ static void crossover_params(struct processing_module *mod) component_set_nearest_period_frames(dev, params->rate); sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - source_c = buffer_acquire(sourceb); - ipc4_update_buffer_format(source_c, &mod->priv.cfg.base_cfg.audio_fmt); - buffer_release(source_c); + ipc4_update_buffer_format(sourceb, &mod->priv.cfg.base_cfg.audio_fmt); list_for_item(sink_list, &dev->bsink_list) { sinkb = container_of(sink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sinkb); - ipc4_update_buffer_format(sink_c, &mod->priv.cfg.base_cfg.audio_fmt); - buffer_release(sink_c); + ipc4_update_buffer_format(sinkb, &mod->priv.cfg.base_cfg.audio_fmt); } } #endif @@ -721,13 +710,12 @@ static void crossover_params(struct processing_module *mod) * \return Error code. */ static int crossover_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; struct comp_buffer *source, *sink; - struct comp_buffer __sparse_cache *source_c, *sink_c; struct list_item *sink_list; int channels; int ret = 0; @@ -741,27 +729,23 @@ static int crossover_prepare(struct processing_module *mod, /* Crossover has a variable number of sinks */ mod->max_sinks = SOF_CROSSOVER_MAX_STREAMS; source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - source_c = buffer_acquire(source); /* Get source data format */ - cd->source_format = audio_stream_get_frm_fmt(&source_c->stream); - channels = audio_stream_get_channels(&source_c->stream); - audio_stream_init_alignment_constants(1, 1, &source_c->stream); - buffer_release(source_c); + cd->source_format = audio_stream_get_frm_fmt(&source->stream); + channels = audio_stream_get_channels(&source->stream); + audio_stream_init_alignment_constants(1, 1, &source->stream); /* Validate frame format and buffer size of sinks */ list_for_item(sink_list, &dev->bsink_list) { sink = container_of(sink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); - if (cd->source_format == audio_stream_get_frm_fmt(&sink_c->stream)) { - audio_stream_init_alignment_constants(1, 1, &sink_c->stream); + if (cd->source_format == audio_stream_get_frm_fmt(&sink->stream)) { + audio_stream_init_alignment_constants(1, 1, &sink->stream); } else { comp_err(dev, "crossover_prepare(): Source fmt %d and sink fmt %d are different.", - cd->source_format, audio_stream_get_frm_fmt(&sink_c->stream)); + cd->source_format, audio_stream_get_frm_fmt(&sink->stream)); ret = -EINVAL; } - buffer_release(sink_c); if (ret < 0) return ret; } @@ -832,8 +816,8 @@ static int crossover_reset(struct processing_module *mod) } /** \brief Crossover Filter component definition. */ -static struct module_interface crossover_interface = { - .init = crossover_init, +static const struct module_interface crossover_interface = { + .init = crossover_init, .prepare = crossover_prepare, .process_audio_stream = crossover_process_audio_stream, .set_configuration = crossover_set_config, diff --git a/src/audio/crossover/crossover_generic.c b/src/audio/crossover/crossover_generic.c index ad8b6b930ea9..0823ce85920f 100644 --- a/src/audio/crossover/crossover_generic.c +++ b/src/audio/crossover/crossover_generic.c @@ -93,8 +93,8 @@ static void crossover_s16_default_pass(struct comp_data *cd, int32_t num_sinks, uint32_t frames) { - const struct audio_stream __sparse_cache *sink_stream; - const struct audio_stream __sparse_cache *source_stream = bsource->data; + const struct audio_stream *sink_stream; + const struct audio_stream *source_stream = bsource->data; int16_t *x; int32_t *y; int i, j; @@ -121,8 +121,8 @@ static void crossover_s32_default_pass(struct comp_data *cd, int32_t num_sinks, uint32_t frames) { - const struct audio_stream __sparse_cache *sink_stream; - const struct audio_stream __sparse_cache *source_stream = bsource->data; + const struct audio_stream *sink_stream; + const struct audio_stream *source_stream = bsource->data; int32_t *x, *y; int i, j; int n = audio_stream_get_channels(source_stream) * frames; @@ -149,8 +149,8 @@ static void crossover_s16_default(struct comp_data *cd, uint32_t frames) { struct crossover_state *state; - const struct audio_stream __sparse_cache *source_stream = bsource->data; - struct audio_stream __sparse_cache *sink_stream; + const struct audio_stream *source_stream = bsource->data; + struct audio_stream *sink_stream; int16_t *x, *y; int ch, i, j; int idx; @@ -187,8 +187,8 @@ static void crossover_s24_default(struct comp_data *cd, uint32_t frames) { struct crossover_state *state; - const struct audio_stream __sparse_cache *source_stream = bsource->data; - struct audio_stream __sparse_cache *sink_stream; + const struct audio_stream *source_stream = bsource->data; + struct audio_stream *sink_stream; int32_t *x, *y; int ch, i, j; int idx; @@ -225,8 +225,8 @@ static void crossover_s32_default(struct comp_data *cd, uint32_t frames) { struct crossover_state *state; - const struct audio_stream __sparse_cache *source_stream = bsource->data; - struct audio_stream __sparse_cache *sink_stream; + const struct audio_stream *source_stream = bsource->data; + struct audio_stream *sink_stream; int32_t *x, *y; int ch, i, j; int idx; diff --git a/src/audio/dai-legacy.c b/src/audio/dai-legacy.c index 884f2b00f2fc..ccbe72f4062b 100644 --- a/src/audio/dai-legacy.c +++ b/src/audio/dai-legacy.c @@ -97,7 +97,6 @@ static void dai_dma_cb(void *arg, enum notify_id type, void *data) struct comp_dev *dev = arg; struct dai_data *dd = comp_get_drvdata(dev); uint32_t bytes = next->elem.size; - struct comp_buffer __sparse_cache *local_buf, *dma_buf; int ret; comp_dbg(dev, "dai_dma_cb()"); @@ -113,37 +112,32 @@ static void dai_dma_cb(void *arg, enum notify_id type, void *data) next->status = DMA_CB_STATUS_END; } - dma_buf = buffer_acquire(dd->dma_buffer); - /* is our pipeline handling an XRUN ? */ if (dd->xrun) { /* make sure we only playback silence during an XRUN */ if (dev->direction == SOF_IPC_STREAM_PLAYBACK) /* fill buffer with silence */ - buffer_zero(dma_buf); - buffer_release(dma_buf); + buffer_zero(dd->dma_buffer); return; } - local_buf = buffer_acquire(dd->local_buffer); - if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { - ret = dma_buffer_copy_to(local_buf, dma_buf, + ret = dma_buffer_copy_to(dd->local_buffer, dd->dma_buffer, dd->process, bytes); } else { - ret = dma_buffer_copy_from(dma_buf, local_buf, + ret = dma_buffer_copy_from(dd->dma_buffer, dd->local_buffer, dd->process, bytes); } /* assert dma_buffer_copy succeed */ if (ret < 0) { - struct comp_buffer __sparse_cache *source_c, *sink_c; + struct comp_buffer *source_c, *sink_c; source_c = dev->direction == SOF_IPC_STREAM_PLAYBACK ? - local_buf : dma_buf; + dd->local_buffer : dd->dma_buffer; sink_c = dev->direction == SOF_IPC_STREAM_PLAYBACK ? - dma_buf : local_buf; + dd->dma_buffer : dd->local_buffer; comp_err(dev, "dai_dma_cb() dma buffer copy failed, dir %d bytes %d avail %d free %d", dev->direction, bytes, audio_stream_get_avail_samples(&source_c->stream) * @@ -154,9 +148,6 @@ static void dai_dma_cb(void *arg, enum notify_id type, void *data) /* update host position (in bytes offset) for drivers */ dd->total_data_processed += bytes; } - - buffer_release(local_buf); - buffer_release(dma_buf); } int dai_common_new(struct dai_data *dd, struct comp_dev *dev, const struct ipc_config_dai *dai) @@ -357,23 +348,18 @@ static int dai_playback_params(struct comp_dev *dev, uint32_t period_bytes, { struct dai_data *dd = comp_get_drvdata(dev); struct dma_sg_config *config = &dd->config; - struct comp_buffer __sparse_cache *dma_buf = buffer_acquire(dd->dma_buffer), - *local_buf = buffer_acquire(dd->local_buffer); - uint32_t local_fmt = audio_stream_get_frm_fmt(&local_buf->stream); - uint32_t dma_fmt = audio_stream_get_frm_fmt(&dma_buf->stream); + uint32_t local_fmt = audio_stream_get_frm_fmt(&dd->local_buffer->stream); + uint32_t dma_fmt = audio_stream_get_frm_fmt(&dd->dma_buffer->stream); uint32_t fifo; int err = 0; /* set processing function */ dd->process = pcm_get_conversion_function(local_fmt, dma_fmt); - buffer_release(local_buf); - if (!dd->process) { comp_err(dev, "dai_playback_params(): converter function NULL: local fmt %d dma fmt %d\n", local_fmt, dma_fmt); - err = -EINVAL; - goto out; + return -EINVAL; } /* set up DMA configuration */ @@ -401,16 +387,13 @@ static int dai_playback_params(struct comp_dev *dev, uint32_t period_bytes, config->direction, period_count, period_bytes, - (uintptr_t)(audio_stream_get_addr(&dma_buf->stream)), + (uintptr_t)(audio_stream_get_addr(&dd->dma_buffer->stream)), fifo); if (err < 0) comp_err(dev, "dai_playback_params(): dma_sg_alloc() for period_count %d period_bytes %d failed with err = %d", period_count, period_bytes, err); } -out: - buffer_release(dma_buf); - return err; } @@ -419,23 +402,18 @@ static int dai_capture_params(struct comp_dev *dev, uint32_t period_bytes, { struct dai_data *dd = comp_get_drvdata(dev); struct dma_sg_config *config = &dd->config; - struct comp_buffer __sparse_cache *dma_buf = buffer_acquire(dd->dma_buffer), - *local_buf = buffer_acquire(dd->local_buffer); - uint32_t local_fmt = audio_stream_get_frm_fmt(&local_buf->stream); - uint32_t dma_fmt = audio_stream_get_frm_fmt(&dma_buf->stream); + uint32_t local_fmt = audio_stream_get_frm_fmt(&dd->local_buffer->stream); + uint32_t dma_fmt = audio_stream_get_frm_fmt(&dd->dma_buffer->stream); uint32_t fifo; int err = 0; /* set processing function */ dd->process = pcm_get_conversion_function(dma_fmt, local_fmt); - buffer_release(local_buf); - if (!dd->process) { comp_err(dev, "dai_capture_params(): converter function NULL: local fmt %d dma fmt %d\n", local_fmt, dma_fmt); - err = -EINVAL; - goto out; + return -EINVAL; } /* set up DMA configuration */ @@ -474,16 +452,13 @@ static int dai_capture_params(struct comp_dev *dev, uint32_t period_bytes, config->direction, period_count, period_bytes, - (uintptr_t)(audio_stream_get_addr(&dma_buf->stream)), + (uintptr_t)(audio_stream_get_addr(&dd->dma_buffer->stream)), fifo); if (err < 0) comp_err(dev, "dai_capture_params(): dma_sg_alloc() for period_count %d period_bytes %d failed with err = %d", period_count, period_bytes, err); } -out: - buffer_release(dma_buf); - return err; } @@ -491,7 +466,6 @@ int dai_common_params(struct dai_data *dd, struct comp_dev *dev, struct sof_ipc_stream_params *params) { struct sof_ipc_stream_params hw_params = *params; - struct comp_buffer __sparse_cache *buffer_c; uint32_t frame_size; uint32_t period_count; uint32_t period_bytes; @@ -565,13 +539,9 @@ int dai_common_params(struct dai_data *dd, struct comp_dev *dev, return -EINVAL; } - buffer_c = buffer_acquire(dd->local_buffer); - /* calculate frame size */ frame_size = get_frame_bytes(dev->ipc_config.frame_fmt, - audio_stream_get_channels(&buffer_c->stream)); - - buffer_release(buffer_c); + audio_stream_get_channels(&dd->local_buffer->stream)); /* calculate period size */ period_bytes = dev->frames * frame_size; @@ -589,9 +559,7 @@ int dai_common_params(struct dai_data *dd, struct comp_dev *dev, /* alloc DMA buffer or change its size if exists */ if (dd->dma_buffer) { - buffer_c = buffer_acquire(dd->dma_buffer); - err = buffer_set_size(buffer_c, buffer_size, addr_align); - buffer_release(buffer_c); + err = buffer_set_size(dd->dma_buffer, buffer_size, addr_align); if (err < 0) { comp_err(dev, "dai_params(): buffer_set_size() failed, buffer_size = %u", @@ -600,7 +568,7 @@ int dai_common_params(struct dai_data *dd, struct comp_dev *dev, } } else { dd->dma_buffer = buffer_alloc(buffer_size, SOF_MEM_CAPS_DMA, 0, - addr_align); + addr_align, false); if (!dd->dma_buffer) { comp_err(dev, "dai_params(): failed to alloc dma buffer"); return -ENOMEM; @@ -613,10 +581,8 @@ int dai_common_params(struct dai_data *dd, struct comp_dev *dev, * frame_fmt's (using pcm converter). */ hw_params.frame_fmt = dev->ipc_config.frame_fmt; - buffer_c = buffer_acquire(dd->dma_buffer); - buffer_set_params(buffer_c, &hw_params, + buffer_set_params(dd->dma_buffer, &hw_params, BUFFER_UPDATE_FORCE); - buffer_release(buffer_c); } return dev->direction == SOF_IPC_STREAM_PLAYBACK ? @@ -685,7 +651,6 @@ int dai_common_config_prepare(struct dai_data *dd, struct comp_dev *dev) int dai_common_prepare(struct dai_data *dd, struct comp_dev *dev) { - struct comp_buffer __sparse_cache *buffer_c; int ret; dd->total_data_processed = 0; @@ -703,9 +668,7 @@ int dai_common_prepare(struct dai_data *dd, struct comp_dev *dev) } /* clear dma buffer to avoid pop noise */ - buffer_c = buffer_acquire(dd->dma_buffer); - buffer_zero(buffer_c); - buffer_release(buffer_c); + buffer_zero(dd->dma_buffer); /* dma reconfig not required if XRUN handling */ if (dd->xrun) { @@ -815,11 +778,7 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev, * this is only supported at capture mode. */ if (dev->direction == SOF_IPC_STREAM_CAPTURE) { - struct comp_buffer __sparse_cache *buffer_c = - buffer_acquire(dd->dma_buffer); - - buffer_zero(buffer_c); - buffer_release(buffer_c); + buffer_zero(dd->dma_buffer); } /* only start the DAI if we are not XRUN handling */ @@ -947,17 +906,14 @@ static int dai_comp_trigger(struct comp_dev *dev, int cmd) static void dai_report_xrun(struct comp_dev *dev, uint32_t bytes) { struct dai_data *dd = comp_get_drvdata(dev); - struct comp_buffer __sparse_cache *buf_c = buffer_acquire(dd->local_buffer); if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { comp_err(dev, "dai_report_xrun(): underrun due to no data available"); - comp_underrun(dev, buf_c, bytes); + comp_underrun(dev, dd->local_buffer, bytes); } else { comp_err(dev, "dai_report_xrun(): overrun due to no space available"); - comp_overrun(dev, buf_c, bytes); + comp_overrun(dev, dd->local_buffer, bytes); } - - buffer_release(buf_c); } /* copy and process stream data from source to sink buffers */ @@ -965,7 +921,6 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun { uint32_t dma_fmt; uint32_t sampling; - struct comp_buffer __sparse_cache *buf_c; uint32_t avail_bytes = 0; uint32_t free_bytes = 0; uint32_t copy_bytes = 0; @@ -981,23 +936,17 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun return ret; } - buf_c = buffer_acquire(dd->dma_buffer); - - dma_fmt = audio_stream_get_frm_fmt(&buf_c->stream); + dma_fmt = audio_stream_get_frm_fmt(&dd->dma_buffer->stream); sampling = get_sample_bytes(dma_fmt); - buffer_release(buf_c); - - buf_c = buffer_acquire(dd->local_buffer); - /* calculate minimum size to copy */ if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { - src_samples = audio_stream_get_avail_samples(&buf_c->stream); + src_samples = audio_stream_get_avail_samples(&dd->local_buffer->stream); sink_samples = free_bytes / sampling; samples = MIN(src_samples, sink_samples); } else { src_samples = avail_bytes / sampling; - sink_samples = audio_stream_get_free_samples(&buf_c->stream); + sink_samples = audio_stream_get_free_samples(&dd->local_buffer->stream); samples = MIN(src_samples, sink_samples); } @@ -1010,9 +959,7 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun comp_dbg(dev, "dai_common_copy(), dir: %d copy_bytes= 0x%x, frames= %d", dev->direction, copy_bytes, - samples / audio_stream_get_channels(&buf_c->stream)); - - buffer_release(buf_c); + samples / audio_stream_get_channels(&dd->local_buffer->stream)); /* Check possibility of glitch occurrence */ if (dev->direction == SOF_IPC_STREAM_PLAYBACK && diff --git a/src/audio/dai-zephyr.c b/src/audio/dai-zephyr.c index bcbfd91dd2ad..6a0694519235 100644 --- a/src/audio/dai-zephyr.c +++ b/src/audio/dai-zephyr.c @@ -226,7 +226,6 @@ static enum dma_cb_status dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes, pcm_converter_func *converter) { - struct comp_buffer __sparse_cache *local_buf, *dma_buf; enum dma_cb_status dma_status = DMA_CB_STATUS_RELOAD; int ret; @@ -241,33 +240,29 @@ dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes, dma_status = DMA_CB_STATUS_END; } - dma_buf = buffer_acquire(dd->dma_buffer); - /* is our pipeline handling an XRUN ? */ if (dd->xrun) { /* make sure we only playback silence during an XRUN */ if (dev->direction == SOF_IPC_STREAM_PLAYBACK) /* fill buffer with silence */ - buffer_zero(dma_buf); - buffer_release(dma_buf); + buffer_zero(dd->dma_buffer); return dma_status; } - local_buf = buffer_acquire(dd->local_buffer); - if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { - ret = dma_buffer_copy_to(local_buf, dma_buf, + ret = dma_buffer_copy_to(dd->local_buffer, dd->dma_buffer, dd->process, bytes); } else { struct list_item *sink_list; - audio_stream_invalidate(&dma_buf->stream, bytes); + audio_stream_invalidate(&dd->dma_buffer->stream, bytes); /* * The PCM converter functions used during DMA buffer copy can never fail, * so no need to check the return value of dma_buffer_copy_from_no_consume(). */ - ret = dma_buffer_copy_from_no_consume(dma_buf, local_buf, dd->process, bytes); + ret = dma_buffer_copy_from_no_consume(dd->dma_buffer, dd->local_buffer, + dd->process, bytes); #if CONFIG_IPC_MAJOR_4 /* Skip in case of endpoint DAI devices created by the copier */ if (converter) { @@ -276,7 +271,6 @@ dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes, * function */ list_for_item(sink_list, &dev->bsink_list) { - struct comp_buffer __sparse_cache *sink_c; struct comp_dev *sink_dev; struct comp_buffer *sink; int j; @@ -287,43 +281,41 @@ dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes, if (sink == dd->local_buffer) continue; - sink_c = buffer_acquire(sink); - sink_dev = sink_c->sink; + sink_dev = sink->sink; - j = IPC4_SINK_QUEUE_ID(sink_c->id); + j = IPC4_SINK_QUEUE_ID(sink->id); if (j >= IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT) { comp_err(dev, "Sink queue ID: %d >= max output pin count: %d\n", j, IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT); ret = -EINVAL; - goto err; + continue; } if (!converter[j]) { comp_err(dev, "No PCM converter for sink queue %d\n", j); ret = -EINVAL; - goto err; + continue; } if (sink_dev && sink_dev->state == COMP_STATE_ACTIVE) - ret = dma_buffer_copy_from_no_consume(dma_buf, sink_c, - converter[j], bytes); -err: - buffer_release(sink_c); + ret = dma_buffer_copy_from_no_consume(dd->dma_buffer, + sink, converter[j], + bytes); } } #endif - audio_stream_consume(&dma_buf->stream, bytes); + audio_stream_consume(&dd->dma_buffer->stream, bytes); } /* assert dma_buffer_copy succeed */ if (ret < 0) { - struct comp_buffer __sparse_cache *source_c, *sink_c; + struct comp_buffer *source_c, *sink_c; source_c = dev->direction == SOF_IPC_STREAM_PLAYBACK ? - local_buf : dma_buf; + dd->local_buffer : dd->dma_buffer; sink_c = dev->direction == SOF_IPC_STREAM_PLAYBACK ? - dma_buf : local_buf; + dd->dma_buffer : dd->local_buffer; comp_err(dev, "dai_dma_cb() dma buffer copy failed, dir %d bytes %d avail %d free %d", dev->direction, bytes, audio_stream_get_avail_samples(&source_c->stream) * @@ -335,9 +327,6 @@ dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes, dd->total_data_processed += bytes; } - buffer_release(local_buf); - buffer_release(dma_buf); - return dma_status; } @@ -346,7 +335,6 @@ static enum dma_cb_status dai_dma_multi_endpoint_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t frames, struct comp_buffer *multi_endpoint_buffer) { - struct comp_buffer __sparse_cache *multi_buf_c, *dma_buf; enum dma_cb_status dma_status = DMA_CB_STATUS_RELOAD; uint32_t i, bytes; @@ -361,48 +349,41 @@ dai_dma_multi_endpoint_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t fr dma_status = DMA_CB_STATUS_END; } - dma_buf = buffer_acquire(dd->dma_buffer); - /* is our pipeline handling an XRUN ? */ if (dd->xrun) { /* make sure we only playback silence during an XRUN */ if (dev->direction == SOF_IPC_STREAM_PLAYBACK) /* fill buffer with silence */ - buffer_zero(dma_buf); - buffer_release(dma_buf); + buffer_zero(dd->dma_buffer); return dma_status; } - multi_buf_c = buffer_acquire(multi_endpoint_buffer); - - bytes = frames * audio_stream_frame_bytes(&dma_buf->stream); + bytes = frames * audio_stream_frame_bytes(&dd->dma_buffer->stream); if (dev->direction == SOF_IPC_STREAM_CAPTURE) - audio_stream_invalidate(&dma_buf->stream, bytes); + audio_stream_invalidate(&dd->dma_buffer->stream, bytes); /* copy all channels one by one */ - for (i = 0; i < audio_stream_get_channels(&dma_buf->stream); i++) { - uint32_t multi_buf_channel = dma_buf->chmap[i]; + for (i = 0; i < audio_stream_get_channels(&dd->dma_buffer->stream); i++) { + uint32_t multi_buf_channel = dd->dma_buffer->chmap[i]; if (dev->direction == SOF_IPC_STREAM_PLAYBACK) - dd->process(&multi_buf_c->stream, multi_buf_channel, - &dma_buf->stream, i, frames); + dd->process(&multi_endpoint_buffer->stream, multi_buf_channel, + &dd->dma_buffer->stream, i, frames); else - dd->process(&dma_buf->stream, i, &multi_buf_c->stream, + dd->process(&dd->dma_buffer->stream, i, &multi_endpoint_buffer->stream, multi_buf_channel, frames); } if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { - audio_stream_writeback(&dma_buf->stream, bytes); - audio_stream_produce(&dma_buf->stream, bytes); + audio_stream_writeback(&dd->dma_buffer->stream, bytes); + audio_stream_produce(&dd->dma_buffer->stream, bytes); } else { - audio_stream_consume(&dma_buf->stream, bytes); + audio_stream_consume(&dd->dma_buffer->stream, bytes); } /* update host position (in bytes offset) for drivers */ dd->total_data_processed += bytes; - buffer_release(multi_buf_c); - buffer_release(dma_buf); return dma_status; } @@ -592,23 +573,18 @@ static int dai_playback_params(struct dai_data *dd, struct comp_dev *dev, uint32 struct dma_config *dma_cfg; struct dma_block_config *dma_block_cfg; struct dma_block_config *prev = NULL; - struct comp_buffer __sparse_cache *dma_buf = buffer_acquire(dd->dma_buffer), - *local_buf = buffer_acquire(dd->local_buffer); - uint32_t local_fmt = audio_stream_get_frm_fmt(&local_buf->stream); - uint32_t dma_fmt = audio_stream_get_frm_fmt(&dma_buf->stream); + uint32_t local_fmt = audio_stream_get_frm_fmt(&dd->local_buffer->stream); + uint32_t dma_fmt = audio_stream_get_frm_fmt(&dd->dma_buffer->stream); uint32_t fifo, max_block_count, buf_size; int i, err = 0; - buffer_release(local_buf); - /* set processing function */ dd->process = pcm_get_conversion_function(local_fmt, dma_fmt); if (!dd->process) { comp_err(dev, "dai_playback_params(): converter function NULL: local fmt %d dma fmt %d\n", local_fmt, dma_fmt); - err = -EINVAL; - goto out; + return -EINVAL; } /* set up DMA configuration */ @@ -635,12 +611,12 @@ static int dai_playback_params(struct dai_data *dd, struct comp_dev *dev, uint32 &max_block_count); if (err < 0) { comp_err(dev, "dai_playback_params(): could not get dma attr max block count, err = %d", err); - goto out; + return err; } if (!max_block_count) { comp_err(dev, "dai_playback_params(): invalid max-block-count of zero"); - goto out; + return err; } if (max_block_count < period_count) { @@ -661,12 +637,12 @@ static int dai_playback_params(struct dai_data *dd, struct comp_dev *dev, uint32 config->direction, period_count, period_bytes, - (uintptr_t)audio_stream_get_addr(&dma_buf->stream), + (uintptr_t)audio_stream_get_addr(&dd->dma_buffer->stream), fifo); if (err < 0) { comp_err(dev, "dai_playback_params(): dma_sg_alloc() for period_count %d period_bytes %d failed with err = %d", period_count, period_bytes, err); - goto out; + return err; } } @@ -721,8 +697,6 @@ static int dai_playback_params(struct dai_data *dd, struct comp_dev *dev, uint32 free: if (err < 0) dma_sg_free(&config->elem_array); -out: - buffer_release(dma_buf); return err; } @@ -734,23 +708,18 @@ static int dai_capture_params(struct dai_data *dd, struct comp_dev *dev, uint32_ struct dma_config *dma_cfg; struct dma_block_config *dma_block_cfg; struct dma_block_config *prev = NULL; - struct comp_buffer __sparse_cache *dma_buf = buffer_acquire(dd->dma_buffer), - *local_buf = buffer_acquire(dd->local_buffer); - uint32_t local_fmt = audio_stream_get_frm_fmt(&local_buf->stream); - uint32_t dma_fmt = audio_stream_get_frm_fmt(&dma_buf->stream); + uint32_t local_fmt = audio_stream_get_frm_fmt(&dd->local_buffer->stream); + uint32_t dma_fmt = audio_stream_get_frm_fmt(&dd->dma_buffer->stream); uint32_t fifo, max_block_count, buf_size; int i, err = 0; - buffer_release(local_buf); - /* set processing function */ dd->process = pcm_get_conversion_function(dma_fmt, local_fmt); if (!dd->process) { comp_err(dev, "dai_capture_params(): converter function NULL: local fmt %d dma fmt %d\n", local_fmt, dma_fmt); - err = -EINVAL; - goto out; + return -EINVAL; } /* set up DMA configuration */ @@ -789,12 +758,12 @@ static int dai_capture_params(struct dai_data *dd, struct comp_dev *dev, uint32_ &max_block_count); if (err < 0) { comp_err(dev, "dai_capture_params(): could not get dma attr max block count, err = %d", err); - goto out; + return err; } if (!max_block_count) { comp_err(dev, "dai_capture_params(): invalid max-block-count of zero"); - goto out; + return err; } if (max_block_count < period_count) { @@ -815,12 +784,12 @@ static int dai_capture_params(struct dai_data *dd, struct comp_dev *dev, uint32_ config->direction, period_count, period_bytes, - (uintptr_t)audio_stream_get_addr(&dma_buf->stream), + (uintptr_t)audio_stream_get_addr(&dd->dma_buffer->stream), fifo); if (err < 0) { comp_err(dev, "dai_capture_params(): dma_sg_alloc() for period_count %d period_bytes %d failed with err = %d", period_count, period_bytes, err); - goto out; + return err; } } @@ -875,8 +844,6 @@ static int dai_capture_params(struct dai_data *dd, struct comp_dev *dev, uint32_ free: if (err < 0) dma_sg_free(&config->elem_array); -out: - buffer_release(dma_buf); return err; } @@ -885,7 +852,6 @@ int dai_common_params(struct dai_data *dd, struct comp_dev *dev, struct sof_ipc_stream_params *params) { struct sof_ipc_stream_params hw_params = *params; - struct comp_buffer __sparse_cache *buffer_c; uint32_t frame_size; uint32_t period_count; uint32_t period_bytes; @@ -967,9 +933,7 @@ int dai_common_params(struct dai_data *dd, struct comp_dev *dev, /* alloc DMA buffer or change its size if exists */ if (dd->dma_buffer) { - buffer_c = buffer_acquire(dd->dma_buffer); - err = buffer_set_size(buffer_c, buffer_size, addr_align); - buffer_release(buffer_c); + err = buffer_set_size(dd->dma_buffer, buffer_size, addr_align); if (err < 0) { comp_err(dev, "dai_common_params(): buffer_set_size() failed, buffer_size = %u", @@ -977,8 +941,9 @@ int dai_common_params(struct dai_data *dd, struct comp_dev *dev, return err; } } else { + /* allocate not shared buffer */ dd->dma_buffer = buffer_alloc(buffer_size, SOF_MEM_CAPS_DMA, 0, - addr_align); + addr_align, false); if (!dd->dma_buffer) { comp_err(dev, "dai_common_params(): failed to alloc dma buffer"); return -ENOMEM; @@ -991,11 +956,10 @@ int dai_common_params(struct dai_data *dd, struct comp_dev *dev, * frame_fmt's (using pcm converter). */ hw_params.frame_fmt = dev->ipc_config.frame_fmt; - buffer_c = buffer_acquire(dd->dma_buffer); - buffer_set_params(buffer_c, &hw_params, + buffer_set_params(dd->dma_buffer, &hw_params, BUFFER_UPDATE_FORCE); + dd->sampling = get_sample_bytes(hw_params.frame_fmt); - buffer_release(buffer_c); } dd->fast_mode = dd->ipc_config.feature_mask & BIT(IPC4_COPIER_FAST_MODE); @@ -1063,7 +1027,6 @@ int dai_common_config_prepare(struct dai_data *dd, struct comp_dev *dev) int dai_common_prepare(struct dai_data *dd, struct comp_dev *dev) { - struct comp_buffer __sparse_cache *buffer_c; int ret; dd->total_data_processed = 0; @@ -1081,9 +1044,7 @@ int dai_common_prepare(struct dai_data *dd, struct comp_dev *dev) } /* clear dma buffer to avoid pop noise */ - buffer_c = buffer_acquire(dd->dma_buffer); - buffer_zero(buffer_c); - buffer_release(buffer_c); + buffer_zero(dd->dma_buffer); /* dma reconfig not required if XRUN handling */ if (dd->xrun) { @@ -1192,11 +1153,7 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev, * this is only supported at capture mode. */ if (dev->direction == SOF_IPC_STREAM_CAPTURE) { - struct comp_buffer __sparse_cache *buffer_c = - buffer_acquire(dd->dma_buffer); - - buffer_zero(buffer_c); - buffer_release(buffer_c); + buffer_zero(dd->dma_buffer); } /* only start the DAI if we are not XRUN handling */ @@ -1338,17 +1295,13 @@ static int dai_comp_trigger(struct comp_dev *dev, int cmd) /* report xrun occurrence */ static void dai_report_xrun(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes) { - struct comp_buffer __sparse_cache *buf_c = buffer_acquire(dd->local_buffer); - if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { comp_err(dev, "dai_report_xrun(): underrun due to no data available"); - comp_underrun(dev, buf_c, bytes); + comp_underrun(dev, dd->local_buffer, bytes); } else { comp_err(dev, "dai_report_xrun(): overrun due to no space available"); - comp_overrun(dev, buf_c, bytes); + comp_overrun(dev, dd->local_buffer, bytes); } - - buffer_release(buf_c); } /* process and copy stream data from multiple DMA source buffers to sink buffer */ @@ -1356,7 +1309,6 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev, struct comp_buffer *multi_endpoint_buffer, int num_endpoints) { - struct comp_buffer __sparse_cache *buf_c; uint32_t avail_bytes = UINT32_MAX; uint32_t free_bytes = UINT32_MAX; uint32_t frames; @@ -1368,9 +1320,7 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev, if (!num_endpoints || !dd || !multi_endpoint_buffer) return 0; - buf_c = buffer_acquire(dd[0]->dma_buffer); - frame_bytes = audio_stream_frame_bytes(&buf_c->stream); - buffer_release(buf_c); + frame_bytes = audio_stream_frame_bytes(&dd[0]->dma_buffer->stream); direction = dev->direction; @@ -1400,16 +1350,14 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev, free_bytes = MIN(free_bytes, stat.free); } - buf_c = buffer_acquire(multi_endpoint_buffer); /* calculate minimum size to copy */ if (direction == SOF_IPC_STREAM_PLAYBACK) { - src_frames = audio_stream_get_avail_frames(&buf_c->stream); + src_frames = audio_stream_get_avail_frames(&multi_endpoint_buffer->stream); sink_frames = free_bytes / frame_bytes; } else { src_frames = avail_bytes / frame_bytes; - sink_frames = audio_stream_get_free_frames(&buf_c->stream); + sink_frames = audio_stream_get_free_frames(&multi_endpoint_buffer->stream); } - buffer_release(buf_c); frames = MIN(src_frames, sink_frames); @@ -1429,10 +1377,8 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev, } if (direction == SOF_IPC_STREAM_PLAYBACK) { - buf_c = buffer_acquire(multi_endpoint_buffer); - frame_bytes = audio_stream_frame_bytes(&buf_c->stream); - buffer_stream_invalidate(buf_c, frames * frame_bytes); - buffer_release(buf_c); + frame_bytes = audio_stream_frame_bytes(&multi_endpoint_buffer->stream); + buffer_stream_invalidate(multi_endpoint_buffer, frames * frame_bytes); } for (i = 0; i < num_endpoints; i++) { @@ -1448,9 +1394,7 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev, if (status == DMA_CB_STATUS_END) dma_stop(dd[i]->chan->dma->z_dev, dd[i]->chan->index); - buf_c = buffer_acquire(dd[i]->dma_buffer); - copy_bytes = frames * audio_stream_frame_bytes(&buf_c->stream); - buffer_release(buf_c); + copy_bytes = frames * audio_stream_frame_bytes(&dd[i]->dma_buffer->stream); ret = dma_reload(dd[i]->chan->dma->z_dev, dd[i]->chan->index, 0, 0, copy_bytes); if (ret < 0) { dai_report_xrun(dd[i], dev, copy_bytes); @@ -1460,28 +1404,22 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev, dai_dma_position_update(dd[i], dev); } - buf_c = buffer_acquire(multi_endpoint_buffer); - frame_bytes = audio_stream_frame_bytes(&buf_c->stream); + frame_bytes = audio_stream_frame_bytes(&multi_endpoint_buffer->stream); if (direction == SOF_IPC_STREAM_PLAYBACK) { - comp_update_buffer_consume(buf_c, frames * frame_bytes); + comp_update_buffer_consume(multi_endpoint_buffer, frames * frame_bytes); } else { - buffer_stream_writeback(buf_c, frames * frame_bytes); - comp_update_buffer_produce(buf_c, frames * frame_bytes); + buffer_stream_writeback(multi_endpoint_buffer, frames * frame_bytes); + comp_update_buffer_produce(multi_endpoint_buffer, frames * frame_bytes); } - buffer_release(buf_c); return 0; } static void set_new_local_buffer(struct dai_data *dd, struct comp_dev *dev) { - struct comp_buffer __sparse_cache *dma_buf = buffer_acquire(dd->dma_buffer); - struct comp_buffer __sparse_cache *local_buf; - uint32_t dma_fmt = audio_stream_get_frm_fmt(&dma_buf->stream); + uint32_t dma_fmt = audio_stream_get_frm_fmt(&dd->dma_buffer->stream); uint32_t local_fmt; - buffer_release(dma_buf); - if (dev->direction == SOF_IPC_STREAM_PLAYBACK) dd->local_buffer = list_first_item(&dev->bsource_list, struct comp_buffer, @@ -1491,9 +1429,7 @@ static void set_new_local_buffer(struct dai_data *dd, struct comp_dev *dev) struct comp_buffer, source_list); - local_buf = buffer_acquire(dd->local_buffer); - local_fmt = audio_stream_get_frm_fmt(&local_buf->stream); - buffer_release(local_buf); + local_fmt = audio_stream_get_frm_fmt(&dd->local_buffer->stream); dd->process = pcm_get_conversion_function(local_fmt, dma_fmt); @@ -1508,7 +1444,6 @@ static void set_new_local_buffer(struct dai_data *dd, struct comp_dev *dev) int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_func *converter) { uint32_t sampling = dd->sampling; - struct comp_buffer __sparse_cache *buf_c; struct dma_status stat; uint32_t avail_bytes; uint32_t free_bytes; @@ -1551,11 +1486,9 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun /* calculate minimum size to copy */ if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { - buf_c = buffer_acquire(dd->local_buffer); - src_samples = audio_stream_get_avail_samples(&buf_c->stream); + src_samples = audio_stream_get_avail_samples(&dd->local_buffer->stream); sink_samples = free_bytes / sampling; samples = MIN(src_samples, sink_samples); - buffer_release(buf_c); } else { struct list_item *sink_list; @@ -1566,10 +1499,8 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun * a DAI copier and it is chosen as the dd->local buffer */ if (!converter) { - buf_c = buffer_acquire(dd->local_buffer); - sink_samples = audio_stream_get_free_samples(&buf_c->stream); + sink_samples = audio_stream_get_free_samples(&dd->local_buffer->stream); samples = MIN(samples, sink_samples); - buffer_release(buf_c); } else { /* * In the case of capture DAI's with multiple sink buffers, compute the @@ -1581,15 +1512,13 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun struct comp_buffer *sink; sink = container_of(sink_list, struct comp_buffer, source_list); - buf_c = buffer_acquire(sink); - sink_dev = buf_c->sink; + sink_dev = sink->sink; if (sink_dev && sink_dev->state == COMP_STATE_ACTIVE) { sink_samples = - audio_stream_get_free_samples(&buf_c->stream); + audio_stream_get_free_samples(&sink->stream); samples = MIN(samples, sink_samples); } - buffer_release(buf_c); } } @@ -1668,7 +1597,7 @@ static int dai_copy(struct comp_dev *dev) int dai_common_ts_config_op(struct dai_data *dd, struct comp_dev *dev) { struct ipc_config_dai *dai = &dd->ipc_config; - struct dai_ts_cfg cfg; + struct dai_ts_cfg *cfg = &dd->ts_config; comp_dbg(dev, "dai_ts_config()"); if (!dd->chan) { @@ -1678,26 +1607,26 @@ int dai_common_ts_config_op(struct dai_data *dd, struct comp_dev *dev) switch (dai->type) { case SOF_DAI_INTEL_SSP: - cfg.type = DAI_INTEL_SSP; + cfg->type = DAI_INTEL_SSP; break; case SOF_DAI_INTEL_ALH: - cfg.type = DAI_INTEL_ALH; + cfg->type = DAI_INTEL_ALH; break; case SOF_DAI_INTEL_DMIC: - cfg.type = DAI_INTEL_DMIC; + cfg->type = DAI_INTEL_DMIC; break; default: comp_err(dev, "dai_ts_config(), not supported dai type"); return -EINVAL; } - cfg.direction = dai->direction; - cfg.index = dd->dai->index; - cfg.dma_id = dd->dma->plat_data.id; - cfg.dma_chan_index = dd->chan->index; - cfg.dma_chan_count = dd->dma->plat_data.channels; + cfg->direction = dai->direction; + cfg->index = dd->dai->index; + cfg->dma_id = dd->dma->plat_data.id; + cfg->dma_chan_index = dd->chan->index; + cfg->dma_chan_count = dd->dma->plat_data.channels; - return dai_ts_config(dd->dai->dev, &cfg); + return dai_ts_config(dd->dai->dev, cfg); } static int dai_ts_config_op(struct comp_dev *dev) @@ -1709,9 +1638,7 @@ static int dai_ts_config_op(struct comp_dev *dev) int dai_common_ts_start(struct dai_data *dd, struct comp_dev *dev) { - struct dai_ts_cfg cfg; - - return dai_ts_start(dd->dai->dev, &cfg); + return dai_ts_start(dd->dai->dev, (struct dai_ts_cfg *)&dd->ts_config); } static int dai_ts_start_op(struct comp_dev *dev) @@ -1722,16 +1649,14 @@ static int dai_ts_start_op(struct comp_dev *dev) return dai_common_ts_start(dd, dev); } -int dai_common_ts_get(struct dai_data *dd, struct comp_dev *dev, struct timestamp_data *tsd) +int dai_common_ts_get(struct dai_data *dd, struct comp_dev *dev, struct dai_ts_data *tsd) { - struct dai_ts_data tsdata; - struct dai_ts_cfg cfg; + struct dai_ts_cfg *cfg = (struct dai_ts_cfg *)&dd->ts_config; - /* TODO: convert to timestamp_data */ - return dai_ts_get(dd->dai->dev, &cfg, &tsdata); + return dai_ts_get(dd->dai->dev, cfg, tsd); } -static int dai_ts_get_op(struct comp_dev *dev, struct timestamp_data *tsd) +static int dai_ts_get_op(struct comp_dev *dev, struct dai_ts_data *tsd) { struct dai_data *dd = comp_get_drvdata(dev); @@ -1742,9 +1667,7 @@ static int dai_ts_get_op(struct comp_dev *dev, struct timestamp_data *tsd) int dai_common_ts_stop(struct dai_data *dd, struct comp_dev *dev) { - struct dai_ts_cfg cfg; - - return dai_ts_stop(dd->dai->dev, &cfg); + return dai_ts_stop(dd->dai->dev, (struct dai_ts_cfg *)&dd->ts_config); } static int dai_ts_stop_op(struct comp_dev *dev) @@ -1791,7 +1714,6 @@ static uint64_t dai_get_processed_data(struct comp_dev *dev, uint32_t stream_no, #ifdef CONFIG_IPC_MAJOR_4 int dai_zephyr_unbind(struct dai_data *dd, struct comp_dev *dev, void *data) { - struct comp_buffer __sparse_cache *local_buf_c; struct ipc4_module_bind_unbind *bu; int buf_id; @@ -1799,12 +1721,10 @@ int dai_zephyr_unbind(struct dai_data *dd, struct comp_dev *dev, void *data) buf_id = IPC4_COMP_ID(bu->extension.r.src_queue, bu->extension.r.dst_queue); if (dd && dd->local_buffer) { - local_buf_c = buffer_acquire(dd->local_buffer); - if (local_buf_c->id == buf_id) { + if (dd->local_buffer->id == buf_id) { comp_dbg(dev, "dai_zephyr_unbind: local_buffer %x unbound", buf_id); dd->local_buffer = NULL; } - buffer_release(local_buf_c); } return 0; diff --git a/src/audio/dcblock/dcblock.c b/src/audio/dcblock/dcblock.c index 956181149900..8e52820341ba 100644 --- a/src/audio/dcblock/dcblock.c +++ b/src/audio/dcblock/dcblock.c @@ -194,8 +194,8 @@ static int dcblock_process(struct processing_module *mod, int num_output_buffers) { struct comp_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = input_buffers[0].data; - struct audio_stream __sparse_cache *sink = output_buffers[0].data; + struct audio_stream *source = input_buffers[0].data; + struct audio_stream *sink = output_buffers[0].data; uint32_t frames = input_buffers[0].size; comp_dbg(mod->dev, "dcblock_process()"); @@ -207,8 +207,8 @@ static int dcblock_process(struct processing_module *mod, } /* init and calculate the aligned setting for available frames and free frames retrieve*/ -static inline void dcblock_set_frame_alignment(struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink) +static inline void dcblock_set_frame_alignment(struct audio_stream *source, + struct audio_stream *sink) { const uint32_t byte_align = 1; const uint32_t frame_align_req = 1; @@ -221,7 +221,6 @@ static inline void dcblock_set_frame_alignment(struct audio_stream __sparse_cach static void dcblock_params(struct processing_module *mod) { struct sof_ipc_stream_params *params = mod->stream_params; - struct comp_buffer __sparse_cache *sink_c, *source_c; struct comp_buffer *sinkb, *sourceb; struct comp_dev *dev = mod->dev; @@ -231,14 +230,10 @@ static void dcblock_params(struct processing_module *mod) component_set_nearest_period_frames(dev, params->rate); sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sinkb); - ipc4_update_buffer_format(sink_c, &mod->priv.cfg.base_cfg.audio_fmt); - buffer_release(sink_c); + ipc4_update_buffer_format(sinkb, &mod->priv.cfg.base_cfg.audio_fmt); sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - source_c = buffer_acquire(sourceb); - ipc4_update_buffer_format(source_c, &mod->priv.cfg.base_cfg.audio_fmt); - buffer_release(source_c); + ipc4_update_buffer_format(sourceb, &mod->priv.cfg.base_cfg.audio_fmt); } #endif /* CONFIG_IPC_MAJOR_4 */ @@ -248,12 +243,11 @@ static void dcblock_params(struct processing_module *mod) * \return Error code. */ static int dcblock_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct comp_data *cd = module_get_private_data(mod); struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; struct comp_dev *dev = mod->dev; comp_info(dev, "dcblock_prepare()"); @@ -266,18 +260,13 @@ static int dcblock_prepare(struct processing_module *mod, sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - /* get source data format */ - cd->source_format = audio_stream_get_frm_fmt(&source_c->stream); + cd->source_format = audio_stream_get_frm_fmt(&sourceb->stream); /* get sink data format and period bytes */ - cd->sink_format = audio_stream_get_frm_fmt(&sink_c->stream); + cd->sink_format = audio_stream_get_frm_fmt(&sinkb->stream); - dcblock_set_frame_alignment(&source_c->stream, &sink_c->stream); - buffer_release(sink_c); - buffer_release(source_c); + dcblock_set_frame_alignment(&sourceb->stream, &sinkb->stream); dcblock_init_state(cd); cd->dcblock_func = dcblock_find_func(cd->source_format); @@ -316,8 +305,8 @@ static int dcblock_reset(struct processing_module *mod) return 0; } -static struct module_interface dcblock_interface = { - .init = dcblock_init, +static const struct module_interface dcblock_interface = { + .init = dcblock_init, .prepare = dcblock_prepare, .process_audio_stream = dcblock_process, .set_configuration = dcblock_set_config, diff --git a/src/audio/dcblock/dcblock_generic.c b/src/audio/dcblock/dcblock_generic.c index 3fb6b476d5e6..459d51993f09 100644 --- a/src/audio/dcblock/dcblock_generic.c +++ b/src/audio/dcblock/dcblock_generic.c @@ -36,8 +36,8 @@ static int32_t dcblock_generic(struct dcblock_state *state, #if CONFIG_FORMAT_S16LE static void dcblock_s16_default(struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + const struct audio_stream *sink, uint32_t frames) { struct dcblock_state *state; @@ -76,8 +76,8 @@ static void dcblock_s16_default(struct comp_data *cd, #if CONFIG_FORMAT_S24LE static void dcblock_s24_default(struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + const struct audio_stream *sink, uint32_t frames) { struct dcblock_state *state; @@ -116,8 +116,8 @@ static void dcblock_s24_default(struct comp_data *cd, #if CONFIG_FORMAT_S32LE static void dcblock_s32_default(struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + const struct audio_stream *sink, uint32_t frames) { struct dcblock_state *state; diff --git a/src/audio/dcblock/dcblock_hifi3.c b/src/audio/dcblock/dcblock_hifi3.c index e8ef80032bb6..30d8aa4d32a8 100644 --- a/src/audio/dcblock/dcblock_hifi3.c +++ b/src/audio/dcblock/dcblock_hifi3.c @@ -29,7 +29,7 @@ static inline ae_int32x2 dcblock_cal(ae_int32x2 R, ae_int32x2 state_x, ae_int32 } /* Setup circular for component source */ -static inline void dcblock_set_circular(const struct audio_stream __sparse_cache *source) +static inline void dcblock_set_circular(const struct audio_stream *source) { /* Set source as circular buffer 0 */ AE_SETCBEGIN0(audio_stream_get_addr(source)); @@ -38,8 +38,8 @@ static inline void dcblock_set_circular(const struct audio_stream __sparse_cache #if CONFIG_FORMAT_S16LE static void dcblock_s16_default(struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + const struct audio_stream *sink, uint32_t frames) { ae_int16 *src = audio_stream_get_rptr(source); @@ -85,8 +85,8 @@ static void dcblock_s16_default(struct comp_data *cd, #if CONFIG_FORMAT_S24LE static void dcblock_s24_default(struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + const struct audio_stream *sink, uint32_t frames) { ae_int32 *src = audio_stream_get_rptr(source); @@ -132,8 +132,8 @@ static void dcblock_s24_default(struct comp_data *cd, #if CONFIG_FORMAT_S32LE static void dcblock_s32_default(struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + const struct audio_stream *sink, uint32_t frames) { ae_int32 *src = audio_stream_get_rptr(source); diff --git a/src/audio/dcblock/dcblock_hifi4.c b/src/audio/dcblock/dcblock_hifi4.c index b537b3dce7b0..98d8edf6345e 100644 --- a/src/audio/dcblock/dcblock_hifi4.c +++ b/src/audio/dcblock/dcblock_hifi4.c @@ -29,8 +29,8 @@ static inline ae_int32x2 dcblock_cal(ae_int32x2 R, ae_int32x2 state_x, ae_int32 } /* Setup circular for component sink and source */ -static inline void dcblock_set_circular(const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink) +static inline void dcblock_set_circular(const struct audio_stream *source, + const struct audio_stream *sink) { /* Set source as circular buffer 0 */ AE_SETCBEGIN0(audio_stream_get_addr(source)); @@ -43,8 +43,8 @@ static inline void dcblock_set_circular(const struct audio_stream __sparse_cache #if CONFIG_FORMAT_S16LE static void dcblock_s16_default(struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + const struct audio_stream *sink, uint32_t frames) { ae_int16 *in; @@ -80,8 +80,8 @@ static void dcblock_s16_default(struct comp_data *cd, #if CONFIG_FORMAT_S24LE static void dcblock_s24_default(struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + const struct audio_stream *sink, uint32_t frames) { ae_int32 *in; @@ -118,8 +118,8 @@ static void dcblock_s24_default(struct comp_data *cd, #if CONFIG_FORMAT_S32LE static void dcblock_s32_default(struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + const struct audio_stream *sink, uint32_t frames) { ae_int32 *in; diff --git a/src/audio/dp_queue.c b/src/audio/dp_queue.c new file mode 100644 index 000000000000..8001594a27bc --- /dev/null +++ b/src/audio/dp_queue.c @@ -0,0 +1,299 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. +// + +#include +#include +#include + +#include + +#include +#include + +LOG_MODULE_REGISTER(dp_queue, CONFIG_SOF_LOG_LEVEL); + +/* 393608d8-4188-11ee-be56-0242ac120002 */ +DECLARE_SOF_RT_UUID("dp_queue", dp_queue_uuid, 0x393608d8, 0x4188, 0x11ee, + 0xbe, 0x56, 0x02, 0x42, 0xac, 0x12, 0x20, 0x02); +DECLARE_TR_CTX(dp_queue_tr, SOF_UUID(dp_queue_uuid), LOG_LEVEL_INFO); + +static inline uint8_t __sparse_cache *dp_queue_buffer_end(struct dp_queue *dp_queue) +{ + return dp_queue->_data_buffer + dp_queue->data_buffer_size; +} + +static inline struct dp_queue *dp_queue_from_sink(struct sof_sink *sink) +{ + return container_of(sink, struct dp_queue, _sink_api); +} + +static inline struct dp_queue *dp_queue_from_source(struct sof_source *source) +{ + return container_of(source, struct dp_queue, _source_api); +} + +static inline void dp_queue_invalidate_shared(struct dp_queue *dp_queue, + void __sparse_cache *ptr, size_t size) +{ + /* no cache required in case of not shared queue */ + if (!dp_queue_is_shared(dp_queue)) + return; + + /* wrap-around? */ + if ((uintptr_t)ptr + size > (uintptr_t)dp_queue_buffer_end(dp_queue)) { + /* writeback till the end of circular buffer */ + dcache_invalidate_region + (ptr, (uintptr_t)dp_queue_buffer_end(dp_queue) - (uintptr_t)ptr); + size -= (uintptr_t)dp_queue_buffer_end(dp_queue) - (uintptr_t)ptr; + ptr = dp_queue->_data_buffer; + } + /* invalidate rest of data */ + dcache_invalidate_region(ptr, size); +} + +static inline void dp_queue_writeback_shared(struct dp_queue *dp_queue, + void __sparse_cache *ptr, size_t size) +{ + /* no cache required in case of not shared queue */ + if (!dp_queue_is_shared(dp_queue)) + return; + + /* wrap-around? */ + if ((uintptr_t)ptr + size > (uintptr_t)dp_queue_buffer_end(dp_queue)) { + /* writeback till the end of circular buffer */ + dcache_writeback_region + (ptr, (uintptr_t)dp_queue_buffer_end(dp_queue) - (uintptr_t)ptr); + size -= (uintptr_t)dp_queue_buffer_end(dp_queue) - (uintptr_t)ptr; + ptr = dp_queue->_data_buffer; + } + /* writeback rest of data */ + dcache_writeback_region(ptr, size); +} + +static inline +uint8_t __sparse_cache *dp_queue_get_pointer(struct dp_queue *dp_queue, size_t offset) +{ + /* check if offset is not in "double area" + * lines below do a quicker version of offset %= dp_queue->data_buffer_size; + */ + if (offset >= dp_queue->data_buffer_size) + offset -= dp_queue->data_buffer_size; + return dp_queue->_data_buffer + offset; +} + +static inline +size_t dp_queue_inc_offset(struct dp_queue *dp_queue, size_t offset, size_t inc) +{ + assert(inc <= dp_queue->data_buffer_size); + offset += inc; + /* wrap around ? 2*size because of "double area" */ + if (offset >= 2 * dp_queue->data_buffer_size) + offset -= 2 * dp_queue->data_buffer_size; + return offset; +} + +static inline +size_t _dp_queue_get_data_available(struct dp_queue *dp_queue) +{ + int32_t avail_data = dp_queue->_write_offset - dp_queue->_read_offset; + /* wrap around ? 2*size because of "double area" */ + if (avail_data < 0) + avail_data = 2 * dp_queue->data_buffer_size + avail_data; + + return avail_data; +} + +static size_t dp_queue_get_data_available(struct sof_source *source) +{ + struct dp_queue *dp_queue = dp_queue_from_source(source); + + CORE_CHECK_STRUCT(dp_queue); + return _dp_queue_get_data_available(dp_queue); +} + +static size_t dp_queue_get_free_size(struct sof_sink *sink) +{ + struct dp_queue *dp_queue = dp_queue_from_sink(sink); + + CORE_CHECK_STRUCT(dp_queue); + return dp_queue->data_buffer_size - _dp_queue_get_data_available(dp_queue); +} + +static int dp_queue_get_buffer(struct sof_sink *sink, size_t req_size, + void **data_ptr, void **buffer_start, size_t *buffer_size) +{ + struct dp_queue *dp_queue = dp_queue_from_sink(sink); + + CORE_CHECK_STRUCT(dp_queue); + if (req_size > dp_queue_get_free_size(sink)) + return -ENODATA; + + /* note, __sparse_force is to be removed once sink/src use __sparse_cache for data ptrs */ + *data_ptr = (__sparse_force void *)dp_queue_get_pointer(dp_queue, dp_queue->_write_offset); + *buffer_start = (__sparse_force void *)dp_queue->_data_buffer; + *buffer_size = dp_queue->data_buffer_size; + + /* no need to invalidate cache - buffer is to be written only */ + return 0; +} + +static int dp_queue_commit_buffer(struct sof_sink *sink, size_t commit_size) +{ + struct dp_queue *dp_queue = dp_queue_from_sink(sink); + + CORE_CHECK_STRUCT(dp_queue); + if (commit_size) { + dp_queue_writeback_shared(dp_queue, + dp_queue_get_pointer(dp_queue, dp_queue->_write_offset), + commit_size); + + /* move write pointer */ + dp_queue->_write_offset = + dp_queue_inc_offset(dp_queue, dp_queue->_write_offset, commit_size); + } + + return 0; +} + +static int dp_queue_get_data(struct sof_source *source, size_t req_size, + void const **data_ptr, void const **buffer_start, size_t *buffer_size) +{ + struct dp_queue *dp_queue = dp_queue_from_source(source); + __sparse_cache void *data_ptr_c; + + CORE_CHECK_STRUCT(dp_queue); + if (req_size > dp_queue_get_data_available(source)) + return -ENODATA; + + data_ptr_c = dp_queue_get_pointer(dp_queue, dp_queue->_read_offset); + + /* clean cache in provided data range */ + dp_queue_invalidate_shared(dp_queue, data_ptr_c, req_size); + + *buffer_start = (__sparse_force void *)dp_queue->_data_buffer; + *buffer_size = dp_queue->data_buffer_size; + *data_ptr = (__sparse_force void *)data_ptr_c; + + return 0; +} + +static int dp_queue_release_data(struct sof_source *source, size_t free_size) +{ + struct dp_queue *dp_queue = dp_queue_from_source(source); + + CORE_CHECK_STRUCT(dp_queue); + if (free_size) { + /* data consumed, free buffer space, no need for any special cache operations */ + dp_queue->_read_offset = + dp_queue_inc_offset(dp_queue, dp_queue->_read_offset, free_size); + } + + return 0; +} + +static int dp_queue_set_ipc_params(struct dp_queue *dp_queue, + struct sof_ipc_stream_params *params, + bool force_update) +{ + CORE_CHECK_STRUCT(dp_queue); + if (dp_queue->_hw_params_configured && !force_update) + return 0; + + dp_queue->audio_stream_params.frame_fmt = params->frame_fmt; + dp_queue->audio_stream_params.rate = params->rate; + dp_queue->audio_stream_params.channels = params->channels; + dp_queue->audio_stream_params.buffer_fmt = params->buffer_fmt; + + dp_queue->_hw_params_configured = true; + + return 0; +} + +static int dp_queue_set_ipc_params_source(struct sof_source *source, + struct sof_ipc_stream_params *params, + bool force_update) +{ + struct dp_queue *dp_queue = dp_queue_from_source(source); + + CORE_CHECK_STRUCT(dp_queue); + return dp_queue_set_ipc_params(dp_queue, params, force_update); +} + +static int dp_queue_set_ipc_params_sink(struct sof_sink *sink, + struct sof_ipc_stream_params *params, + bool force_update) +{ + struct dp_queue *dp_queue = dp_queue_from_sink(sink); + + CORE_CHECK_STRUCT(dp_queue); + return dp_queue_set_ipc_params(dp_queue, params, force_update); +} + +static const struct source_ops dp_queue_source_ops = { + .get_data_available = dp_queue_get_data_available, + .get_data = dp_queue_get_data, + .release_data = dp_queue_release_data, + .audio_set_ipc_params = dp_queue_set_ipc_params_source, +}; + +static const struct sink_ops dp_queue_sink_ops = { + .get_free_size = dp_queue_get_free_size, + .get_buffer = dp_queue_get_buffer, + .commit_buffer = dp_queue_commit_buffer, + .audio_set_ipc_params = dp_queue_set_ipc_params_sink, +}; + +struct dp_queue *dp_queue_create(size_t min_available, size_t min_free_space, uint32_t flags) +{ + struct dp_queue *dp_queue; + + /* allocate DP structure */ + if (flags & DP_QUEUE_MODE_SHARED) + dp_queue = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, + sizeof(*dp_queue)); + else + dp_queue = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*dp_queue)); + if (!dp_queue) + return NULL; + + dp_queue->_flags = flags; + + CORE_CHECK_STRUCT_INIT(dp_queue, flags & DP_QUEUE_MODE_SHARED); + + /* initiate structures */ + source_init(dp_queue_get_source(dp_queue), &dp_queue_source_ops, + &dp_queue->audio_stream_params); + sink_init(dp_queue_get_sink(dp_queue), &dp_queue_sink_ops, + &dp_queue->audio_stream_params); + + list_init(&dp_queue->list); + + /* set obs/ibs in sink/source interfaces */ + sink_set_min_free_space(&dp_queue->_sink_api, min_free_space); + source_set_min_available(&dp_queue->_source_api, min_available); + + uint32_t max_ibs_obs = MAX(min_available, min_free_space); + + /* calculate required buffer size */ + dp_queue->data_buffer_size = 2 * max_ibs_obs; + + /* allocate data buffer - always in cached memory alias */ + dp_queue->data_buffer_size = ALIGN_UP(dp_queue->data_buffer_size, PLATFORM_DCACHE_ALIGN); + dp_queue->_data_buffer = (__sparse_force __sparse_cache void *) + rballoc_align(0, 0, dp_queue->data_buffer_size, PLATFORM_DCACHE_ALIGN); + if (!dp_queue->_data_buffer) + goto err; + + tr_info(&dp_queue_tr, "DpQueue created, shared: %u min_available: %u min_free_space %u, size %u", + dp_queue_is_shared(dp_queue), min_available, min_free_space, + dp_queue->data_buffer_size); + + /* return a pointer to allocated structure */ + return dp_queue; +err: + tr_err(&dp_queue_tr, "DpQueue creation failure"); + rfree(dp_queue); + return NULL; +} diff --git a/src/audio/drc/drc.c b/src/audio/drc/drc.c index a435e347a608..c69b3a742ea6 100644 --- a/src/audio/drc/drc.c +++ b/src/audio/drc/drc.c @@ -227,8 +227,8 @@ static int drc_get_config(struct processing_module *mod, return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); } -static void drc_set_alignment(struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink) +static void drc_set_alignment(struct audio_stream *source, + struct audio_stream *sink) { /* Currently no optimizations those would use wider loads and stores */ audio_stream_init_alignment_constants(1, 1, source); @@ -243,8 +243,8 @@ static int drc_process(struct processing_module *mod, { struct drc_comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - struct audio_stream __sparse_cache *source = input_buffers[0].data; - struct audio_stream __sparse_cache *sink = output_buffers[0].data; + struct audio_stream *source = input_buffers[0].data; + struct audio_stream *sink = output_buffers[0].data; int frames = input_buffers[0].size; int ret; @@ -272,7 +272,6 @@ static int drc_process(struct processing_module *mod, static void drc_params(struct processing_module *mod) { struct sof_ipc_stream_params *params = mod->stream_params; - struct comp_buffer __sparse_cache *sink_c, *source_c; struct comp_buffer *sinkb, *sourceb; struct comp_dev *dev = mod->dev; @@ -282,24 +281,19 @@ static void drc_params(struct processing_module *mod) component_set_nearest_period_frames(dev, params->rate); sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sinkb); - ipc4_update_buffer_format(sink_c, &mod->priv.cfg.base_cfg.audio_fmt); - buffer_release(sink_c); + ipc4_update_buffer_format(sinkb, &mod->priv.cfg.base_cfg.audio_fmt); sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - source_c = buffer_acquire(sourceb); - ipc4_update_buffer_format(source_c, &mod->priv.cfg.base_cfg.audio_fmt); - buffer_release(source_c); + ipc4_update_buffer_format(sourceb, &mod->priv.cfg.base_cfg.audio_fmt); } #endif /* CONFIG_IPC_MAJOR_4 */ static int drc_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct drc_comp_data *cd = module_get_private_data(mod); struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; struct comp_dev *dev = mod->dev; int channels; int rate; @@ -314,16 +308,12 @@ static int drc_prepare(struct processing_module *mod, /* DRC component will only ever have 1 source and 1 sink buffer */ sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - drc_set_alignment(&source_c->stream, &sink_c->stream); + drc_set_alignment(&sourceb->stream, &sinkb->stream); /* get source data format */ - cd->source_format = audio_stream_get_frm_fmt(&source_c->stream); - channels = audio_stream_get_channels(&sink_c->stream); - rate = audio_stream_get_rate(&sink_c->stream); - buffer_release(sink_c); - buffer_release(source_c); + cd->source_format = audio_stream_get_frm_fmt(&sourceb->stream); + channels = audio_stream_get_channels(&sinkb->stream); + rate = audio_stream_get_rate(&sinkb->stream); /* Initialize DRC */ comp_info(dev, "drc_prepare(), source_format=%d", cd->source_format); @@ -360,8 +350,8 @@ static int drc_reset(struct processing_module *mod) return 0; } -static struct module_interface drc_interface = { - .init = drc_init, +static const struct module_interface drc_interface = { + .init = drc_init, .prepare = drc_prepare, .process_audio_stream = drc_process, .set_configuration = drc_set_config, diff --git a/src/audio/drc/drc_generic.c b/src/audio/drc/drc_generic.c index fb7978c54cdc..472431a0e408 100644 --- a/src/audio/drc/drc_generic.c +++ b/src/audio/drc/drc_generic.c @@ -466,8 +466,8 @@ static void drc_process_one_division(struct drc_state *state, } void drc_default_pass(struct processing_module *mod, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, uint32_t frames) + const struct audio_stream *source, + struct audio_stream *sink, uint32_t frames) { audio_stream_copy(source, 0, sink, 0, frames * audio_stream_get_channels(source)); } @@ -479,8 +479,8 @@ static inline void drc_pre_delay_index_inc(int *idx, int increment) #if CONFIG_FORMAT_S16LE static void drc_delay_input_sample_s16(struct drc_state *state, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, int16_t **x, int16_t **y, int samples) { int16_t *x1; @@ -528,8 +528,8 @@ static void drc_delay_input_sample_s16(struct drc_state *state, } static void drc_s16_default(struct processing_module *mod, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, uint32_t frames) { int16_t *x = audio_stream_get_rptr(source); @@ -574,8 +574,8 @@ static void drc_s16_default(struct processing_module *mod, #if CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE static void drc_delay_input_sample_s32(struct drc_state *state, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, int32_t **x, int32_t **y, int samples) { int32_t *x1; @@ -625,8 +625,8 @@ static void drc_delay_input_sample_s32(struct drc_state *state, #if CONFIG_FORMAT_S24LE static void drc_delay_input_sample_s24(struct drc_state *state, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, int32_t **x, int32_t **y, int samples) { int32_t *x1; @@ -674,8 +674,8 @@ static void drc_delay_input_sample_s24(struct drc_state *state, } static void drc_s24_default(struct processing_module *mod, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, uint32_t frames) { int32_t *x = audio_stream_get_rptr(source); @@ -722,8 +722,8 @@ static void drc_s24_default(struct processing_module *mod, #if CONFIG_FORMAT_S32LE static void drc_s32_default(struct processing_module *mod, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, uint32_t frames) { int32_t *x = audio_stream_get_rptr(source); diff --git a/src/audio/eq_fir/eq_fir.c b/src/audio/eq_fir/eq_fir.c index 5fad4db4babf..baca41e054a4 100644 --- a/src/audio/eq_fir/eq_fir.c +++ b/src/audio/eq_fir/eq_fir.c @@ -174,7 +174,6 @@ static int eq_fir_params(struct processing_module *mod) struct sof_ipc_stream_params comp_params; struct comp_dev *dev = mod->dev; struct comp_buffer *sinkb; - struct comp_buffer __sparse_cache *sink_c; enum sof_ipc_frame valid_fmt, frame_fmt; int i, ret; @@ -197,9 +196,7 @@ static int eq_fir_params(struct processing_module *mod) component_set_nearest_period_frames(dev, comp_params.rate); sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sinkb); - ret = buffer_set_params(sink_c, &comp_params, true); - buffer_release(sink_c); + ret = buffer_set_params(sinkb, &comp_params, true); return ret; } #endif /* CONFIG_IPC_MAJOR_4 */ @@ -213,8 +210,8 @@ static void eq_fir_passthrough(struct fir_state_32x16 fir[], struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; audio_stream_copy(source, 0, sink, 0, frames * audio_stream_get_channels(source)); } @@ -512,7 +509,7 @@ static int eq_fir_process(struct processing_module *mod, int num_output_buffers) { struct comp_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = input_buffers[0].data; + struct audio_stream *source = input_buffers[0].data; uint32_t frame_count = input_buffers[0].size; int ret; @@ -554,8 +551,8 @@ static int eq_fir_process(struct processing_module *mod, return 0; } -static void eq_fir_set_alignment(struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink) +static void eq_fir_set_alignment(struct audio_stream *source, + struct audio_stream *sink) { const uint32_t byte_align = 1; const uint32_t frame_align_req = 2; /* Process multiples of 2 frames */ @@ -565,12 +562,11 @@ static void eq_fir_set_alignment(struct audio_stream __sparse_cache *source, } static int eq_fir_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct comp_data *cd = module_get_private_data(mod); struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; struct comp_dev *dev = mod->dev; int channels; enum sof_ipc_frame frame_fmt; @@ -589,13 +585,9 @@ static int eq_fir_prepare(struct processing_module *mod, /* EQ component will only ever have 1 source and 1 sink buffer. */ sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - eq_fir_set_alignment(&source_c->stream, &sink_c->stream); - channels = audio_stream_get_channels(&sink_c->stream); - frame_fmt = audio_stream_get_frm_fmt(&source_c->stream); - buffer_release(sink_c); - buffer_release(source_c); + eq_fir_set_alignment(&sourceb->stream, &sinkb->stream); + channels = audio_stream_get_channels(&sinkb->stream); + frame_fmt = audio_stream_get_frm_fmt(&sourceb->stream); cd->eq_fir_func = eq_fir_passthrough; cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); @@ -636,7 +628,7 @@ static int eq_fir_reset(struct processing_module *mod) return 0; } -static struct module_interface eq_fir_interface = { +static const struct module_interface eq_fir_interface = { .init = eq_fir_init, .free = eq_fir_free, .set_configuration = eq_fir_set_config, diff --git a/src/audio/eq_fir/eq_fir_generic.c b/src/audio/eq_fir/eq_fir_generic.c index ff763d325864..7edea7b21057 100644 --- a/src/audio/eq_fir/eq_fir_generic.c +++ b/src/audio/eq_fir/eq_fir_generic.c @@ -23,8 +23,8 @@ LOG_MODULE_DECLARE(eq_fir, CONFIG_SOF_LOG_LEVEL); void eq_fir_s16(struct fir_state_32x16 fir[], struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; struct fir_state_32x16 *filter; int32_t z; int16_t *x0, *y0; @@ -61,8 +61,8 @@ void eq_fir_s16(struct fir_state_32x16 fir[], struct input_stream_buffer *bsourc void eq_fir_s24(struct fir_state_32x16 fir[], struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; struct fir_state_32x16 *filter; int32_t z; int32_t *x0, *y0; @@ -99,8 +99,8 @@ void eq_fir_s24(struct fir_state_32x16 fir[], struct input_stream_buffer *bsourc void eq_fir_s32(struct fir_state_32x16 fir[], struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; struct fir_state_32x16 *filter; int32_t *x0, *y0; int32_t *x = audio_stream_get_rptr(source); diff --git a/src/audio/eq_fir/eq_fir_hifi2ep.c b/src/audio/eq_fir/eq_fir_hifi2ep.c index 29d12587ab1f..fc5ce500b9de 100644 --- a/src/audio/eq_fir/eq_fir_hifi2ep.c +++ b/src/audio/eq_fir/eq_fir_hifi2ep.c @@ -28,8 +28,8 @@ LOG_MODULE_DECLARE(eq_fir, CONFIG_SOF_LOG_LEVEL); void eq_fir_2x_s32(struct fir_state_32x16 fir[], struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; struct fir_state_32x16 *f; int32_t *src = audio_stream_get_rptr(source); int32_t *snk = audio_stream_get_wptr(sink); @@ -72,8 +72,8 @@ void eq_fir_2x_s32(struct fir_state_32x16 fir[], struct input_stream_buffer *bso void eq_fir_2x_s24(struct fir_state_32x16 fir[], struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; struct fir_state_32x16 *f; int32_t *src = audio_stream_get_rptr(source); int32_t *snk = audio_stream_get_wptr(sink); @@ -120,8 +120,8 @@ void eq_fir_2x_s24(struct fir_state_32x16 fir[], struct input_stream_buffer *bso void eq_fir_2x_s16(struct fir_state_32x16 fir[], struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; struct fir_state_32x16 *f; int16_t *src = audio_stream_get_rptr(source); int16_t *snk = audio_stream_get_wptr(sink); diff --git a/src/audio/eq_fir/eq_fir_hifi3.c b/src/audio/eq_fir/eq_fir_hifi3.c index b9b5f3b1ec63..00ce836741f5 100644 --- a/src/audio/eq_fir/eq_fir_hifi3.c +++ b/src/audio/eq_fir/eq_fir_hifi3.c @@ -27,8 +27,8 @@ LOG_MODULE_DECLARE(eq_fir, CONFIG_SOF_LOG_LEVEL); void eq_fir_2x_s32(struct fir_state_32x16 fir[], struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; struct fir_state_32x16 *f; ae_int32x2 d0 = 0; ae_int32x2 d1 = 0; @@ -84,8 +84,8 @@ void eq_fir_2x_s32(struct fir_state_32x16 fir[], struct input_stream_buffer *bso void eq_fir_2x_s24(struct fir_state_32x16 fir[], struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; struct fir_state_32x16 *f; ae_int32x2 d0 = 0; ae_int32x2 d1 = 0; @@ -156,8 +156,8 @@ void eq_fir_2x_s24(struct fir_state_32x16 fir[], struct input_stream_buffer *bso void eq_fir_2x_s16(struct fir_state_32x16 fir[], struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; struct fir_state_32x16 *f; ae_int16x4 d0 = AE_ZERO16(); ae_int16x4 d1 = AE_ZERO16(); diff --git a/src/audio/eq_iir/CMakeLists.txt b/src/audio/eq_iir/CMakeLists.txt index 498946370528..0c9853540ad5 100644 --- a/src/audio/eq_iir/CMakeLists.txt +++ b/src/audio/eq_iir/CMakeLists.txt @@ -1,3 +1,8 @@ # SPDX-License-Identifier: BSD-3-Clause -add_local_sources(sof eq_iir.c) +add_local_sources(sof eq_iir.c eq_iir_generic.c) +if(CONFIG_IPC_MAJOR_3) + add_local_sources(sof eq_iir_ipc3.c) +elseif(CONFIG_IPC_MAJOR_4) + add_local_sources(sof eq_iir_ipc4.c) +endif() diff --git a/src/audio/eq_iir/eq_iir.c b/src/audio/eq_iir/eq_iir.c index 1ff8ed6879e6..2a91a08165a2 100644 --- a/src/audio/eq_iir/eq_iir.c +++ b/src/audio/eq_iir/eq_iir.c @@ -6,11 +6,11 @@ // Liam Girdwood // Keyon Jie +#include "eq_iir.h" #include #include #include #include -#include #include #include #include @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -44,585 +43,6 @@ DECLARE_SOF_RT_UUID("eq-iir", eq_iir_uuid, 0x5150c0e6, 0x27f9, 0x4ec8, DECLARE_TR_CTX(eq_iir_tr, SOF_UUID(eq_iir_uuid), LOG_LEVEL_INFO); -/* IIR component private data */ -struct comp_data { - struct iir_state_df1 iir[PLATFORM_MAX_CHANNELS]; /**< filters state */ - struct comp_data_blob_handler *model_handler; - struct sof_eq_iir_config *config; - int32_t *iir_delay; /**< pointer to allocated RAM */ - size_t iir_delay_size; /**< allocated size */ - eq_iir_func eq_iir_func; /**< processing function */ -}; - -#if CONFIG_FORMAT_S16LE - -/* - * EQ IIR algorithm code - */ - -static void eq_iir_s16_default(struct processing_module *mod, struct input_stream_buffer *bsource, - struct output_stream_buffer *bsink, uint32_t frames) -{ - struct comp_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; - struct iir_state_df1 *filter; - int16_t *x0; - int16_t *y0; - int16_t *x; - int16_t *y; - int nmax; - int n1; - int n2; - int i; - int j; - int n; - const int nch = audio_stream_get_channels(source); - const int samples = frames * nch; - int processed = 0; - - x = audio_stream_get_rptr(source); - y = audio_stream_get_wptr(sink); - while (processed < samples) { - nmax = samples - processed; - n1 = audio_stream_bytes_without_wrap(source, x) >> 1; - n2 = audio_stream_bytes_without_wrap(sink, y) >> 1; - n = MIN(n1, n2); - n = MIN(n, nmax); - for (i = 0; i < nch; i++) { - x0 = x + i; - y0 = y + i; - filter = &cd->iir[i]; - for (j = 0; j < n; j += nch) { - *y0 = iir_df1_s16(filter, *x0); - x0 += nch; - y0 += nch; - } - } - processed += n; - x = audio_stream_wrap(source, x + n); - y = audio_stream_wrap(sink, y + n); - } -} -#endif /* CONFIG_FORMAT_S16LE */ - -#if CONFIG_FORMAT_S24LE - -static void eq_iir_s24_default(struct processing_module *mod, struct input_stream_buffer *bsource, - struct output_stream_buffer *bsink, uint32_t frames) -{ - struct comp_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; - struct iir_state_df1 *filter; - int32_t *x0; - int32_t *y0; - int32_t *x; - int32_t *y; - int nmax; - int n1; - int n2; - int i; - int j; - int n; - const int nch = audio_stream_get_channels(source); - const int samples = frames * nch; - int processed = 0; - - x = audio_stream_get_rptr(source); - y = audio_stream_get_wptr(sink); - while (processed < samples) { - nmax = samples - processed; - n1 = audio_stream_bytes_without_wrap(source, x) >> 2; - n2 = audio_stream_bytes_without_wrap(sink, y) >> 2; - n = MIN(n1, n2); - n = MIN(n, nmax); - for (i = 0; i < nch; i++) { - x0 = x + i; - y0 = y + i; - filter = &cd->iir[i]; - for (j = 0; j < n; j += nch) { - *y0 = iir_df1_s24(filter, *x0); - x0 += nch; - y0 += nch; - } - } - processed += n; - x = audio_stream_wrap(source, x + n); - y = audio_stream_wrap(sink, y + n); - } -} -#endif /* CONFIG_FORMAT_S24LE */ - -#if CONFIG_FORMAT_S32LE - -static void eq_iir_s32_default(struct processing_module *mod, struct input_stream_buffer *bsource, - struct output_stream_buffer *bsink, uint32_t frames) -{ - struct comp_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; - struct iir_state_df1 *filter; - int32_t *x0; - int32_t *y0; - int32_t *x; - int32_t *y; - int nmax; - int n1; - int n2; - int i; - int j; - int n; - const int nch = audio_stream_get_channels(source); - const int samples = frames * nch; - int processed = 0; - - x = audio_stream_get_rptr(source); - y = audio_stream_get_wptr(sink); - while (processed < samples) { - nmax = samples - processed; - n1 = audio_stream_bytes_without_wrap(source, x) >> 2; - n2 = audio_stream_bytes_without_wrap(sink, y) >> 2; - n = MIN(n1, n2); - n = MIN(n, nmax); - for (i = 0; i < nch; i++) { - x0 = x + i; - y0 = y + i; - filter = &cd->iir[i]; - for (j = 0; j < n; j += nch) { - *y0 = iir_df1(filter, *x0); - x0 += nch; - y0 += nch; - } - } - processed += n; - x = audio_stream_wrap(source, x + n); - y = audio_stream_wrap(sink, y + n); - } -} -#endif /* CONFIG_FORMAT_S32LE */ - -#if CONFIG_IPC_MAJOR_3 -#if CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S16LE -static void eq_iir_s32_16_default(struct processing_module *mod, - struct input_stream_buffer *bsource, - struct output_stream_buffer *bsink, uint32_t frames) -{ - struct comp_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; - struct iir_state_df1 *filter; - int32_t *x0; - int16_t *y0; - int32_t *x; - int16_t *y; - int nmax; - int n1; - int n2; - int i; - int j; - int n; - const int nch = audio_stream_get_channels(source); - const int samples = frames * nch; - int processed = 0; - - x = audio_stream_get_rptr(source); - y = audio_stream_get_wptr(sink); - while (processed < samples) { - nmax = samples - processed; - n1 = audio_stream_bytes_without_wrap(source, x) >> 2; /* divide 4 */ - n2 = audio_stream_bytes_without_wrap(sink, y) >> 1; /* divide 2 */ - n = MIN(n1, n2); - n = MIN(n, nmax); - for (i = 0; i < nch; i++) { - x0 = x + i; - y0 = y + i; - filter = &cd->iir[i]; - for (j = 0; j < n; j += nch) { - *y0 = iir_df1_s32_s16(filter, *x0); - x0 += nch; - y0 += nch; - } - } - processed += n; - x = audio_stream_wrap(source, x + n); - y = audio_stream_wrap(sink, y + n); - } -} -#endif /* CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S16LE */ - -#if CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S24LE -static void eq_iir_s32_24_default(struct processing_module *mod, - struct input_stream_buffer *bsource, - struct output_stream_buffer *bsink, uint32_t frames) -{ - struct comp_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; - struct iir_state_df1 *filter; - int32_t *x0; - int32_t *y0; - int32_t *x; - int32_t *y; - int nmax; - int n1; - int n2; - int i; - int j; - int n; - const int nch = audio_stream_get_channels(source); - const int samples = frames * nch; - int processed = 0; - - x = audio_stream_get_rptr(source); - y = audio_stream_get_wptr(sink); - while (processed < samples) { - nmax = samples - processed; - n1 = audio_stream_bytes_without_wrap(source, x) >> 2; - n2 = audio_stream_bytes_without_wrap(sink, y) >> 2; - n = MIN(n1, n2); - n = MIN(n, nmax); - for (i = 0; i < nch; i++) { - x0 = x + i; - y0 = y + i; - filter = &cd->iir[i]; - for (j = 0; j < n; j += nch) { - *y0 = iir_df1_s32_s24(filter, *x0); - x0 += nch; - y0 += nch; - } - } - processed += n; - x = audio_stream_wrap(source, x + n); - y = audio_stream_wrap(sink, y + n); - } -} -#endif /* CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S24LE */ -#endif /* CONFIG_IPC_MAJOR_3 */ - -static void eq_iir_pass(struct processing_module *mod, struct input_stream_buffer *bsource, - struct output_stream_buffer *bsink, uint32_t frames) -{ - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; - - audio_stream_copy(source, 0, sink, 0, frames * audio_stream_get_channels(source)); -} - -#if CONFIG_IPC_MAJOR_3 -#if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE -static void eq_iir_s32_s16_pass(struct processing_module *mod, struct input_stream_buffer *bsource, - struct output_stream_buffer *bsink, uint32_t frames) -{ - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; - int32_t *x = audio_stream_get_rptr(source); - int16_t *y = audio_stream_get_wptr(sink); - int nmax; - int n; - int i; - int remaining_samples = frames * audio_stream_get_channels(source); - - while (remaining_samples) { - nmax = EQ_IIR_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); - n = MIN(remaining_samples, nmax); - nmax = EQ_IIR_BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); - n = MIN(n, nmax); - for (i = 0; i < n; i++) { - *y = sat_int16(Q_SHIFT_RND(*x, 31, 15)); - x++; - y++; - } - remaining_samples -= n; - x = audio_stream_wrap(source, x); - y = audio_stream_wrap(sink, y); - } -} -#endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE */ - -#if CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE -static void eq_iir_s32_s24_pass(struct processing_module *mod, struct input_stream_buffer *bsource, - struct output_stream_buffer *bsink, uint32_t frames) -{ - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; - int32_t *x = audio_stream_get_rptr(source); - int32_t *y = audio_stream_get_wptr(sink); - int nmax; - int n; - int i; - int remaining_samples = frames * audio_stream_get_channels(source); - - while (remaining_samples) { - nmax = EQ_IIR_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); - n = MIN(remaining_samples, nmax); - nmax = EQ_IIR_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); - n = MIN(n, nmax); - for (i = 0; i < n; i++) { - *y = sat_int24(Q_SHIFT_RND(*x, 31, 23)); - x++; - y++; - } - remaining_samples -= n; - x = audio_stream_wrap(source, x); - y = audio_stream_wrap(sink, y); - } -} -#endif /* CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE */ -#endif /* CONFIG_IPC_MAJOR_3 */ - -#if CONFIG_IPC_MAJOR_3 -const struct eq_iir_func_map fm_configured[] = { -#if CONFIG_FORMAT_S16LE - {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, eq_iir_s16_default}, -#endif /* CONFIG_FORMAT_S16LE */ -#if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S24LE - {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S24_4LE, NULL}, - {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE, NULL}, - -#endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S24LE */ -#if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE - {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, NULL}, - {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, eq_iir_s32_16_default}, -#endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE */ -#if CONFIG_FORMAT_S24LE - {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_4LE, eq_iir_s24_default}, -#endif /* CONFIG_FORMAT_S24LE */ -#if CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE - {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, NULL}, - {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, eq_iir_s32_24_default}, -#endif /* CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE */ -#if CONFIG_FORMAT_S32LE - {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, eq_iir_s32_default}, -#endif /* CONFIG_FORMAT_S32LE */ -}; - -const struct eq_iir_func_map fm_passthrough[] = { -#if CONFIG_FORMAT_S16LE - {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, eq_iir_pass}, -#endif /* CONFIG_FORMAT_S16LE */ -#if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S24LE - {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S24_4LE, NULL}, - {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE, NULL}, - -#endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S24LE*/ -#if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE - {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, NULL}, - {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, eq_iir_s32_s16_pass}, -#endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE*/ -#if CONFIG_FORMAT_S24LE - {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_4LE, eq_iir_pass}, -#endif /* CONFIG_FORMAT_S24LE */ -#if CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE - {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, NULL}, - {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, eq_iir_s32_s24_pass}, -#endif /* CONFIG_FORMAT_S24LE */ -#if CONFIG_FORMAT_S32LE - {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, eq_iir_pass}, -#endif /* CONFIG_FORMAT_S32LE */ -}; - -static eq_iir_func eq_iir_find_func(enum sof_ipc_frame source_format, - enum sof_ipc_frame sink_format, - const struct eq_iir_func_map *map, - int n) -{ - int i; - - /* Find suitable processing function from map. */ - for (i = 0; i < n; i++) { - if ((uint8_t)source_format != map[i].source) - continue; - if ((uint8_t)sink_format != map[i].sink) - continue; - - return map[i].func; - } - - return NULL; -} - -#elif CONFIG_IPC_MAJOR_4 - -static eq_iir_func eq_iir_find_func(struct processing_module *mod) -{ - unsigned int valid_bit_depth = mod->priv.cfg.base_cfg.audio_fmt.valid_bit_depth; - - comp_dbg(mod->dev, "eq_iir_find_func(): valid_bit_depth %d", valid_bit_depth); - switch (valid_bit_depth) { -#if CONFIG_FORMAT_S16LE - case IPC4_DEPTH_16BIT: - return eq_iir_s16_default; -#endif /* CONFIG_FORMAT_S16LE */ -#if CONFIG_FORMAT_S24LE - case IPC4_DEPTH_24BIT: - return eq_iir_s24_default; -#endif /* CONFIG_FORMAT_S24LE */ -#if CONFIG_FORMAT_S32LE - case IPC4_DEPTH_32BIT: - return eq_iir_s32_default; -#endif /* CONFIG_FORMAT_S32LE */ - default: - comp_err(mod->dev, "set_fir_func(), invalid valid_bith_depth"); - } - return NULL; -} -#endif /* CONFIG_IPC_MAJOR_4 */ - -static void eq_iir_free_delaylines(struct comp_data *cd) -{ - struct iir_state_df1 *iir = cd->iir; - int i = 0; - - /* Free the common buffer for all EQs and point then - * each IIR channel delay line to NULL. - */ - rfree(cd->iir_delay); - cd->iir_delay = NULL; - cd->iir_delay_size = 0; - for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) - iir[i].delay = NULL; -} - -static int eq_iir_init_coef(struct processing_module *mod, int nch) -{ - struct comp_data *cd = module_get_private_data(mod); - struct sof_eq_iir_config *config = cd->config; - struct iir_state_df1 *iir = cd->iir; - struct sof_eq_iir_header *lookup[SOF_EQ_IIR_MAX_RESPONSES]; - struct sof_eq_iir_header *eq; - int32_t *assign_response; - int32_t *coef_data; - int size_sum = 0; - int resp = 0; - int i; - int j; - int s; - - comp_info(mod->dev, "eq_iir_init_coef(): %u responses, %u channels, stream %d channels", - config->number_of_responses, config->channels_in_config, nch); - - /* Sanity checks */ - if (nch > PLATFORM_MAX_CHANNELS || - config->channels_in_config > PLATFORM_MAX_CHANNELS || - !config->channels_in_config) { - comp_err(mod->dev, "eq_iir_init_coef(), invalid channels count"); - return -EINVAL; - } - if (config->number_of_responses > SOF_EQ_IIR_MAX_RESPONSES) { - comp_err(mod->dev, "eq_iir_init_coef(), # of resp exceeds max"); - return -EINVAL; - } - - /* Collect index of response start positions in all_coefficients[] */ - j = 0; - assign_response = ASSUME_ALIGNED(&config->data[0], 4); - coef_data = ASSUME_ALIGNED(&config->data[config->channels_in_config], - 4); - for (i = 0; i < SOF_EQ_IIR_MAX_RESPONSES; i++) { - if (i < config->number_of_responses) { - eq = (struct sof_eq_iir_header *)&coef_data[j]; - lookup[i] = eq; - j += SOF_EQ_IIR_NHEADER - + SOF_EQ_IIR_NBIQUAD * eq->num_sections; - } else { - lookup[i] = NULL; - } - } - - /* Initialize 1st phase */ - for (i = 0; i < nch; i++) { - /* Check for not reading past blob response to channel assign - * map. The previous channel response is assigned for any - * additional channels in the stream. It allows to use single - * channel configuration to setup multi channel equalization - * with the same response. - */ - if (i < config->channels_in_config) - resp = assign_response[i]; - - if (resp < 0) { - /* Initialize EQ channel to bypass and continue with - * next channel response. - */ - comp_info(mod->dev, "eq_iir_init_coef(), ch %d is set to bypass", i); - iir_reset_df1(&iir[i]); - continue; - } - - if (resp >= config->number_of_responses) { - comp_err(mod->dev, "eq_iir_init_coef(), requested response %d exceeds defined", - resp); - return -EINVAL; - } - - /* Initialize EQ coefficients */ - eq = lookup[resp]; - s = iir_delay_size_df1(eq); - if (s > 0) { - size_sum += s; - } else { - comp_err(mod->dev, "eq_iir_init_coef(), sections count %d exceeds max", - eq->num_sections); - return -EINVAL; - } - - iir_init_coef_df1(&iir[i], eq); - comp_info(mod->dev, "eq_iir_init_coef(), ch %d is set to response %d", i, resp); - } - - return size_sum; -} - -static void eq_iir_init_delay(struct iir_state_df1 *iir, - int32_t *delay_start, int nch) -{ - int32_t *delay = delay_start; - int i; - - /* Initialize second phase to set EQ delay lines pointers. A - * bypass mode filter is indicated by biquads count of zero. - */ - for (i = 0; i < nch; i++) { - if (iir[i].biquads > 0) - iir_init_delay_df1(&iir[i], &delay); - } -} - -static int eq_iir_setup(struct processing_module *mod, int nch) -{ - struct comp_data *cd = module_get_private_data(mod); - int delay_size; - - /* Free existing IIR channels data if it was allocated */ - eq_iir_free_delaylines(cd); - - /* Set coefficients for each channel EQ from coefficient blob */ - delay_size = eq_iir_init_coef(mod, nch); - if (delay_size < 0) - return delay_size; /* Contains error code */ - - /* If all channels were set to bypass there's no need to - * allocate delay. Just return with success. - */ - if (!delay_size) - return 0; - - /* Allocate all IIR channels data in a big chunk and clear it */ - cd->iir_delay = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, - delay_size); - if (!cd->iir_delay) { - comp_err(mod->dev, "eq_iir_setup(), delay allocation fail"); - return -ENOMEM; - } - - cd->iir_delay_size = delay_size; - - /* Assign delay line to each channel EQ */ - eq_iir_init_delay(cd->iir, cd->iir_delay, nch); - return 0; -} - /* * End of EQ setup code. Next the standard component methods. */ @@ -689,48 +109,6 @@ static int eq_iir_free(struct processing_module *mod) return 0; } -#if CONFIG_IPC_MAJOR_3 -static int eq_iir_verify_params(struct comp_dev *dev, - struct sof_ipc_stream_params *params) -{ - struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; - uint32_t buffer_flag; - int ret; - - comp_dbg(dev, "eq_iir_verify_params()"); - - /* EQ component will only ever have 1 source and 1 sink buffer */ - sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, - sink_list); - sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, - source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - - /* we check whether we can support frame_fmt conversion (whether we have - * such conversion function) due to source and sink buffer frame_fmt's. - * If not, we will overwrite sink (playback) and source (capture) with - * pcm frame_fmt and will not make any conversion (sink and source - * frame_fmt will be equal). - */ - buffer_flag = eq_iir_find_func(audio_stream_get_frm_fmt(&source_c->stream), - audio_stream_get_frm_fmt(&sink_c->stream), fm_configured, - ARRAY_SIZE(fm_configured)) ? - BUFF_PARAMS_FRAME_FMT : 0; - - buffer_release(sink_c); - buffer_release(source_c); - - ret = comp_verify_params(dev, buffer_flag, params); - if (ret < 0) { - comp_err(dev, "eq_iir_verify_params(): comp_verify_params() failed."); - return ret; - } - - return 0; -} -#endif /* CONFIG_IPC_MAJOR_3 */ /* used to pass standard and bespoke commands (with data) to component */ static int eq_iir_set_config(struct processing_module *mod, uint32_t config_id, @@ -758,44 +136,13 @@ static int eq_iir_get_config(struct processing_module *mod, return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); } -static int eq_iir_new_blob(struct processing_module *mod, struct comp_data *cd, - enum sof_ipc_frame source_format, enum sof_ipc_frame sink_format, - int channels) -{ - int ret; - - ret = eq_iir_setup(mod, channels); - if (ret < 0) { - comp_err(mod->dev, "eq_iir_new_blob(), failed IIR setup"); - return ret; - } else if (cd->iir_delay_size) { - comp_dbg(mod->dev, "eq_iir_new_blob(), active"); -#if CONFIG_IPC_MAJOR_3 - cd->eq_iir_func = eq_iir_find_func(source_format, sink_format, fm_configured, - ARRAY_SIZE(fm_configured)); -#elif CONFIG_IPC_MAJOR_4 - cd->eq_iir_func = eq_iir_find_func(mod); -#endif - } else { - comp_dbg(mod->dev, "eq_iir_new_blob(), pass-through"); -#if CONFIG_IPC_MAJOR_3 - cd->eq_iir_func = eq_iir_find_func(source_format, sink_format, fm_passthrough, - ARRAY_SIZE(fm_passthrough)); -#elif CONFIG_IPC_MAJOR_4 - cd->eq_iir_func = eq_iir_pass; -#endif - } - - return 0; -} - static int eq_iir_process(struct processing_module *mod, struct input_stream_buffer *input_buffers, int num_input_buffers, struct output_stream_buffer *output_buffers, int num_output_buffers) { struct comp_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = input_buffers[0].data; - struct audio_stream __sparse_cache *sink = output_buffers[0].data; + struct audio_stream *source = input_buffers[0].data; + struct audio_stream *sink = output_buffers[0].data; uint32_t frame_count = input_buffers[0].size; int ret; @@ -821,8 +168,8 @@ static int eq_iir_process(struct processing_module *mod, * \param[in,out] source Structure pointer of source. * \param[in,out] sink Structure pointer of sink. */ -static void eq_iir_set_alignment(struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink) +static void eq_iir_set_alignment(struct audio_stream *source, + struct audio_stream *sink) { const uint32_t byte_align = 8; const uint32_t frame_align_req = 2; @@ -831,61 +178,12 @@ static void eq_iir_set_alignment(struct audio_stream __sparse_cache *source, audio_stream_init_alignment_constants(byte_align, frame_align_req, sink); } -#if CONFIG_IPC_MAJOR_4 -static int eq_iir_params(struct processing_module *mod) -{ - struct sof_ipc_stream_params *params = mod->stream_params; - struct sof_ipc_stream_params comp_params; - struct comp_dev *dev = mod->dev; - struct comp_buffer *sinkb; - struct comp_buffer __sparse_cache *sink_c; - enum sof_ipc_frame valid_fmt, frame_fmt; - int i, ret; - - comp_dbg(dev, "eq_iir_params()"); - comp_params = *params; - comp_params.channels = mod->priv.cfg.base_cfg.audio_fmt.channels_count; - comp_params.rate = mod->priv.cfg.base_cfg.audio_fmt.sampling_frequency; - comp_params.buffer_fmt = mod->priv.cfg.base_cfg.audio_fmt.interleaving_style; - - audio_stream_fmt_conversion(mod->priv.cfg.base_cfg.audio_fmt.depth, - mod->priv.cfg.base_cfg.audio_fmt.valid_bit_depth, - &frame_fmt, &valid_fmt, - mod->priv.cfg.base_cfg.audio_fmt.s_type); - - comp_params.frame_fmt = valid_fmt; - - for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) - comp_params.chmap[i] = (mod->priv.cfg.base_cfg.audio_fmt.ch_map >> i * 4) & 0xf; - - component_set_nearest_period_frames(dev, comp_params.rate); - sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sinkb); - ret = buffer_set_params(sink_c, &comp_params, true); - buffer_release(sink_c); - return ret; -} -#endif - -static void eq_iir_set_passthrough_func(struct comp_data *cd, - enum sof_ipc_frame source_format, - enum sof_ipc_frame sink_format) -{ -#if CONFIG_IPC_MAJOR_3 - cd->eq_iir_func = eq_iir_find_func(source_format, sink_format, fm_passthrough, - ARRAY_SIZE(fm_passthrough)); -#else - cd->eq_iir_func = eq_iir_pass; -#endif -} - static int eq_iir_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct comp_data *cd = module_get_private_data(mod); struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; struct comp_dev *dev = mod->dev; enum sof_ipc_frame source_format; enum sof_ipc_frame sink_format; @@ -894,32 +192,19 @@ static int eq_iir_prepare(struct processing_module *mod, comp_dbg(dev, "eq_iir_prepare()"); -#if CONFIG_IPC_MAJOR_3 - ret = eq_iir_verify_params(dev, mod->stream_params); + ret = eq_iir_prepare_sub(mod); if (ret < 0) return ret; -#elif CONFIG_IPC_MAJOR_4 - ret = eq_iir_params(mod); - if (ret < 0) { - comp_set_state(dev, COMP_TRIGGER_RESET); - return ret; - } -#endif - /* EQ component will only ever have 1 source and 1 sink buffer */ sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - eq_iir_set_alignment(&source_c->stream, &sink_c->stream); + eq_iir_set_alignment(&sourceb->stream, &sinkb->stream); /* get source and sink data format */ - channels = audio_stream_get_channels(&sink_c->stream); - source_format = audio_stream_get_frm_fmt(&source_c->stream); - sink_format = audio_stream_get_frm_fmt(&sink_c->stream); - buffer_release(sink_c); - buffer_release(source_c); + channels = audio_stream_get_channels(&sinkb->stream); + source_format = audio_stream_get_frm_fmt(&sourceb->stream); + sink_format = audio_stream_get_frm_fmt(&sinkb->stream); cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); @@ -960,8 +245,8 @@ static int eq_iir_reset(struct processing_module *mod) return 0; } -static struct module_interface eq_iir_interface = { - .init = eq_iir_init, +static const struct module_interface eq_iir_interface = { + .init = eq_iir_init, .prepare = eq_iir_prepare, .process_audio_stream = eq_iir_process, .set_configuration = eq_iir_set_config, diff --git a/src/audio/eq_iir/eq_iir.h b/src/audio/eq_iir/eq_iir.h new file mode 100644 index 000000000000..7b6b6c247574 --- /dev/null +++ b/src/audio/eq_iir/eq_iir.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2017 Intel Corporation. All rights reserved. + * + * Author: Seppo Ingalsuo + * Liam Girdwood + * Keyon Jie + */ + +#ifndef __SOF_AUDIO_EQ_IIR_EQ_IIR_H__ +#define __SOF_AUDIO_EQ_IIR_EQ_IIR_H__ + +#include +#include +#include +#include + +/** \brief Macros to convert without division bytes count to samples count */ +#define EQ_IIR_BYTES_TO_S16_SAMPLES(b) ((b) >> 1) +#define EQ_IIR_BYTES_TO_S32_SAMPLES(b) ((b) >> 2) + +struct audio_stream; +struct comp_dev; + +/** \brief Type definition for processing function select return value. */ +typedef void (*eq_iir_func)(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames); + +/** \brief IIR EQ processing functions map item. */ +struct eq_iir_func_map { + uint8_t source; /**< source frame format */ + uint8_t sink; /**< sink frame format */ + eq_iir_func func; /**< processing function */ +}; + +/* IIR component private data */ +struct comp_data { + struct iir_state_df1 iir[PLATFORM_MAX_CHANNELS]; /**< filters state */ + struct comp_data_blob_handler *model_handler; + struct sof_eq_iir_config *config; + int32_t *iir_delay; /**< pointer to allocated RAM */ + size_t iir_delay_size; /**< allocated size */ + eq_iir_func eq_iir_func; /**< processing function */ +}; + +#ifdef UNIT_TEST +void sys_comp_module_eq_iir_interface_init(void); +#endif + +void eq_iir_s16_default(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames); + +void eq_iir_s24_default(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames); + +void eq_iir_s32_default(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames); + +int eq_iir_new_blob(struct processing_module *mod, struct comp_data *cd, + enum sof_ipc_frame source_format, enum sof_ipc_frame sink_format, + int channels); + +void eq_iir_set_passthrough_func(struct comp_data *cd, + enum sof_ipc_frame source_format, + enum sof_ipc_frame sink_format); + +int eq_iir_prepare_sub(struct processing_module *mod); + +void eq_iir_pass(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames); + +int eq_iir_setup(struct processing_module *mod, int nch); + +void eq_iir_free_delaylines(struct comp_data *cd); +#endif /* __SOF_AUDIO_EQ_IIR_EQ_IIR_H__ */ diff --git a/src/audio/eq_iir/eq_iir_generic.c b/src/audio/eq_iir/eq_iir_generic.c new file mode 100644 index 000000000000..2f891e240b10 --- /dev/null +++ b/src/audio/eq_iir/eq_iir_generic.c @@ -0,0 +1,346 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2017-2022 Intel Corporation. All rights reserved. +// +// Author: Seppo Ingalsuo +// Liam Girdwood +// Keyon Jie + +#include "eq_iir.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(eq_iir, CONFIG_SOF_LOG_LEVEL); + +#if CONFIG_FORMAT_S16LE +void eq_iir_s16_default(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) +{ + struct comp_data *cd = module_get_private_data(mod); + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; + struct iir_state_df1 *filter; + int16_t *x0; + int16_t *y0; + int16_t *x; + int16_t *y; + int nmax; + int n1; + int n2; + int i; + int j; + int n; + const int nch = audio_stream_get_channels(source); + const int samples = frames * nch; + int processed = 0; + + x = audio_stream_get_rptr(source); + y = audio_stream_get_wptr(sink); + while (processed < samples) { + nmax = samples - processed; + n1 = audio_stream_bytes_without_wrap(source, x) >> 1; + n2 = audio_stream_bytes_without_wrap(sink, y) >> 1; + n = MIN(n1, n2); + n = MIN(n, nmax); + for (i = 0; i < nch; i++) { + x0 = x + i; + y0 = y + i; + filter = &cd->iir[i]; + for (j = 0; j < n; j += nch) { + *y0 = iir_df1_s16(filter, *x0); + x0 += nch; + y0 += nch; + } + } + processed += n; + x = audio_stream_wrap(source, x + n); + y = audio_stream_wrap(sink, y + n); + } +} +#endif /* CONFIG_FORMAT_S16LE */ + +#if CONFIG_FORMAT_S24LE + +void eq_iir_s24_default(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) +{ + struct comp_data *cd = module_get_private_data(mod); + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; + struct iir_state_df1 *filter; + int32_t *x0; + int32_t *y0; + int32_t *x; + int32_t *y; + int nmax; + int n1; + int n2; + int i; + int j; + int n; + const int nch = audio_stream_get_channels(source); + const int samples = frames * nch; + int processed = 0; + + x = audio_stream_get_rptr(source); + y = audio_stream_get_wptr(sink); + while (processed < samples) { + nmax = samples - processed; + n1 = audio_stream_bytes_without_wrap(source, x) >> 2; + n2 = audio_stream_bytes_without_wrap(sink, y) >> 2; + n = MIN(n1, n2); + n = MIN(n, nmax); + for (i = 0; i < nch; i++) { + x0 = x + i; + y0 = y + i; + filter = &cd->iir[i]; + for (j = 0; j < n; j += nch) { + *y0 = iir_df1_s24(filter, *x0); + x0 += nch; + y0 += nch; + } + } + processed += n; + x = audio_stream_wrap(source, x + n); + y = audio_stream_wrap(sink, y + n); + } +} +#endif /* CONFIG_FORMAT_S24LE */ + +#if CONFIG_FORMAT_S32LE + +void eq_iir_s32_default(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) +{ + struct comp_data *cd = module_get_private_data(mod); + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; + struct iir_state_df1 *filter; + int32_t *x0; + int32_t *y0; + int32_t *x; + int32_t *y; + int nmax; + int n1; + int n2; + int i; + int j; + int n; + const int nch = audio_stream_get_channels(source); + const int samples = frames * nch; + int processed = 0; + + x = audio_stream_get_rptr(source); + y = audio_stream_get_wptr(sink); + while (processed < samples) { + nmax = samples - processed; + n1 = audio_stream_bytes_without_wrap(source, x) >> 2; + n2 = audio_stream_bytes_without_wrap(sink, y) >> 2; + n = MIN(n1, n2); + n = MIN(n, nmax); + for (i = 0; i < nch; i++) { + x0 = x + i; + y0 = y + i; + filter = &cd->iir[i]; + for (j = 0; j < n; j += nch) { + *y0 = iir_df1(filter, *x0); + x0 += nch; + y0 += nch; + } + } + processed += n; + x = audio_stream_wrap(source, x + n); + y = audio_stream_wrap(sink, y + n); + } +} +#endif /* CONFIG_FORMAT_S32LE */ + +static int eq_iir_init_coef(struct processing_module *mod, int nch) +{ + struct comp_data *cd = module_get_private_data(mod); + struct sof_eq_iir_config *config = cd->config; + struct iir_state_df1 *iir = cd->iir; + struct sof_eq_iir_header *lookup[SOF_EQ_IIR_MAX_RESPONSES]; + struct sof_eq_iir_header *eq; + int32_t *assign_response; + int32_t *coef_data; + int size_sum = 0; + int resp = 0; + int i; + int j; + int s; + + comp_info(mod->dev, "eq_iir_init_coef(): %u responses, %u channels, stream %d channels", + config->number_of_responses, config->channels_in_config, nch); + + /* Sanity checks */ + if (nch > PLATFORM_MAX_CHANNELS || + config->channels_in_config > PLATFORM_MAX_CHANNELS || + !config->channels_in_config) { + comp_err(mod->dev, "eq_iir_init_coef(), invalid channels count"); + return -EINVAL; + } + if (config->number_of_responses > SOF_EQ_IIR_MAX_RESPONSES) { + comp_err(mod->dev, "eq_iir_init_coef(), # of resp exceeds max"); + return -EINVAL; + } + + /* Collect index of response start positions in all_coefficients[] */ + j = 0; + assign_response = ASSUME_ALIGNED(&config->data[0], 4); + coef_data = ASSUME_ALIGNED(&config->data[config->channels_in_config], + 4); + for (i = 0; i < SOF_EQ_IIR_MAX_RESPONSES; i++) { + if (i < config->number_of_responses) { + eq = (struct sof_eq_iir_header *)&coef_data[j]; + lookup[i] = eq; + j += SOF_EQ_IIR_NHEADER + + SOF_EQ_IIR_NBIQUAD * eq->num_sections; + } else { + lookup[i] = NULL; + } + } + + /* Initialize 1st phase */ + for (i = 0; i < nch; i++) { + /* Check for not reading past blob response to channel assign + * map. The previous channel response is assigned for any + * additional channels in the stream. It allows to use single + * channel configuration to setup multi channel equalization + * with the same response. + */ + if (i < config->channels_in_config) + resp = assign_response[i]; + + if (resp < 0) { + /* Initialize EQ channel to bypass and continue with + * next channel response. + */ + comp_info(mod->dev, "eq_iir_init_coef(), ch %d is set to bypass", i); + iir_reset_df1(&iir[i]); + continue; + } + + if (resp >= config->number_of_responses) { + comp_err(mod->dev, "eq_iir_init_coef(), requested response %d exceeds defined", + resp); + return -EINVAL; + } + + /* Initialize EQ coefficients */ + eq = lookup[resp]; + s = iir_delay_size_df1(eq); + if (s > 0) { + size_sum += s; + } else { + comp_err(mod->dev, "eq_iir_init_coef(), sections count %d exceeds max", + eq->num_sections); + return -EINVAL; + } + + iir_init_coef_df1(&iir[i], eq); + comp_info(mod->dev, "eq_iir_init_coef(), ch %d is set to response %d", i, resp); + } + + return size_sum; +} + +static void eq_iir_init_delay(struct iir_state_df1 *iir, + int32_t *delay_start, int nch) +{ + int32_t *delay = delay_start; + int i; + + /* Initialize second phase to set EQ delay lines pointers. A + * bypass mode filter is indicated by biquads count of zero. + */ + for (i = 0; i < nch; i++) { + if (iir[i].biquads > 0) + iir_init_delay_df1(&iir[i], &delay); + } +} + +void eq_iir_free_delaylines(struct comp_data *cd) +{ + struct iir_state_df1 *iir = cd->iir; + int i = 0; + + /* Free the common buffer for all EQs and point then + * each IIR channel delay line to NULL. + */ + rfree(cd->iir_delay); + cd->iir_delay = NULL; + cd->iir_delay_size = 0; + for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) + iir[i].delay = NULL; +} + +void eq_iir_pass(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) +{ + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; + + audio_stream_copy(source, 0, sink, 0, frames * audio_stream_get_channels(source)); +} + +int eq_iir_setup(struct processing_module *mod, int nch) +{ + struct comp_data *cd = module_get_private_data(mod); + int delay_size; + + /* Free existing IIR channels data if it was allocated */ + eq_iir_free_delaylines(cd); + + /* Set coefficients for each channel EQ from coefficient blob */ + delay_size = eq_iir_init_coef(mod, nch); + if (delay_size < 0) + return delay_size; /* Contains error code */ + + /* If all channels were set to bypass there's no need to + * allocate delay. Just return with success. + */ + if (!delay_size) + return 0; + + /* Allocate all IIR channels data in a big chunk and clear it */ + cd->iir_delay = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, + delay_size); + if (!cd->iir_delay) { + comp_err(mod->dev, "eq_iir_setup(), delay allocation fail"); + return -ENOMEM; + } + + cd->iir_delay_size = delay_size; + + /* Assign delay line to each channel EQ */ + eq_iir_init_delay(cd->iir, cd->iir_delay, nch); + return 0; +} + diff --git a/src/audio/eq_iir/eq_iir_ipc3.c b/src/audio/eq_iir/eq_iir_ipc3.c new file mode 100644 index 000000000000..6958dd6b536b --- /dev/null +++ b/src/audio/eq_iir/eq_iir_ipc3.c @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2017-2022 Intel Corporation. All rights reserved. +// +// Author: Seppo Ingalsuo +// Liam Girdwood +// Keyon Jie + +#include "eq_iir.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(eq_iir, CONFIG_SOF_LOG_LEVEL); + +#if CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S16LE +static void eq_iir_s32_16_default(struct processing_module *mod, + struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) +{ + struct comp_data *cd = module_get_private_data(mod); + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; + struct iir_state_df1 *filter; + int32_t *x0; + int16_t *y0; + int32_t *x; + int16_t *y; + int nmax; + int n1; + int n2; + int i; + int j; + int n; + const int nch = audio_stream_get_channels(source); + const int samples = frames * nch; + int processed = 0; + + x = audio_stream_get_rptr(source); + y = audio_stream_get_wptr(sink); + while (processed < samples) { + nmax = samples - processed; + n1 = audio_stream_bytes_without_wrap(source, x) >> 2; /* divide 4 */ + n2 = audio_stream_bytes_without_wrap(sink, y) >> 1; /* divide 2 */ + n = MIN(n1, n2); + n = MIN(n, nmax); + for (i = 0; i < nch; i++) { + x0 = x + i; + y0 = y + i; + filter = &cd->iir[i]; + for (j = 0; j < n; j += nch) { + *y0 = iir_df1_s32_s16(filter, *x0); + x0 += nch; + y0 += nch; + } + } + processed += n; + x = audio_stream_wrap(source, x + n); + y = audio_stream_wrap(sink, y + n); + } +} +#endif /* CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S16LE */ + +#if CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S24LE +static void eq_iir_s32_24_default(struct processing_module *mod, + struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) +{ + struct comp_data *cd = module_get_private_data(mod); + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; + struct iir_state_df1 *filter; + int32_t *x0; + int32_t *y0; + int32_t *x; + int32_t *y; + int nmax; + int n1; + int n2; + int i; + int j; + int n; + const int nch = audio_stream_get_channels(source); + const int samples = frames * nch; + int processed = 0; + + x = audio_stream_get_rptr(source); + y = audio_stream_get_wptr(sink); + while (processed < samples) { + nmax = samples - processed; + n1 = audio_stream_bytes_without_wrap(source, x) >> 2; + n2 = audio_stream_bytes_without_wrap(sink, y) >> 2; + n = MIN(n1, n2); + n = MIN(n, nmax); + for (i = 0; i < nch; i++) { + x0 = x + i; + y0 = y + i; + filter = &cd->iir[i]; + for (j = 0; j < n; j += nch) { + *y0 = iir_df1_s32_s24(filter, *x0); + x0 += nch; + y0 += nch; + } + } + processed += n; + x = audio_stream_wrap(source, x + n); + y = audio_stream_wrap(sink, y + n); + } +} +#endif /* CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S24LE */ + +#if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE +static void eq_iir_s32_s16_pass(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) +{ + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; + int32_t *x = audio_stream_get_rptr(source); + int16_t *y = audio_stream_get_wptr(sink); + int nmax; + int n; + int i; + int remaining_samples = frames * audio_stream_get_channels(source); + + while (remaining_samples) { + nmax = EQ_IIR_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); + n = MIN(remaining_samples, nmax); + nmax = EQ_IIR_BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); + n = MIN(n, nmax); + for (i = 0; i < n; i++) { + *y = sat_int16(Q_SHIFT_RND(*x, 31, 15)); + x++; + y++; + } + remaining_samples -= n; + x = audio_stream_wrap(source, x); + y = audio_stream_wrap(sink, y); + } +} +#endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE */ + +#if CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE +static void eq_iir_s32_s24_pass(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) +{ + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; + int32_t *x = audio_stream_get_rptr(source); + int32_t *y = audio_stream_get_wptr(sink); + int nmax; + int n; + int i; + int remaining_samples = frames * audio_stream_get_channels(source); + + while (remaining_samples) { + nmax = EQ_IIR_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); + n = MIN(remaining_samples, nmax); + nmax = EQ_IIR_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); + n = MIN(n, nmax); + for (i = 0; i < n; i++) { + *y = sat_int24(Q_SHIFT_RND(*x, 31, 23)); + x++; + y++; + } + remaining_samples -= n; + x = audio_stream_wrap(source, x); + y = audio_stream_wrap(sink, y); + } +} +#endif /* CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE */ + +const struct eq_iir_func_map fm_configured[] = { +#if CONFIG_FORMAT_S16LE + {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, eq_iir_s16_default}, +#endif /* CONFIG_FORMAT_S16LE */ +#if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S24LE + {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S24_4LE, NULL}, + {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE, NULL}, + +#endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S24LE */ +#if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE + {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, NULL}, + {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, eq_iir_s32_16_default}, +#endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE */ +#if CONFIG_FORMAT_S24LE + {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_4LE, eq_iir_s24_default}, +#endif /* CONFIG_FORMAT_S24LE */ +#if CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE + {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, NULL}, + {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, eq_iir_s32_24_default}, +#endif /* CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE */ +#if CONFIG_FORMAT_S32LE + {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, eq_iir_s32_default}, +#endif /* CONFIG_FORMAT_S32LE */ +}; + +const struct eq_iir_func_map fm_passthrough[] = { +#if CONFIG_FORMAT_S16LE + {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, eq_iir_pass}, +#endif /* CONFIG_FORMAT_S16LE */ +#if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S24LE + {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S24_4LE, NULL}, + {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE, NULL}, + +#endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S24LE*/ +#if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE + {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, NULL}, + {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, eq_iir_s32_s16_pass}, +#endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE*/ +#if CONFIG_FORMAT_S24LE + {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_4LE, eq_iir_pass}, +#endif /* CONFIG_FORMAT_S24LE */ +#if CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE + {SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, NULL}, + {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, eq_iir_s32_s24_pass}, +#endif /* CONFIG_FORMAT_S24LE */ +#if CONFIG_FORMAT_S32LE + {SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, eq_iir_pass}, +#endif /* CONFIG_FORMAT_S32LE */ +}; + +static eq_iir_func eq_iir_find_func(enum sof_ipc_frame source_format, + enum sof_ipc_frame sink_format, + const struct eq_iir_func_map *map, + int n) +{ + int i; + + /* Find suitable processing function from map. */ + for (i = 0; i < n; i++) { + if ((uint8_t)source_format != map[i].source) + continue; + if ((uint8_t)sink_format != map[i].sink) + continue; + + return map[i].func; + } + + return NULL; +} + +static int eq_iir_verify_params(struct comp_dev *dev, + struct sof_ipc_stream_params *params) +{ + struct comp_buffer *sourceb, *sinkb; + uint32_t buffer_flag; + int ret; + + comp_dbg(dev, "eq_iir_verify_params()"); + + /* EQ component will only ever have 1 source and 1 sink buffer */ + sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, + sink_list); + sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, + source_list); + + /* we check whether we can support frame_fmt conversion (whether we have + * such conversion function) due to source and sink buffer frame_fmt's. + * If not, we will overwrite sink (playback) and source (capture) with + * pcm frame_fmt and will not make any conversion (sink and source + * frame_fmt will be equal). + */ + buffer_flag = eq_iir_find_func(audio_stream_get_frm_fmt(&sourceb->stream), + audio_stream_get_frm_fmt(&sinkb->stream), fm_configured, + ARRAY_SIZE(fm_configured)) ? + BUFF_PARAMS_FRAME_FMT : 0; + + ret = comp_verify_params(dev, buffer_flag, params); + if (ret < 0) { + comp_err(dev, "eq_iir_verify_params(): comp_verify_params() failed."); + return ret; + } + + return 0; +} + +int eq_iir_new_blob(struct processing_module *mod, struct comp_data *cd, + enum sof_ipc_frame source_format, enum sof_ipc_frame sink_format, + int channels) +{ + int ret; + + ret = eq_iir_setup(mod, channels); + if (ret < 0) { + comp_err(mod->dev, "eq_iir_new_blob(), failed IIR setup"); + return ret; + } else if (cd->iir_delay_size) { + comp_dbg(mod->dev, "eq_iir_new_blob(), active"); + cd->eq_iir_func = eq_iir_find_func(source_format, sink_format, fm_configured, + ARRAY_SIZE(fm_configured)); + } else { + comp_dbg(mod->dev, "eq_iir_new_blob(), pass-through"); + cd->eq_iir_func = eq_iir_find_func(source_format, sink_format, fm_passthrough, + ARRAY_SIZE(fm_passthrough)); + } + + return 0; +} + +void eq_iir_set_passthrough_func(struct comp_data *cd, + enum sof_ipc_frame source_format, + enum sof_ipc_frame sink_format) +{ + cd->eq_iir_func = eq_iir_find_func(source_format, sink_format, fm_passthrough, + ARRAY_SIZE(fm_passthrough)); +} + +int eq_iir_prepare_sub(struct processing_module *mod) +{ + return eq_iir_verify_params(mod->dev, mod->stream_params); +} diff --git a/src/audio/eq_iir/eq_iir_ipc4.c b/src/audio/eq_iir/eq_iir_ipc4.c new file mode 100644 index 000000000000..474b820b14de --- /dev/null +++ b/src/audio/eq_iir/eq_iir_ipc4.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2017-2022 Intel Corporation. All rights reserved. +// +// Author: Seppo Ingalsuo +// Liam Girdwood +// Keyon Jie + +#include "eq_iir.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(eq_iir, CONFIG_SOF_LOG_LEVEL); + +/* + * In early days of SOF the preference for pipelines was 16 bits to save RAM in platforms + * like Baytrail. However in microphone paths if there was need to digitally boost the gain + * the quality was bad in topologies where capture DAI was 16 bit and we applied with volume + * or IIR about 20 dB gain. In practice a 16 bit word got left shifted by some bit positions + * that effectively made signal like 12 bits. We could achieve a lot better quality by + * capturing codec and DAI with 24 or 32bits and applying the gain in IIR for the larger word + * length. Then all 16 bits in the pipelines after DAI and IIR had signal. The IIR was chosen for + * format conversion because it also canceled the sometimes large DC component + * (and some lowest non-audible frequencies) in signal. + * It gave the headroom for signal for amplification. + + * If IPC4 systems ever need the memory save small 16 bit capture paths + * the format conversion could be brought back. + */ + +static eq_iir_func eq_iir_find_func(struct processing_module *mod) +{ + unsigned int valid_bit_depth = mod->priv.cfg.base_cfg.audio_fmt.valid_bit_depth; + + comp_dbg(mod->dev, "eq_iir_find_func(): valid_bit_depth %d", valid_bit_depth); + switch (valid_bit_depth) { +#if CONFIG_FORMAT_S16LE + case IPC4_DEPTH_16BIT: + return eq_iir_s16_default; +#endif /* CONFIG_FORMAT_S16LE */ +#if CONFIG_FORMAT_S24LE + case IPC4_DEPTH_24BIT: + return eq_iir_s24_default; +#endif /* CONFIG_FORMAT_S24LE */ +#if CONFIG_FORMAT_S32LE + case IPC4_DEPTH_32BIT: + return eq_iir_s32_default; +#endif /* CONFIG_FORMAT_S32LE */ + default: + comp_err(mod->dev, "set_fir_func(), invalid valid_bith_depth"); + } + return NULL; +} + +int eq_iir_new_blob(struct processing_module *mod, struct comp_data *cd, + enum sof_ipc_frame source_format, enum sof_ipc_frame sink_format, + int channels) +{ + int ret; + + ret = eq_iir_setup(mod, channels); + if (ret < 0) { + comp_err(mod->dev, "eq_iir_new_blob(), failed IIR setup"); + return ret; + } else if (cd->iir_delay_size) { + comp_dbg(mod->dev, "eq_iir_new_blob(), active"); + cd->eq_iir_func = eq_iir_find_func(mod); + } else { + comp_dbg(mod->dev, "eq_iir_new_blob(), pass-through"); + cd->eq_iir_func = eq_iir_pass; + } + + return 0; +} + +static int eq_iir_params(struct processing_module *mod) +{ + struct sof_ipc_stream_params *params = mod->stream_params; + struct sof_ipc_stream_params comp_params; + struct comp_dev *dev = mod->dev; + struct comp_buffer *sinkb; + enum sof_ipc_frame valid_fmt, frame_fmt; + int i, ret; + + comp_dbg(dev, "eq_iir_params()"); + comp_params = *params; + comp_params.channels = mod->priv.cfg.base_cfg.audio_fmt.channels_count; + comp_params.rate = mod->priv.cfg.base_cfg.audio_fmt.sampling_frequency; + comp_params.buffer_fmt = mod->priv.cfg.base_cfg.audio_fmt.interleaving_style; + + audio_stream_fmt_conversion(mod->priv.cfg.base_cfg.audio_fmt.depth, + mod->priv.cfg.base_cfg.audio_fmt.valid_bit_depth, + &frame_fmt, &valid_fmt, + mod->priv.cfg.base_cfg.audio_fmt.s_type); + + comp_params.frame_fmt = valid_fmt; + + for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) + comp_params.chmap[i] = (mod->priv.cfg.base_cfg.audio_fmt.ch_map >> i * 4) & 0xf; + + component_set_nearest_period_frames(dev, comp_params.rate); + sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + ret = buffer_set_params(sinkb, &comp_params, true); + return ret; +} + +void eq_iir_set_passthrough_func(struct comp_data *cd, + enum sof_ipc_frame source_format, + enum sof_ipc_frame sink_format) +{ + cd->eq_iir_func = eq_iir_pass; +} + +int eq_iir_prepare_sub(struct processing_module *mod) +{ + struct comp_dev *dev = mod->dev; + int ret = 0; + + ret = eq_iir_params(mod); + if (ret < 0) + comp_set_state(dev, COMP_TRIGGER_RESET); + + return ret; +} + diff --git a/src/audio/google/CMakeLists.txt b/src/audio/google/CMakeLists.txt index 480766c2f4d5..3936c8041b67 100644 --- a/src/audio/google/CMakeLists.txt +++ b/src/audio/google/CMakeLists.txt @@ -1,7 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause - -if(NOT CONFIG_LIBRARY) +if((NOT CONFIG_LIBRARY) OR CONFIG_LIBRARY_STATIC) if(CONFIG_COMP_GOOGLE_HOTWORD_DETECT) add_local_sources(sof google_hotword_detect.c diff --git a/src/audio/google/google_hotword_detect.c b/src/audio/google/google_hotword_detect.c index b948420ec36b..cf2c4ea3f00c 100644 --- a/src/audio/google/google_hotword_detect.c +++ b/src/audio/google/google_hotword_detect.c @@ -159,7 +159,6 @@ static int ghd_params(struct comp_dev *dev, struct sof_ipc_stream_params *params) { struct comp_buffer *sourceb; - struct comp_buffer __sparse_cache *source_c; int ret; /* Detector is used only in KPB topology. It always requires channels @@ -176,21 +175,18 @@ static int ghd_params(struct comp_dev *dev, /* This detector component will only ever have 1 source */ sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - source_c = buffer_acquire(sourceb); - if (audio_stream_get_channels(source_c->stream) != 1) { + if (audio_stream_get_channels(sourceb->stream) != 1) { comp_err(dev, "ghd_params(): Only single-channel supported"); ret = -EINVAL; - } else if (audio_stream_get_frm_fmt(&source_c->stream) != SOF_IPC_FRAME_S16_LE) { + } else if (audio_stream_get_frm_fmt(&sourceb->stream) != SOF_IPC_FRAME_S16_LE) { comp_err(dev, "ghd_params(): Only S16_LE supported"); ret = -EINVAL; - } else if (source_c->stream.rate != KPB_SAMPLNG_FREQUENCY) { + } else if (sourceb->stream.rate != KPB_SAMPLNG_FREQUENCY) { comp_err(dev, "ghd_params(): Only 16KHz supported"); ret = -EINVAL; } - buffer_release(source_c); - return ret; } @@ -383,8 +379,7 @@ static int ghd_copy(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *source; - struct comp_buffer __sparse_cache *source_c; - struct audio_stream __sparse_cache *stream; + struct audio_stream *stream; uint32_t bytes, tail_bytes, head_bytes = 0; int ret; @@ -399,8 +394,7 @@ static int ghd_copy(struct comp_dev *dev) /* keyword components will only ever have 1 source */ source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - source_c = buffer_acquire(sourceb); - stream = &source_c->stream; + stream = &sourceb->stream; bytes = audio_stream_get_avail_bytes(stream); @@ -411,7 +405,7 @@ static int ghd_copy(struct comp_dev *dev) (uint32_t)audio_stream_get_end_addr(stream)); /* copy and perform detection */ - buffer_stream_invalidate(source_c, bytes); + buffer_stream_invalidate(sourceb, bytes); tail_bytes = (char *)audio_stream_get_end_addr(stream) - (char *)audio_stream_get_rptr(stream); @@ -426,9 +420,7 @@ static int ghd_copy(struct comp_dev *dev) ghd_detect(dev, stream, audio_stream_get_addr(stream), head_bytes); /* calc new available */ - comp_update_buffer_consume(source_c, bytes); - - buffer_release(source_c); + comp_update_buffer_consume(sourceb, bytes); return 0; } diff --git a/src/audio/google/google_rtc_audio_processing.c b/src/audio/google/google_rtc_audio_processing.c index 29493cf9da0b..544e94dd7476 100644 --- a/src/audio/google/google_rtc_audio_processing.c +++ b/src/audio/google/google_rtc_audio_processing.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -54,9 +55,6 @@ struct google_rtc_audio_processing_comp_data { #if CONFIG_IPC_MAJOR_4 struct sof_ipc4_aec_config config; #endif - struct comp_buffer *raw_microphone; - struct comp_buffer *aec_reference; - struct comp_buffer *output; uint32_t num_frames; int num_aec_reference_channels; int num_capture_channels; @@ -70,6 +68,8 @@ struct google_rtc_audio_processing_comp_data { uint8_t *memory_buffer; struct comp_data_blob_handler *tuning_handler; bool reconfigure; + int aec_reference_source; + int raw_microphone_source; }; void *GoogleRtcMalloc(size_t size) @@ -82,51 +82,31 @@ void GoogleRtcFree(void *ptr) return rfree(ptr); } -static int google_rtc_audio_processing_params( - struct comp_dev *dev, - struct sof_ipc_stream_params *params) -{ - int ret; #if CONFIG_IPC_MAJOR_4 - struct google_rtc_audio_processing_comp_data *cd = comp_get_drvdata(dev); - struct comp_buffer __sparse_cache *sink_c; - struct comp_buffer *sink; - - /* update sink buffer format */ - memset(params, 0, sizeof(*params)); - params->channels = cd->config.base_cfg.audio_fmt.channels_count; - params->rate = cd->config.base_cfg.audio_fmt.sampling_frequency; - params->sample_container_bytes = cd->config.base_cfg.audio_fmt.depth / 8; - params->sample_valid_bytes = - cd->config.base_cfg.audio_fmt.valid_bit_depth / 8; - params->buffer_fmt = cd->config.base_cfg.audio_fmt.interleaving_style; - params->buffer.size = cd->config.base_cfg.ibs; - - /* update sink format */ - if (!list_is_empty(&dev->bsink_list)) { - struct ipc4_audio_format *out_fmt = &cd->config.output_fmt; - enum sof_ipc_frame valid_fmt, frame_fmt; - - sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); - ipc4_update_buffer_format(sink_c, out_fmt); - buffer_release(sink_c); - } -#endif +static void google_rtc_audio_processing_params(struct processing_module *mod) +{ + struct sof_ipc_stream_params *params = mod->stream_params; + struct comp_buffer *sinkb, *sourceb; + struct list_item *source_list; + struct comp_dev *dev = mod->dev; - ret = comp_verify_params(dev, 0, params); - if (ret < 0) { - comp_err(dev, - "google_rtc_audio_processing_params(): comp_verify_params failed."); - return -EINVAL; + ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); + component_set_nearest_period_frames(dev, params->rate); + + list_for_item(source_list, &dev->bsource_list) { + sourceb = container_of(source_list, struct comp_buffer, sink_list); + ipc4_update_buffer_format(sourceb, &mod->priv.cfg.base_cfg.audio_fmt); } - return 0; + sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + ipc4_update_buffer_format(sinkb, &mod->priv.cfg.base_cfg.audio_fmt); } +#endif -static int google_rtc_audio_processing_reconfigure(struct comp_dev *dev) +static int google_rtc_audio_processing_reconfigure(struct processing_module *mod) { - struct google_rtc_audio_processing_comp_data *cd = comp_get_drvdata(dev); + struct google_rtc_audio_processing_comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; uint8_t *config; size_t size; int ret; @@ -270,11 +250,11 @@ static int google_rtc_audio_processing_reconfigure(struct comp_dev *dev) return 0; } -static int google_rtc_audio_processing_cmd_set_data( - struct comp_dev *dev, - struct sof_ipc_ctrl_data *cdata) +#if CONFIG_IPC_MAJOR_3 +static int google_rtc_audio_processing_cmd_set_data(struct processing_module *mod, + struct sof_ipc_ctrl_data *cdata) { - struct google_rtc_audio_processing_comp_data *cd = comp_get_drvdata(dev); + struct google_rtc_audio_processing_comp_data *cd = module_get_private_data(mod); int ret; switch (cdata->cmd) { @@ -297,85 +277,124 @@ static int google_rtc_audio_processing_cmd_set_data( } return 0; default: - comp_err(dev, - "google_rtc_audio_processing_ctrl_set_data(): Only binary controls supported %d", - cdata->cmd); + comp_err(mod->dev, + "google_rtc_audio_processing_ctrl_set_data(): Only binary controls supported %d", + cdata->cmd); return -EINVAL; } } -static int google_rtc_audio_processing_cmd_get_data( - struct comp_dev *dev, - struct sof_ipc_ctrl_data *cdata, - int max_data_size) +static int google_rtc_audio_processing_cmd_get_data(struct processing_module *mod, + struct sof_ipc_ctrl_data *cdata, + size_t max_data_size) { - struct google_rtc_audio_processing_comp_data *cd = comp_get_drvdata(dev); + struct google_rtc_audio_processing_comp_data *cd = module_get_private_data(mod); - comp_info(dev, "google_rtc_audio_processing_ctrl_get_data(): %u", cdata->cmd); + comp_info(mod->dev, "google_rtc_audio_processing_ctrl_get_data(): %u", cdata->cmd); switch (cdata->cmd) { case SOF_CTRL_CMD_BINARY: return comp_data_blob_get_cmd(cd->tuning_handler, cdata, max_data_size); default: - comp_err(dev, - "google_rtc_audio_processing_ctrl_get_data(): Only binary controls supported %d", - cdata->cmd); + comp_err(mod->dev, + "google_rtc_audio_processing_ctrl_get_data(): Only binary controls supported %d", + cdata->cmd); return -EINVAL; } } +#endif -static int google_rtc_audio_processing_cmd(struct comp_dev *dev, int cmd, void *data, - int max_data_size) +static int google_rtc_audio_processing_set_config(struct processing_module *mod, uint32_t param_id, + enum module_cfg_fragment_position pos, + uint32_t data_offset_size, + const uint8_t *fragment, + size_t fragment_size, uint8_t *response, + size_t response_size) { - struct sof_ipc_ctrl_data *cdata = data; - - comp_dbg(dev, "google_rtc_audio_processing_cmd(): %d - data_cmd: %d", cmd, cdata->cmd); +#if CONFIG_IPC_MAJOR_4 + struct google_rtc_audio_processing_comp_data *cd = module_get_private_data(mod); + int ret; - switch (cmd) { - case COMP_CMD_SET_VALUE: - case COMP_CMD_GET_VALUE: - return 0; - case COMP_CMD_SET_DATA: - return google_rtc_audio_processing_cmd_set_data(dev, cdata); - case COMP_CMD_GET_DATA: - return google_rtc_audio_processing_cmd_get_data(dev, cdata, max_data_size); - default: - comp_err(dev, "google_rtc_audio_processing_cmd(): Unknown cmd %d", cmd); + switch (param_id) { + case SOF_IPC4_SWITCH_CONTROL_PARAM_ID: + case SOF_IPC4_ENUM_CONTROL_PARAM_ID: + comp_err(mod->dev, "google_rtc_audio_processing_ctrl_set_data(): Only binary controls supported"); return -EINVAL; } + + ret = comp_data_blob_set(cd->tuning_handler, pos, data_offset_size, + fragment, fragment_size); + if (ret) + return ret; + + /* Accept the new blob immediately so that userspace can write + * the control in quick succession without error. + * This ensures the last successful control write from userspace + * before prepare/copy is applied. + * The config blob is not referenced after reconfigure() returns + * so it is safe to call comp_get_data_blob here which frees the + * old blob. This assumes cmd() and prepare()/copy() cannot run + * concurrently which is the case when there is no preemption. + * + * Note from review: A race condition is possible and should be + * further investigated and fixed. + */ + if (comp_is_new_data_blob_available(cd->tuning_handler)) { + comp_get_data_blob(cd->tuning_handler, NULL, NULL); + cd->reconfigure = true; + } + + return 0; +#elif CONFIG_IPC_MAJOR_3 + struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; + + return google_rtc_audio_processing_cmd_set_data(mod, cdata); +#endif } -static struct comp_dev *google_rtc_audio_processing_create( - const struct comp_driver *drv, - const struct comp_ipc_config *config, - const void *spec) +static int google_rtc_audio_processing_get_config(struct processing_module *mod, + uint32_t param_id, uint32_t *data_offset_size, + uint8_t *fragment, size_t fragment_size) { - struct comp_dev *dev; - struct google_rtc_audio_processing_comp_data *cd; - int ret; - - comp_cl_info(drv, "google_rtc_audio_processing_create()"); +#if CONFIG_IPC_MAJOR_4 + comp_err(mod->dev, "google_rtc_audio_processing_ctrl_get_config(): Not supported"); + return -EINVAL; +#elif CONFIG_IPC_MAJOR_3 + struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; - /* Create component device with an effect processing component */ - dev = comp_alloc(drv, sizeof(*dev)); + return google_rtc_audio_processing_cmd_get_data(mod, cdata, fragment_size); +#endif +} - if (!dev) - return NULL; +static int google_rtc_audio_processing_init(struct processing_module *mod) +{ + struct module_data *md = &mod->priv; + struct comp_dev *dev = mod->dev; + struct google_rtc_audio_processing_comp_data *cd; + int ret; - dev->ipc_config = *config; + comp_info(dev, "google_rtc_audio_processing_init()"); /* Create private component data */ cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*cd)); - if (!cd) + if (!cd) { + ret = -ENOMEM; goto fail; + } + + md->private = cd; #if CONFIG_IPC_MAJOR_4 - cd->config = *(const struct sof_ipc4_aec_config *)spec; + struct module_config *cfg = &md->cfg; + + cd->config = *(const struct sof_ipc4_aec_config *)cfg->init_data; #endif cd->tuning_handler = comp_data_blob_handler_new(dev); - if (!cd->tuning_handler) + if (!cd->tuning_handler) { + ret = -ENOMEM; goto fail; + } cd->num_aec_reference_channels = CONFIG_COMP_GOOGLE_RTC_AUDIO_PROCESSING_NUM_AEC_REFERENCE_CHANNELS; cd->num_capture_channels = CONFIG_COMP_GOOGLE_RTC_AUDIO_PROCESSING_NUM_CHANNELS; @@ -387,8 +406,8 @@ static struct comp_dev *google_rtc_audio_processing_create( CONFIG_COMP_GOOGLE_RTC_AUDIO_PROCESSING_MEMORY_BUFFER_SIZE_BYTES * sizeof(cd->memory_buffer[0])); if (!cd->memory_buffer) { - comp_err(dev, "google_rtc_audio_processing_create: failed to allocate memory buffer"); - + comp_err(dev, "google_rtc_audio_processing_init: failed to allocate memory buffer"); + ret = -ENOMEM; goto fail; } @@ -404,6 +423,7 @@ static struct comp_dev *google_rtc_audio_processing_create( if (!cd->state) { comp_err(dev, "Failed to initialized GoogleRtcAudioProcessing"); + ret = -EINVAL; goto fail; } @@ -421,8 +441,10 @@ static struct comp_dev *google_rtc_audio_processing_create( cd->raw_mic_buffer = rballoc( 0, SOF_MEM_CAPS_RAM, cd->num_frames * cd->num_capture_channels * sizeof(cd->raw_mic_buffer[0])); - if (!cd->raw_mic_buffer) + if (!cd->raw_mic_buffer) { + ret = -EINVAL; goto fail; + } bzero(cd->raw_mic_buffer, cd->num_frames * cd->num_capture_channels * sizeof(cd->raw_mic_buffer[0])); cd->raw_mic_buffer_frame_index = 0; @@ -430,16 +452,20 @@ static struct comp_dev *google_rtc_audio_processing_create( 0, SOF_MEM_CAPS_RAM, cd->num_frames * sizeof(cd->aec_reference_buffer[0]) * cd->num_aec_reference_channels); - if (!cd->aec_reference_buffer) + if (!cd->aec_reference_buffer) { + ret = -ENOMEM; goto fail; + } bzero(cd->aec_reference_buffer, cd->num_frames * cd->num_aec_reference_channels * sizeof(cd->aec_reference_buffer[0])); cd->aec_reference_frame_index = 0; cd->output_buffer = rballoc( 0, SOF_MEM_CAPS_RAM, cd->num_frames * cd->num_capture_channels * sizeof(cd->output_buffer[0])); - if (!cd->output_buffer) + if (!cd->output_buffer) { + ret = -ENOMEM; goto fail; + } bzero(cd->output_buffer, cd->num_frames * sizeof(cd->output_buffer[0])); cd->output_buffer_frame_index = 0; @@ -450,12 +476,14 @@ static struct comp_dev *google_rtc_audio_processing_create( */ cd->reconfigure = true; - comp_set_drvdata(dev, cd); - dev->state = COMP_STATE_READY; - comp_dbg(dev, "google_rtc_audio_processing_create(): Ready"); - return dev; + /* Mic and reference, needed for audio stream type copy module client */ + mod->max_sources = 2; + + comp_dbg(dev, "google_rtc_audio_processing_init(): Ready"); + return 0; + fail: - comp_err(dev, "google_rtc_audio_processing_create(): Failed"); + comp_err(dev, "google_rtc_audio_processing_init(): Failed"); if (cd) { rfree(cd->output_buffer); rfree(cd->aec_reference_buffer); @@ -468,15 +496,15 @@ static struct comp_dev *google_rtc_audio_processing_create( comp_data_blob_handler_free(cd->tuning_handler); rfree(cd); } - rfree(dev); - return NULL; + + return ret; } -static void google_rtc_audio_processing_free(struct comp_dev *dev) +static int google_rtc_audio_processing_free(struct processing_module *mod) { - struct google_rtc_audio_processing_comp_data *cd = comp_get_drvdata(dev); + struct google_rtc_audio_processing_comp_data *cd = module_get_private_data(mod); - comp_dbg(dev, "google_rtc_audio_processing_free()"); + comp_dbg(mod->dev, "google_rtc_audio_processing_free()"); GoogleRtcAudioProcessingFree(cd->state); cd->state = NULL; @@ -487,47 +515,55 @@ static void google_rtc_audio_processing_free(struct comp_dev *dev) rfree(cd->raw_mic_buffer); comp_data_blob_handler_free(cd->tuning_handler); rfree(cd); - rfree(dev); -} - - -static int google_rtc_audio_processing_trigger(struct comp_dev *dev, int cmd) -{ - comp_dbg(dev, "google_rtc_audio_processing_trigger(): %d", cmd); - - return comp_set_state(dev, cmd); + return 0; } -static int google_rtc_audio_processing_prepare(struct comp_dev *dev) +static int google_rtc_audio_processing_prepare(struct processing_module *mod, + struct sof_source **sources, + int num_of_sources, + struct sof_sink **sinks, + int num_of_sinks) { - struct google_rtc_audio_processing_comp_data *cd = comp_get_drvdata(dev); + struct comp_dev *dev = mod->dev; + struct google_rtc_audio_processing_comp_data *cd = module_get_private_data(mod); struct list_item *source_buffer_list_item; - struct comp_buffer __sparse_cache *output_c; + struct comp_buffer *output; unsigned int aec_channels = 0, frame_fmt, rate; + int microphone_stream_channels = 0; + int output_stream_channels; int ret; + int i = 0; + + comp_info(dev, "google_rtc_audio_processing_prepare()"); - comp_dbg(dev, "google_rtc_audio_processing_prepare()"); +#if CONFIG_IPC_MAJOR_4 + google_rtc_audio_processing_params(mod); +#endif /* searching for stream and feedback source buffers */ list_for_item(source_buffer_list_item, &dev->bsource_list) { struct comp_buffer *source = container_of(source_buffer_list_item, struct comp_buffer, sink_list); - struct comp_buffer __sparse_cache *source_c = buffer_acquire(source); - #if CONFIG_IPC_MAJOR_4 - if (IPC4_SINK_QUEUE_ID(source_c->id) == SOF_AEC_FEEDBACK_QUEUE_ID) { + if (IPC4_SINK_QUEUE_ID(source->id) == SOF_AEC_FEEDBACK_QUEUE_ID) { #else - if (source_c->source->pipeline->pipeline_id != dev->pipeline->pipeline_id) { + if (source->source->pipeline->pipeline_id != dev->pipeline->pipeline_id) { #endif - cd->aec_reference = source; - aec_channels = audio_stream_get_channels(&source_c->stream); + cd->aec_reference_source = i; + aec_channels = audio_stream_get_channels(&source->stream); + comp_dbg(dev, "reference index = %d, channels = %d", i, aec_channels); } else { - cd->raw_microphone = source; + cd->raw_microphone_source = i; + microphone_stream_channels = audio_stream_get_channels(&source->stream); + comp_dbg(dev, "microphone index = %d, channels = %d", i, + microphone_stream_channels); } - buffer_release(source_c); + + audio_stream_init_alignment_constants(1, 1, &source->stream); + i++; } - cd->output = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + output = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); /* On some platform the playback output is left right left right due to a crossover * later on the signal processing chain. That makes the aec_reference be 4 channels @@ -539,21 +575,20 @@ static int google_rtc_audio_processing_prepare(struct comp_dev *dev) return -EINVAL; } - output_c = buffer_acquire(cd->output); - frame_fmt = audio_stream_get_frm_fmt(&output_c->stream); - rate = audio_stream_get_rate(&output_c->stream); - buffer_release(output_c); - + audio_stream_init_alignment_constants(1, 1, &output->stream); + frame_fmt = audio_stream_get_frm_fmt(&output->stream); + rate = audio_stream_get_rate(&output->stream); + output_stream_channels = audio_stream_get_channels(&output->stream); - if (cd->num_capture_channels > audio_stream_get_channels(&cd->raw_microphone->stream)) { + if (cd->num_capture_channels > microphone_stream_channels) { comp_err(dev, "unsupported number of microphone channels: %d", - audio_stream_get_channels(&cd->raw_microphone->stream)); + microphone_stream_channels); return -EINVAL; } - if (cd->num_capture_channels > audio_stream_get_channels(&cd->output->stream)) { + if (cd->num_capture_channels > output_stream_channels) { comp_err(dev, "unsupported number of output channels: %d", - audio_stream_get_channels(&cd->output->stream)); + output_stream_channels); return -EINVAL; } @@ -575,61 +610,65 @@ static int google_rtc_audio_processing_prepare(struct comp_dev *dev) /* Blobs sent during COMP_STATE_READY is assigned to blob_handler->data * directly, so comp_is_new_data_blob_available always returns false. */ - ret = google_rtc_audio_processing_reconfigure(dev); + ret = google_rtc_audio_processing_reconfigure(mod); if (ret) return ret; - return comp_set_state(dev, COMP_TRIGGER_PREPARE); + return 0; } -static int google_rtc_audio_processing_reset(struct comp_dev *dev) +static int google_rtc_audio_processing_reset(struct processing_module *mod) { - comp_dbg(dev, "google_rtc_audio_processing_reset()"); + comp_dbg(mod->dev, "google_rtc_audio_processing_reset()"); - return comp_set_state(dev, COMP_TRIGGER_RESET); + return 0; } -static int google_rtc_audio_processing_copy(struct comp_dev *dev) +static int google_rtc_audio_processing_process(struct processing_module *mod, + struct input_stream_buffer *input_buffers, + int num_input_buffers, + struct output_stream_buffer *output_buffers, + int num_output_buffers) { - struct google_rtc_audio_processing_comp_data *cd = comp_get_drvdata(dev); - struct comp_buffer __sparse_cache *buffer_c, *mic_buf, *output_buf; - struct comp_copy_limits cl; + struct google_rtc_audio_processing_comp_data *cd = module_get_private_data(mod); int16_t *src, *dst, *ref; uint32_t num_aec_reference_frames; uint32_t num_aec_reference_bytes; int num_samples_remaining; int num_frames_remaining; int channel; + int frames; int nmax; int ret; int i, j, n; + struct input_stream_buffer *ref_streamb, *mic_streamb; + struct output_stream_buffer *out_streamb; + struct audio_stream *ref_stream, *mic_stream, *out_stream; + if (cd->reconfigure) { - ret = google_rtc_audio_processing_reconfigure(dev); + ret = google_rtc_audio_processing_reconfigure(mod); if (ret) return ret; } - buffer_c = buffer_acquire(cd->aec_reference); - - ref = audio_stream_get_rptr(&buffer_c->stream); + ref_streamb = &input_buffers[cd->aec_reference_source]; + ref_stream = ref_streamb->data; + ref = audio_stream_get_rptr(ref_stream); - num_aec_reference_frames = audio_stream_get_avail_frames(&buffer_c->stream); - num_aec_reference_bytes = audio_stream_get_avail_bytes(&buffer_c->stream); + num_aec_reference_frames = input_buffers[cd->aec_reference_source].size; + num_aec_reference_bytes = audio_stream_frame_bytes(ref_stream) * num_aec_reference_frames; - buffer_stream_invalidate(buffer_c, num_aec_reference_bytes); - - num_samples_remaining = num_aec_reference_frames * - audio_stream_get_channels(&buffer_c->stream); + num_samples_remaining = num_aec_reference_frames * audio_stream_get_channels(ref_stream); while (num_samples_remaining) { - nmax = audio_stream_samples_without_wrap_s16(&buffer_c->stream, ref); + nmax = audio_stream_samples_without_wrap_s16(ref_stream, ref); n = MIN(num_samples_remaining, nmax); for (i = 0; i < n; i += cd->num_aec_reference_channels) { j = cd->num_aec_reference_channels * cd->aec_reference_frame_index; for (channel = 0; channel < cd->num_aec_reference_channels; ++channel) cd->aec_reference_buffer[j++] = ref[channel]; - ref += audio_stream_get_channels(&buffer_c->stream); + ref += audio_stream_get_channels(ref_stream); ++cd->aec_reference_frame_index; if (cd->aec_reference_frame_index == cd->num_frames) { @@ -639,26 +678,25 @@ static int google_rtc_audio_processing_copy(struct comp_dev *dev) } } num_samples_remaining -= n; - ref = audio_stream_wrap(&buffer_c->stream, ref); + ref = audio_stream_wrap(ref_stream, ref); } - comp_update_buffer_consume(buffer_c, num_aec_reference_bytes); - - buffer_release(buffer_c); + input_buffers[cd->aec_reference_source].consumed = num_aec_reference_bytes; - mic_buf = buffer_acquire(cd->raw_microphone); - output_buf = buffer_acquire(cd->output); + mic_streamb = &input_buffers[cd->raw_microphone_source]; + mic_stream = mic_streamb->data; + out_streamb = &output_buffers[0]; + out_stream = out_streamb->data; - src = audio_stream_get_rptr(&mic_buf->stream); - dst = audio_stream_get_wptr(&output_buf->stream); + src = audio_stream_get_rptr(mic_stream); + dst = audio_stream_get_wptr(out_stream); - comp_get_copy_limits(mic_buf, output_buf, &cl); - buffer_stream_invalidate(mic_buf, cl.source_bytes); + frames = input_buffers[cd->raw_microphone_source].size; + num_frames_remaining = frames; - num_frames_remaining = cl.frames; while (num_frames_remaining) { - nmax = audio_stream_frames_without_wrap(&mic_buf->stream, src); + nmax = audio_stream_frames_without_wrap(mic_stream, src); n = MIN(num_frames_remaining, nmax); - nmax = audio_stream_frames_without_wrap(&output_buf->stream, dst); + nmax = audio_stream_frames_without_wrap(out_stream, dst); n = MIN(n, nmax); for (i = 0; i < n; i++) { memcpy_s(&(cd->raw_mic_buffer[cd->raw_mic_buffer_frame_index * @@ -668,7 +706,6 @@ static int google_rtc_audio_processing_copy(struct comp_dev *dev) sizeof(int16_t) * cd->num_capture_channels); ++cd->raw_mic_buffer_frame_index; - memcpy_s(dst, cd->num_frames * cd->num_capture_channels * sizeof(cd->output_buffer[0]), &(cd->output_buffer[cd->output_buffer_frame_index * @@ -684,72 +721,31 @@ static int google_rtc_audio_processing_copy(struct comp_dev *dev) cd->raw_mic_buffer_frame_index = 0; } - src += audio_stream_get_channels(&mic_buf->stream); - dst += audio_stream_get_channels(&output_buf->stream); + src += audio_stream_get_channels(mic_stream); + dst += audio_stream_get_channels(out_stream); } num_frames_remaining -= n; - src = audio_stream_wrap(&mic_buf->stream, src); - dst = audio_stream_wrap(&output_buf->stream, dst); + src = audio_stream_wrap(mic_stream, src); + dst = audio_stream_wrap(out_stream, dst); } - buffer_stream_writeback(output_buf, cl.sink_bytes); - - comp_update_buffer_produce(output_buf, cl.sink_bytes); - comp_update_buffer_consume(mic_buf, cl.source_bytes); - - buffer_release(output_buf); - buffer_release(mic_buf); - - return 0; -} - -#if CONFIG_IPC_MAJOR_4 -static int google_rtc_audio_processing_get_attribute(struct comp_dev *dev, - uint32_t type, void *value) -{ - struct google_rtc_audio_processing_comp_data *cd = comp_get_drvdata(dev); - - switch (type) { - case COMP_ATTR_BASE_CONFIG: - *(struct ipc4_base_module_cfg *)value = cd->config.base_cfg; - break; - default: - return -EINVAL; - } + module_update_buffer_position(&input_buffers[cd->raw_microphone_source], + &output_buffers[0], frames); return 0; } -#endif -static const struct comp_driver google_rtc_audio_processing = { - .uid = SOF_RT_UUID(google_rtc_audio_processing_uuid), - .tctx = &google_rtc_audio_processing_tr, - .ops = { - .create = google_rtc_audio_processing_create, - .free = google_rtc_audio_processing_free, - .params = google_rtc_audio_processing_params, - .cmd = google_rtc_audio_processing_cmd, - .trigger = google_rtc_audio_processing_trigger, - .copy = google_rtc_audio_processing_copy, - .prepare = google_rtc_audio_processing_prepare, - .reset = google_rtc_audio_processing_reset, -#if CONFIG_IPC_MAJOR_4 - .get_attribute = google_rtc_audio_processing_get_attribute, -#endif - }, +static struct module_interface google_rtc_audio_processing_interface = { + .init = google_rtc_audio_processing_init, + .free = google_rtc_audio_processing_free, + .process_audio_stream = google_rtc_audio_processing_process, + .prepare = google_rtc_audio_processing_prepare, + .set_configuration = google_rtc_audio_processing_set_config, + .get_configuration = google_rtc_audio_processing_get_config, + .reset = google_rtc_audio_processing_reset, }; -static SHARED_DATA struct comp_driver_info google_rtc_audio_processing_info = { - .drv = &google_rtc_audio_processing, -}; - -UT_STATIC void sys_comp_google_rtc_audio_processing_init(void) -{ - comp_register( - platform_shared_get( - &google_rtc_audio_processing_info, - sizeof(google_rtc_audio_processing_info))); -} - -DECLARE_MODULE(sys_comp_google_rtc_audio_processing_init); -SOF_MODULE_INIT(google_rtc_audio_processing, sys_comp_google_rtc_audio_processing_init); +DECLARE_MODULE_ADAPTER(google_rtc_audio_processing_interface, + google_rtc_audio_processing_uuid, google_rtc_audio_processing_tr); +SOF_MODULE_INIT(google_rtc_audio_processing, + sys_comp_module_google_rtc_audio_processing_interface_init); diff --git a/src/audio/google/google_rtc_audio_processing_mock.c b/src/audio/google/google_rtc_audio_processing_mock.c index 6073e125a539..a6c55c641270 100644 --- a/src/audio/google/google_rtc_audio_processing_mock.c +++ b/src/audio/google/google_rtc_audio_processing_mock.c @@ -10,6 +10,8 @@ #include #include +#include +#include #include #include "ipc/topology.h" @@ -145,11 +147,23 @@ int GoogleRtcAudioProcessingProcessCapture_int16(GoogleRtcAudioProcessingState * int16_t *ref = state->aec_reference; int16_t *mic = (int16_t *) src; int16_t *out = dest; - int n; + int n, io, im, ir; + /* Mix input and reference channels to output. The matching channels numbers + * are mixed. If e.g. microphone and output channels count is 4, and reference + * has 2 channels, output channels 3 and 4 are copy of microphone channels 3 and 4, + * and output channels 1 and 2 are sum of microphone and reference. + */ memset(dest, 0, sizeof(int16_t) * state->num_output_channels * state->num_frames); for (n = 0; n < state->num_frames; ++n) { - *out = *mic + *ref; + im = 0; + ir = 0; + for (io = 0; io < state->num_output_channels; io++) { + out[io] = sat_int16( + (im < state->num_capture_channels ? (int32_t)mic[im++] : 0) + + (ir < state->num_aec_reference_channels ? (int32_t)ref[ir++] : 0)); + } + ref += state->num_aec_reference_channels; out += state->num_output_channels; mic += state->num_capture_channels; diff --git a/src/audio/host-legacy.c b/src/audio/host-legacy.c index b9a112583586..83cf3c8cd3c4 100644 --- a/src/audio/host-legacy.c +++ b/src/audio/host-legacy.c @@ -105,16 +105,13 @@ static int host_dma_set_config_and_copy(struct host_data *hd, struct comp_dev *d */ static uint32_t host_get_copy_bytes_one_shot(struct host_data *hd, struct comp_dev *dev) { - struct comp_buffer __sparse_cache *buffer_c = buffer_acquire(hd->local_buffer); uint32_t copy_bytes; /* calculate minimum size to copy */ if (dev->direction == SOF_IPC_STREAM_PLAYBACK) - copy_bytes = audio_stream_get_free_bytes(&buffer_c->stream); + copy_bytes = audio_stream_get_free_bytes(&hd->local_buffer->stream); else - copy_bytes = audio_stream_get_avail_bytes(&buffer_c->stream); - - buffer_release(buffer_c); + copy_bytes = audio_stream_get_avail_bytes(&hd->local_buffer->stream); /* copy_bytes should be aligned to minimum possible chunk of * data to be copied by dma. @@ -168,17 +165,14 @@ static int host_copy_one_shot(struct host_data *hd, struct comp_dev *dev, copy_c static uint32_t host_get_copy_bytes_one_shot(struct host_data *hd, struct comp_dev *dev) { struct dma_sg_elem *local_elem = hd->config.elem_array.elems; - struct comp_buffer __sparse_cache *buffer_c = buffer_acquire(hd->local_buffer); uint32_t copy_bytes; uint32_t split_value; /* calculate minimum size to copy */ if (dev->direction == SOF_IPC_STREAM_PLAYBACK) - copy_bytes = audio_stream_get_free_bytes(&buffer_c->stream); + copy_bytes = audio_stream_get_free_bytes(&hd->local_buffer->stream); else - copy_bytes = audio_stream_get_avail_bytes(&buffer_c->stream); - - buffer_release(buffer_c); + copy_bytes = audio_stream_get_avail_bytes(&hd->local_buffer->stream); /* copy_bytes should be aligned to minimum possible chunk of * data to be copied by dma. @@ -232,19 +226,19 @@ static int host_copy_one_shot(struct host_data *hd, struct comp_dev *dev, copy_c void host_common_update(struct host_data *hd, struct comp_dev *dev, uint32_t bytes) { - struct comp_buffer __sparse_cache *source; - struct comp_buffer __sparse_cache *sink; + struct comp_buffer *source; + struct comp_buffer *sink; int ret; bool update_mailbox = false; bool send_ipc = false; if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { - source = buffer_acquire(hd->dma_buffer); - sink = buffer_acquire(hd->local_buffer); + source = hd->dma_buffer; + sink = hd->local_buffer; ret = dma_buffer_copy_from(source, sink, hd->process, bytes); } else { - source = buffer_acquire(hd->local_buffer); - sink = buffer_acquire(hd->dma_buffer); + source = hd->local_buffer; + sink = hd->dma_buffer; ret = dma_buffer_copy_to(source, sink, hd->process, bytes); } @@ -257,9 +251,6 @@ void host_common_update(struct host_data *hd, struct comp_dev *dev, uint32_t byt audio_stream_get_free_samples(&sink->stream) * audio_stream_frame_bytes(&sink->stream)); - buffer_release(sink); - buffer_release(source); - if (ret < 0) return; @@ -372,7 +363,6 @@ static void host_dma_cb(void *arg, enum notify_id type, void *data) */ static uint32_t host_get_copy_bytes_normal(struct host_data *hd, struct comp_dev *dev) { - struct comp_buffer __sparse_cache *buffer_c; uint32_t avail_bytes = 0; uint32_t free_bytes = 0; uint32_t copy_bytes = 0; @@ -387,28 +377,24 @@ static uint32_t host_get_copy_bytes_normal(struct host_data *hd, struct comp_dev return 0; } - buffer_c = buffer_acquire(hd->local_buffer); - /* calculate minimum size to copy */ if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { /* limit bytes per copy to one period for the whole pipeline * in order to avoid high load spike */ - free_bytes = audio_stream_get_free_bytes(&buffer_c->stream); + free_bytes = audio_stream_get_free_bytes(&hd->local_buffer->stream); copy_bytes = MIN(hd->period_bytes, MIN(avail_bytes, free_bytes)); if (!copy_bytes) comp_info(dev, "no bytes to copy, %d free in buffer, %d available in DMA", free_bytes, avail_bytes); } else { - avail_bytes = audio_stream_get_avail_bytes(&buffer_c->stream); + avail_bytes = audio_stream_get_avail_bytes(&hd->local_buffer->stream); copy_bytes = MIN(avail_bytes, free_bytes); if (!copy_bytes) comp_info(dev, "no bytes to copy, %d avail in buffer, %d free in DMA", avail_bytes, free_bytes); } - buffer_release(buffer_c); - /* copy_bytes should be aligned to minimum possible chunk of * data to be copied by dma. */ @@ -446,7 +432,6 @@ static int host_copy_normal(struct host_data *hd, struct comp_dev *dev, copy_cal static int create_local_elems(struct host_data *hd, struct comp_dev *dev, uint32_t buffer_count, uint32_t buffer_bytes) { - struct comp_buffer __sparse_cache *dma_buf_c; struct dma_sg_elem_array *elem_array; uint32_t dir; int err; @@ -469,11 +454,9 @@ static int create_local_elems(struct host_data *hd, struct comp_dev *dev, uint32 elem_array = &hd->config.elem_array; } - dma_buf_c = buffer_acquire(hd->dma_buffer); err = dma_sg_alloc(elem_array, SOF_MEM_ZONE_RUNTIME, dir, buffer_count, buffer_bytes, - (uintptr_t)(audio_stream_get_addr(&dma_buf_c->stream)), 0); - buffer_release(dma_buf_c); + (uintptr_t)(audio_stream_get_addr(&hd->dma_buffer->stream)), 0); if (err < 0) { comp_err(dev, "create_local_elems(): dma_sg_alloc() failed"); return err; @@ -690,8 +673,6 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, struct sof_ipc_stream_params *params, notifier_callback_t cb) { struct dma_sg_config *config = &hd->config; - struct comp_buffer __sparse_cache *host_buf_c; - struct comp_buffer __sparse_cache *dma_buf_c; uint32_t period_count; uint32_t period_bytes; uint32_t buffer_size; @@ -740,10 +721,9 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, hd->local_buffer = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - host_buf_c = buffer_acquire(hd->local_buffer); period_bytes = dev->frames * - audio_stream_frame_bytes(&host_buf_c->stream); + audio_stream_frame_bytes(&hd->local_buffer->stream); if (!period_bytes) { comp_err(dev, "host_params(): invalid period_bytes"); @@ -778,9 +758,7 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, * but we have to write back caches after we finish anyway */ if (hd->dma_buffer) { - dma_buf_c = buffer_acquire(hd->dma_buffer); - err = buffer_set_size(dma_buf_c, buffer_size, addr_align); - buffer_release(dma_buf_c); + err = buffer_set_size(hd->dma_buffer, buffer_size, addr_align); if (err < 0) { comp_err(dev, "host_params(): buffer_set_size() failed, buffer_size = %u", buffer_size); @@ -788,16 +766,14 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, } } else { hd->dma_buffer = buffer_alloc(buffer_size, SOF_MEM_CAPS_DMA, 0, - addr_align); + addr_align, false); if (!hd->dma_buffer) { comp_err(dev, "host_params(): failed to alloc dma buffer"); err = -ENOMEM; goto out; } - dma_buf_c = buffer_acquire(hd->dma_buffer); - buffer_set_params(dma_buf_c, params, BUFFER_UPDATE_FORCE); - buffer_release(dma_buf_c); + buffer_set_params(hd->dma_buffer, params, BUFFER_UPDATE_FORCE); } /* create SG DMA elems for local DMA buffer */ @@ -806,8 +782,8 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, goto out; /* set up DMA configuration - copy in sample bytes. */ - config->src_width = audio_stream_sample_bytes(&host_buf_c->stream); - config->dest_width = audio_stream_sample_bytes(&host_buf_c->stream); + config->src_width = audio_stream_sample_bytes(&hd->local_buffer->stream); + config->dest_width = audio_stream_sample_bytes(&hd->local_buffer->stream); config->cyclic = 0; config->irq_disabled = pipeline_is_timer_driven(dev->pipeline); config->is_scheduling_source = comp_is_scheduling_source(dev); @@ -851,11 +827,11 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, host_copy_normal; /* set processing function */ - hd->process = pcm_get_conversion_function(audio_stream_get_frm_fmt(&host_buf_c->stream), - audio_stream_get_frm_fmt(&host_buf_c->stream)); + hd->process = + pcm_get_conversion_function(audio_stream_get_frm_fmt(&hd->local_buffer->stream), + audio_stream_get_frm_fmt(&hd->local_buffer->stream)); out: - buffer_release(host_buf_c); hd->cb_dev = dev; @@ -886,11 +862,7 @@ static int host_params(struct comp_dev *dev, int host_common_prepare(struct host_data *hd) { - struct comp_buffer __sparse_cache *buf_c = buffer_acquire(hd->dma_buffer); - - buffer_zero(buf_c); - buffer_release(buf_c); - + buffer_zero(hd->dma_buffer); return 0; } diff --git a/src/audio/host-zephyr.c b/src/audio/host-zephyr.c index d62ad4b424fc..4016a8be82a4 100644 --- a/src/audio/host-zephyr.c +++ b/src/audio/host-zephyr.c @@ -109,18 +109,13 @@ static int host_dma_set_config_and_copy(struct host_data *hd, struct comp_dev *d static uint32_t host_get_copy_bytes_one_shot(struct host_data *hd) { struct comp_buffer *buffer = hd->local_buffer; - struct comp_buffer __sparse_cache *buffer_c; uint32_t copy_bytes; - buffer_c = buffer_acquire(buffer); - /* calculate minimum size to copy */ if (hd->ipc_host.direction == SOF_IPC_STREAM_PLAYBACK) - copy_bytes = audio_stream_get_free_bytes(&buffer_c->stream); + copy_bytes = audio_stream_get_free_bytes(&buffer->stream); else - copy_bytes = audio_stream_get_avail_bytes(&buffer_c->stream); - - buffer_release(buffer_c); + copy_bytes = audio_stream_get_avail_bytes(&buffer->stream); /* copy_bytes should be aligned to minimum possible chunk of * data to be copied by dma. @@ -175,19 +170,14 @@ static uint32_t host_get_copy_bytes_one_shot(struct host_data *hd) { struct dma_sg_elem *local_elem = hd->config.elem_array.elems; struct comp_buffer *buffer = hd->local_buffer; - struct comp_buffer __sparse_cache *buffer_c; uint32_t copy_bytes; uint32_t split_value; - buffer_c = buffer_acquire(buffer); - /* calculate minimum size to copy */ if (hd->ipc_host.direction == SOF_IPC_STREAM_PLAYBACK) - copy_bytes = audio_stream_get_free_bytes(&buffer_c->stream); + copy_bytes = audio_stream_get_free_bytes(&buffer->stream); else - copy_bytes = audio_stream_get_avail_bytes(&buffer_c->stream); - - buffer_release(buffer_c); + copy_bytes = audio_stream_get_avail_bytes(&buffer->stream); /* copy_bytes should be aligned to minimum possible chunk of * data to be copied by dma. @@ -241,36 +231,27 @@ static int host_copy_one_shot(struct host_data *hd, struct comp_dev *dev, copy_c void host_common_update(struct host_data *hd, struct comp_dev *dev, uint32_t bytes) { - struct comp_buffer __sparse_cache *source; - struct comp_buffer __sparse_cache *sink; + struct comp_buffer *source; + struct comp_buffer *sink; int ret; bool update_mailbox = false; bool send_ipc = false; - if (hd->ipc_host.direction == SOF_IPC_STREAM_PLAYBACK) { - source = buffer_acquire(hd->dma_buffer); - sink = buffer_acquire(hd->local_buffer); + if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { + source = hd->dma_buffer; + sink = hd->local_buffer; ret = dma_buffer_copy_from(source, sink, hd->process, bytes); } else { - source = buffer_acquire(hd->local_buffer); - sink = buffer_acquire(hd->dma_buffer); + source = hd->local_buffer; + sink = hd->dma_buffer; ret = dma_buffer_copy_to(source, sink, hd->process, bytes); } - /* assert dma_buffer_copy succeed */ - if (ret < 0) - comp_err(dev, "host_common_update() dma buffer copy failed, dir %d bytes %d avail %d free %d", - hd->ipc_host.direction, bytes, - audio_stream_get_avail_samples(&source->stream) * - audio_stream_frame_bytes(&source->stream), - audio_stream_get_free_samples(&sink->stream) * - audio_stream_frame_bytes(&sink->stream)); - - buffer_release(sink); - buffer_release(source); - - if (ret < 0) + if (ret < 0) { + comp_err(dev, "host_common_update() copy failed, dir %d bytes %d return: %d", + dev->direction, bytes, ret); return; + } hd->total_data_processed += bytes; @@ -379,8 +360,6 @@ static void host_dma_cb(struct comp_dev *dev, size_t bytes) static uint32_t host_get_copy_bytes_normal(struct host_data *hd, struct comp_dev *dev) { struct comp_buffer *buffer = hd->local_buffer; - struct comp_buffer __sparse_cache *buffer_c; - struct comp_buffer __sparse_cache *dma_buf_c; struct dma_status dma_stat; uint32_t avail_samples; uint32_t free_samples; @@ -397,18 +376,14 @@ static uint32_t host_get_copy_bytes_normal(struct host_data *hd, struct comp_dev return 0; } - dma_buf_c = buffer_acquire(hd->dma_buffer); - dma_sample_bytes = get_sample_bytes(audio_stream_get_frm_fmt(&dma_buf_c->stream)); - buffer_release(dma_buf_c); - - buffer_c = buffer_acquire(buffer); + dma_sample_bytes = hd->config.src_width; /* calculate minimum size to copy */ if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { avail_samples = (dma_stat.pending_length - hd->partial_size) / dma_sample_bytes; - free_samples = audio_stream_get_free_samples(&buffer_c->stream); + free_samples = audio_stream_get_free_samples(&buffer->stream); } else { - avail_samples = audio_stream_get_avail_samples(&buffer_c->stream); + avail_samples = audio_stream_get_avail_samples(&buffer->stream); free_samples = (dma_stat.free - hd->partial_size) / dma_sample_bytes; } @@ -425,8 +400,6 @@ static uint32_t host_get_copy_bytes_normal(struct host_data *hd, struct comp_dev comp_info(dev, "no bytes to copy, available samples: %d, free_samples: %d", avail_samples, free_samples); - buffer_release(buffer_c); - /* dma_copy_bytes should be aligned to minimum possible chunk of * data to be copied by dma. */ @@ -464,7 +437,6 @@ static inline bool stream_sync(struct host_data *hd, struct comp_dev *dev) */ static int host_copy_normal(struct host_data *hd, struct comp_dev *dev, copy_callback_t cb) { - struct comp_buffer __sparse_cache *buffer_c; uint32_t copy_bytes; const unsigned int threshold = #if CONFIG_HOST_DMA_RELOAD_DELAY_ENABLE @@ -482,7 +454,6 @@ static int host_copy_normal(struct host_data *hd, struct comp_dev *dev, copy_cal cb(dev, copy_bytes); hd->partial_size += copy_bytes; - buffer_c = buffer_acquire(hd->dma_buffer); /* * On large buffers we don't need to reload DMA on every period. When @@ -491,8 +462,8 @@ static int host_copy_normal(struct host_data *hd, struct comp_dev *dev, copy_cal * also adding a 2ms safety margin. */ if (!IS_ENABLED(CONFIG_HOST_DMA_RELOAD_DELAY_ENABLE) || - audio_stream_get_size(&buffer_c->stream) < hd->period_bytes << 3 || - audio_stream_get_size(&buffer_c->stream) - hd->partial_size <= + hd->dma_buffer_size < hd->period_bytes << 3 || + hd->dma_buffer_size - hd->partial_size <= (2 + threshold) * hd->period_bytes) { if (stream_sync(hd, dev)) { ret = dma_reload(hd->chan->dma->z_dev, hd->chan->index, 0, 0, @@ -503,16 +474,12 @@ static int host_copy_normal(struct host_data *hd, struct comp_dev *dev, copy_cal hd->partial_size = 0; } } - - buffer_release(buffer_c); - return ret; } static int create_local_elems(struct host_data *hd, struct comp_dev *dev, uint32_t buffer_count, uint32_t buffer_bytes, uint32_t direction) { - struct comp_buffer __sparse_cache *dma_buf_c; struct dma_sg_elem_array *elem_array; uint32_t dir; int err; @@ -535,11 +502,9 @@ static int create_local_elems(struct host_data *hd, struct comp_dev *dev, uint32 elem_array = &hd->config.elem_array; } - dma_buf_c = buffer_acquire(hd->dma_buffer); err = dma_sg_alloc(elem_array, SOF_MEM_ZONE_RUNTIME, dir, buffer_count, buffer_bytes, - (uintptr_t)audio_stream_get_addr(&dma_buf_c->stream), 0); - buffer_release(dma_buf_c); + (uintptr_t)audio_stream_get_addr(&hd->dma_buffer->stream), 0); if (err < 0) { comp_err(dev, "create_local_elems(): dma_sg_alloc() failed"); return err; @@ -759,8 +724,6 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, struct dma_sg_elem *sg_elem; struct dma_config *dma_cfg = &hd->z_config; struct dma_block_config dma_block_cfg; - struct comp_buffer __sparse_cache *host_buf_c; - struct comp_buffer __sparse_cache *dma_buf_c; uint32_t period_count; uint32_t period_bytes; uint32_t buffer_size; @@ -809,14 +772,12 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, hd->local_buffer = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - host_buf_c = buffer_acquire(hd->local_buffer); period_bytes = dev->frames * get_frame_bytes(params->frame_fmt, params->channels); if (!period_bytes) { comp_err(dev, "host_params(): invalid period_bytes"); - err = -EINVAL; - goto out; + return -EINVAL; } /* determine source and sink buffer elements */ @@ -848,46 +809,43 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, * but we have to write back caches after we finish anywae */ if (hd->dma_buffer) { - dma_buf_c = buffer_acquire(hd->dma_buffer); - err = buffer_set_size(dma_buf_c, buffer_size, addr_align); - buffer_release(dma_buf_c); + err = buffer_set_size(hd->dma_buffer, buffer_size, addr_align); if (err < 0) { comp_err(dev, "host_params(): buffer_set_size() failed, buffer_size = %u", buffer_size); - goto out; + return err; } } else { + /* allocate not shared buffer */ hd->dma_buffer = buffer_alloc(buffer_size, SOF_MEM_CAPS_DMA, 0, - addr_align); + addr_align, false); if (!hd->dma_buffer) { comp_err(dev, "host_params(): failed to alloc dma buffer"); - err = -ENOMEM; - goto out; + return -ENOMEM; } - dma_buf_c = buffer_acquire(hd->dma_buffer); - buffer_set_params(dma_buf_c, params, BUFFER_UPDATE_FORCE); + buffer_set_params(hd->dma_buffer, params, BUFFER_UPDATE_FORCE); /* set processing function */ if (params->direction == SOF_IPC_STREAM_CAPTURE) hd->process = pcm_get_conversion_function( - audio_stream_get_frm_fmt(&host_buf_c->stream), - audio_stream_get_frm_fmt(&dma_buf_c->stream)); + audio_stream_get_frm_fmt(&hd->local_buffer->stream), + audio_stream_get_frm_fmt(&hd->dma_buffer->stream)); else hd->process = pcm_get_conversion_function( - audio_stream_get_frm_fmt(&dma_buf_c->stream), - audio_stream_get_frm_fmt(&host_buf_c->stream)); + audio_stream_get_frm_fmt(&hd->dma_buffer->stream), + audio_stream_get_frm_fmt(&hd->local_buffer->stream)); - config->src_width = audio_stream_sample_bytes(&dma_buf_c->stream); + config->src_width = audio_stream_sample_bytes(&hd->dma_buffer->stream); config->dest_width = config->src_width; - buffer_release(dma_buf_c); + hd->dma_buffer_size = audio_stream_get_size(&hd->dma_buffer->stream); } /* create SG DMA elems for local DMA buffer */ err = create_local_elems(hd, dev, period_count, buffer_size / period_count, params->direction); if (err < 0) - goto out; + return err; /* set up DMA configuration - copy in sample bytes. */ config->cyclic = 0; @@ -905,8 +863,7 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, channel = dma_request_channel(hd->dma->z_dev, &hda_chan); if (channel < 0) { comp_err(dev, "host_params(): requested channel %d is busy", hda_chan); - err = -ENODEV; - goto out; + return -ENODEV; } hd->chan = &hd->dma->chan[channel]; @@ -960,7 +917,7 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, comp_err(dev, "host_params(): dma_config() failed"); dma_release_channel(hd->dma->z_dev, hd->chan->index); hd->chan = NULL; - goto out; + return err; } err = dma_get_attribute(hd->dma->z_dev, DMA_ATTR_COPY_ALIGNMENT, @@ -968,8 +925,7 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, if (err < 0) { comp_err(dev, "host_params(): dma_get_attribute()"); - - goto out; + return err; } /* minimal copied data shouldn't be less than alignment */ @@ -982,9 +938,7 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev, hd->copy = hd->copy_type == COMP_COPY_ONE_SHOT ? host_copy_one_shot : host_copy_normal; -out: - buffer_release(host_buf_c); - return err; + return 0; } static int host_params(struct comp_dev *dev, @@ -1006,11 +960,7 @@ static int host_params(struct comp_dev *dev, int host_common_prepare(struct host_data *hd) { - struct comp_buffer __sparse_cache *buf_c = buffer_acquire(hd->dma_buffer); - - buffer_zero(buf_c); - buffer_release(buf_c); - + buffer_zero(hd->dma_buffer); return 0; } diff --git a/src/audio/igo_nr/igo_nr.c b/src/audio/igo_nr/igo_nr.c index 7ee3884bd023..19d0cc01db46 100644 --- a/src/audio/igo_nr/igo_nr.c +++ b/src/audio/igo_nr/igo_nr.c @@ -66,8 +66,8 @@ static void igo_nr_lib_process(struct comp_data *cd) #if CONFIG_FORMAT_S16LE static void igo_nr_capture_s16(struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, int32_t frames) { int32_t nch = audio_stream_get_channels(source); @@ -125,8 +125,8 @@ static void igo_nr_capture_s16(struct comp_data *cd, #if CONFIG_FORMAT_S24LE static void igo_nr_capture_s24(struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, int32_t frames) { int32_t nch = audio_stream_get_channels(source); @@ -184,8 +184,8 @@ static void igo_nr_capture_s24(struct comp_data *cd, #if CONFIG_FORMAT_S32LE static void igo_nr_capture_s32(struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, int32_t frames) { int32_t nch = audio_stream_get_channels(source); @@ -379,7 +379,6 @@ static int32_t igo_nr_params(struct comp_dev *dev, { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *sinkb, *sourceb; - struct comp_buffer __sparse_cache *sink_c, *source_c; int32_t err; comp_info(dev, "igo_nr_params()"); @@ -395,22 +394,16 @@ static int32_t igo_nr_params(struct comp_dev *dev, sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - /* set source/sink_frames/rate */ - cd->source_rate = audio_stream_get_rate(&source_c->stream); - cd->sink_rate = audio_stream_get_rate(&sink_c->stream); + cd->source_rate = audio_stream_get_rate(&sourceb->stream); + cd->sink_rate = audio_stream_get_rate(&sinkb->stream); - if (audio_stream_get_channels(&source_c->stream) != - audio_stream_get_channels(&sink_c->stream)) { + if (audio_stream_get_channels(&sourceb->stream) != + audio_stream_get_channels(&sinkb->stream)) { comp_err(dev, "igo_nr_params(), mismatch source/sink stream channels"); cd->invalid_param = true; } - buffer_release(sink_c); - buffer_release(source_c); - if (!cd->sink_rate) { comp_err(dev, "igo_nr_params(), zero sink rate"); return -EINVAL; @@ -619,8 +612,8 @@ static int32_t igo_nr_cmd(struct comp_dev *dev, } static void igo_nr_process(struct comp_dev *dev, - struct comp_buffer __sparse_cache *source, - struct comp_buffer __sparse_cache *sink, + struct comp_buffer *source, + struct comp_buffer *sink, struct comp_copy_limits *cl, int32_t frames) @@ -701,7 +694,6 @@ static int32_t igo_nr_copy(struct comp_dev *dev) { struct comp_copy_limits cl; struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; struct comp_data *cd = comp_get_drvdata(dev); int32_t src_frames; int32_t sink_frames; @@ -713,27 +705,21 @@ static int32_t igo_nr_copy(struct comp_dev *dev) sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - /* Check for changed configuration */ if (comp_is_new_data_blob_available(cd->model_handler)) igo_nr_set_igo_params(dev); /* Get source, sink, number of frames etc. to process. */ - comp_get_copy_limits(source_c, sink_c, &cl); + comp_get_copy_limits(sourceb, sinkb, &cl); - src_frames = audio_stream_get_avail_frames(&source_c->stream); - sink_frames = audio_stream_get_free_frames(&sink_c->stream); + src_frames = audio_stream_get_avail_frames(&sourceb->stream); + sink_frames = audio_stream_get_free_frames(&sinkb->stream); comp_dbg(dev, "src_frames = %d, sink_frames = %d.", src_frames, sink_frames); /* Process only when frames count is enough. */ if (src_frames >= IGO_FRAME_SIZE && sink_frames >= IGO_FRAME_SIZE) - igo_nr_process(dev, source_c, sink_c, &cl, IGO_FRAME_SIZE); - - buffer_release(sink_c); - buffer_release(source_c); + igo_nr_process(dev, sourceb, sinkb, &cl, IGO_FRAME_SIZE); return 0; } diff --git a/src/audio/kpb.c b/src/audio/kpb.c index dee693d6fd9d..48bc6bd3eeec 100644 --- a/src/audio/kpb.c +++ b/src/audio/kpb.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +107,8 @@ struct comp_data { uint32_t num_of_in_channels; uint32_t offsets[KPB_MAX_MICSEL_CHANNELS]; struct kpb_micselector_config mic_sel; + struct kpb_fmt_dev_list fmt_device_list; + struct fast_mode_task fmt; #if CONFIG_AMS uint32_t kpd_uuid_id; @@ -120,18 +123,18 @@ static int kpb_register_client(struct comp_data *kpb, struct kpb_client *cli); static void kpb_init_draining(struct comp_dev *dev, struct kpb_client *cli); static enum task_state kpb_draining_task(void *arg); static int kpb_buffer_data(struct comp_dev *dev, - const struct comp_buffer __sparse_cache *source, size_t size); + const struct comp_buffer *source, size_t size); static size_t kpb_allocate_history_buffer(struct comp_data *kpb, size_t hb_size_req); static void kpb_clear_history_buffer(struct history_buffer *buff); static void kpb_free_history_buffer(struct history_buffer *buff); static inline bool kpb_is_sample_width_supported(uint32_t sampling_width); -static void kpb_copy_samples(struct comp_buffer __sparse_cache *sink, - struct comp_buffer __sparse_cache *source, size_t size, +static void kpb_copy_samples(struct comp_buffer *sink, + struct comp_buffer *source, size_t size, size_t sample_width, uint32_t channels); -static void kpb_drain_samples(void *source, struct audio_stream __sparse_cache *sink, +static void kpb_drain_samples(void *source, struct audio_stream *sink, size_t size, size_t sample_width); -static void kpb_buffer_samples(const struct audio_stream __sparse_cache *source, +static void kpb_buffer_samples(const struct audio_stream *source, int offset, void *sink, size_t size, size_t sample_width); static void kpb_reset_history_buffer(struct history_buffer *buff); @@ -141,6 +144,23 @@ static inline bool validate_host_params(struct comp_dev *dev, size_t hb_size_req); static inline void kpb_change_state(struct comp_data *kpb, enum kpb_state state); +#ifdef CONFIG_IPC_MAJOR_4 +/* KpbFastModeTaskModulesList Namespace */ +static inline int alloc_fmt_module_list_item(struct kpb_fmt_dev_list *fmt_device_list, + struct comp_dev *mi_ptr, struct comp_dev ***item); +static int clear_fmt_modules_list(struct kpb_fmt_dev_list *fmt_device_list, + uint32_t outpin_idx); +static int prepare_fmt_modules_list(struct comp_dev *kpb_dev, uint32_t outpin_idx, + const struct kpb_task_params *modules_to_prepare); +/* FMT Namespace */ +static int register_modules_list(struct fast_mode_task *fmt, + struct device_list *new_list, size_t list_idx); +static int unregister_modules_list(struct fast_mode_task *fmt, + struct device_list *list_to_remove, size_t list_idx); +/* Devicelist */ +static int devicelist_push(struct device_list *devlist, struct comp_dev **dev); +static void devicelist_reset(struct device_list *devlist, bool remove_items); +#endif static uint64_t kpb_task_deadline(void *data) { @@ -330,17 +350,14 @@ static int kpb_bind(struct comp_dev *dev, void *data) list_for_item(blist, &dev->bsink_list) { struct comp_buffer *sink = container_of(blist, struct comp_buffer, source_list); - struct comp_buffer __sparse_cache *sink_c = buffer_acquire(sink); int sink_buf_id; - if (!sink_c->sink) { + if (!sink->sink) { ret = -EINVAL; - buffer_release(sink_c); break; } - sink_buf_id = sink_c->id; - buffer_release(sink_c); + sink_buf_id = sink->id; if (sink_buf_id == buf_id) { if (sink_buf_id == 0) @@ -376,7 +393,8 @@ static int kpb_unbind(struct comp_dev *dev, void *data) else kpb->host_sink = NULL; - return 0; + /* Clear fmt config */ + return clear_fmt_modules_list(&kpb->fmt_device_list, bu->extension.r.src_queue); } #else /* CONFIG_IPC_MAJOR_4 */ @@ -848,17 +866,13 @@ static int kpb_prepare(struct comp_dev *dev) list_for_item(blist, &dev->bsink_list) { struct comp_buffer *sink = container_of(blist, struct comp_buffer, source_list); - struct comp_buffer __sparse_cache *sink_c = buffer_acquire(sink); enum sof_comp_type type; - if (!sink_c->sink) { + if (!sink->sink) { ret = -EINVAL; - buffer_release(sink_c); break; } - - type = dev_comp_type(sink_c->sink); - buffer_release(sink_c); + type = dev_comp_type(sink->sink); switch (type) { case SOF_COMP_SELECTOR: @@ -886,18 +900,15 @@ static int kpb_prepare(struct comp_dev *dev) list_for_item(sink_list, &dev->bsink_list) { struct comp_buffer *sink = container_of(sink_list, struct comp_buffer, source_list); - struct comp_buffer __sparse_cache *sink_c = buffer_acquire(sink); audio_stream_init_alignment_constants(byte_align, frame_align_req, - &sink_c->stream); - sink_id = sink_c->id; + &sink->stream); + sink_id = sink->id; if (sink_id == 0) - audio_stream_set_channels(&sink_c->stream, kpb->num_of_sel_mic); + audio_stream_set_channels(&sink->stream, kpb->num_of_sel_mic); else - audio_stream_set_channels(&sink_c->stream, kpb->config.channels); - - buffer_release(sink_c); + audio_stream_set_channels(&sink->stream, kpb->config.channels); } } #endif /* CONFIG_IPC_MAJOR_4 */ @@ -991,12 +1002,12 @@ static int kpb_reset(struct comp_dev *dev) #ifdef KPB_HIFI3 #if CONFIG_FORMAT_S16LE -static void kpb_micselect_copy16(struct comp_buffer __sparse_cache *sink, - struct comp_buffer __sparse_cache *source, size_t size, +static void kpb_micselect_copy16(struct comp_buffer *sink, + struct comp_buffer *source, size_t size, uint32_t in_channels, uint32_t micsel_channels, uint32_t *offsets) { - struct audio_stream __sparse_cache *istream = &source->stream; - struct audio_stream __sparse_cache *ostream = &sink->stream; + struct audio_stream *istream = &source->stream; + struct audio_stream *ostream = &sink->stream; uint16_t ch; size_t i; @@ -1024,12 +1035,12 @@ static void kpb_micselect_copy16(struct comp_buffer __sparse_cache *sink, } #endif #if CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE -static void kpb_micselect_copy32(struct comp_buffer __sparse_cache *sink, - struct comp_buffer __sparse_cache *source, size_t size, +static void kpb_micselect_copy32(struct comp_buffer *sink, + struct comp_buffer *source, size_t size, uint32_t in_channels, uint32_t micsel_channels, uint32_t *offsets) { - struct audio_stream __sparse_cache *istream = &source->stream; - struct audio_stream __sparse_cache *ostream = &sink->stream; + struct audio_stream *istream = &source->stream; + struct audio_stream *ostream = &sink->stream; uint16_t ch; size_t i; @@ -1058,12 +1069,12 @@ static void kpb_micselect_copy32(struct comp_buffer __sparse_cache *sink, } #endif #else -static void kpb_micselect_copy16(struct comp_buffer __sparse_cache *sink, - struct comp_buffer __sparse_cache *source, size_t size, +static void kpb_micselect_copy16(struct comp_buffer *sink, + struct comp_buffer *source, size_t size, uint32_t in_channels, uint32_t micsel_channels, uint32_t *offsets) { - struct audio_stream __sparse_cache *istream = &source->stream; - struct audio_stream __sparse_cache *ostream = &sink->stream; + struct audio_stream *istream = &source->stream; + struct audio_stream *ostream = &sink->stream; buffer_stream_invalidate(source, size); size_t out_samples; @@ -1090,12 +1101,12 @@ static void kpb_micselect_copy16(struct comp_buffer __sparse_cache *sink, } } -static void kpb_micselect_copy32(struct comp_buffer __sparse_cache *sink, - struct comp_buffer __sparse_cache *source, size_t size, +static void kpb_micselect_copy32(struct comp_buffer *sink, + struct comp_buffer *source, size_t size, uint32_t in_channels, uint32_t micsel_channels, uint32_t *offsets) { - struct audio_stream __sparse_cache *istream = &source->stream; - struct audio_stream __sparse_cache *ostream = &sink->stream; + struct audio_stream *istream = &source->stream; + struct audio_stream *ostream = &sink->stream; buffer_stream_invalidate(source, size); size_t out_samples; @@ -1121,8 +1132,8 @@ static void kpb_micselect_copy32(struct comp_buffer __sparse_cache *sink, } } #endif -static void kpb_micselect_copy(struct comp_dev *dev, struct comp_buffer __sparse_cache *sink_c, - struct comp_buffer __sparse_cache *source_c, size_t copy_bytes, +static void kpb_micselect_copy(struct comp_dev *dev, struct comp_buffer *sink_c, + struct comp_buffer *source_c, size_t copy_bytes, uint32_t channels) { struct comp_data *kpb = comp_get_drvdata(dev); @@ -1167,7 +1178,6 @@ static int kpb_copy(struct comp_dev *dev) int ret = 0; struct comp_data *kpb = comp_get_drvdata(dev); struct comp_buffer *source, *sink; - struct comp_buffer __sparse_cache *source_c, *sink_c = NULL; size_t copy_bytes = 0, produced_bytes = 0; size_t sample_width = kpb->config.sampling_width; struct draining_data *dd = &kpb->draining_task_data; @@ -1185,13 +1195,11 @@ static int kpb_copy(struct comp_dev *dev) source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - source_c = buffer_acquire(source); - /* Validate source */ - if (!audio_stream_get_rptr(&source_c->stream)) { + if (!audio_stream_get_rptr(&source->stream)) { comp_err(dev, "kpb_copy(): invalid source pointers."); ret = -EINVAL; - goto out; + return ret; } switch (kpb->state) { @@ -1206,29 +1214,27 @@ static int kpb_copy(struct comp_dev *dev) break; } - sink_c = buffer_acquire(sink); - /* Validate sink */ - if (!audio_stream_get_wptr(&sink_c->stream)) { + if (!audio_stream_get_wptr(&sink->stream)) { comp_err(dev, "kpb_copy(): invalid selector sink pointers."); ret = -EINVAL; break; } - copy_bytes = audio_stream_get_copy_bytes(&source_c->stream, &sink_c->stream); + copy_bytes = audio_stream_get_copy_bytes(&source->stream, &sink->stream); if (!copy_bytes) { comp_err(dev, "kpb_copy(): nothing to copy sink->free %d source->avail %d", - audio_stream_get_free_bytes(&sink_c->stream), - audio_stream_get_avail_bytes(&source_c->stream)); + audio_stream_get_free_bytes(&sink->stream), + audio_stream_get_avail_bytes(&source->stream)); ret = PPL_STATUS_PATH_STOP; break; } if (kpb->num_of_sel_mic == 0) { - kpb_copy_samples(sink_c, source_c, copy_bytes, sample_width, channels); + kpb_copy_samples(sink, source, copy_bytes, sample_width, channels); } else { - uint32_t avail = audio_stream_get_avail_bytes(&source_c->stream); - uint32_t free = audio_stream_get_free_bytes(&sink_c->stream); + uint32_t avail = audio_stream_get_avail_bytes(&source->stream); + uint32_t free = audio_stream_get_free_bytes(&sink->stream); copy_bytes = MIN(avail, free * channels / kpb->num_of_sel_mic); copy_bytes = ROUND_DOWN(copy_bytes, (sample_width >> 3) * channels); @@ -1244,13 +1250,13 @@ static int kpb_copy(struct comp_dev *dev) ret = PPL_STATUS_PATH_STOP; break; } - kpb_micselect_copy(dev, sink_c, source_c, produced_bytes, channels); + kpb_micselect_copy(dev, sink, source, produced_bytes, channels); } /* Buffer source data internally in history buffer for future * use by clients. */ if (copy_bytes <= kpb->hd.buffer_size) { - ret = kpb_buffer_data(dev, source_c, copy_bytes); + ret = kpb_buffer_data(dev, source, copy_bytes); if (ret) { comp_err(dev, "kpb_copy(): internal buffering failed."); @@ -1269,11 +1275,11 @@ static int kpb_copy(struct comp_dev *dev) } if (kpb->num_of_sel_mic == 0) - comp_update_buffer_produce(sink_c, copy_bytes); + comp_update_buffer_produce(sink, copy_bytes); else - comp_update_buffer_produce(sink_c, produced_bytes); + comp_update_buffer_produce(sink, produced_bytes); - comp_update_buffer_consume(source_c, copy_bytes); + comp_update_buffer_consume(source, copy_bytes); break; case KPB_STATE_HOST_COPY: @@ -1286,20 +1292,18 @@ static int kpb_copy(struct comp_dev *dev) break; } - sink_c = buffer_acquire(sink); - /* Validate sink */ - if (!audio_stream_get_wptr(&sink_c->stream)) { + if (!audio_stream_get_wptr(&sink->stream)) { comp_err(dev, "kpb_copy(): invalid host sink pointers."); ret = -EINVAL; break; } - copy_bytes = audio_stream_get_copy_bytes(&source_c->stream, &sink_c->stream); + copy_bytes = audio_stream_get_copy_bytes(&source->stream, &sink->stream); if (!copy_bytes) { comp_err(dev, "kpb_copy(): nothing to copy sink->free %d source->avail %d", - audio_stream_get_free_bytes(&sink_c->stream), - audio_stream_get_avail_bytes(&source_c->stream)); + audio_stream_get_free_bytes(&sink->stream), + audio_stream_get_avail_bytes(&source->stream)); /* NOTE! We should stop further pipeline copy due to * no data availability however due to HW bug * (no HOST DMA IRQs) we need to call host copy @@ -1308,10 +1312,10 @@ static int kpb_copy(struct comp_dev *dev) break; } - kpb_copy_samples(sink_c, source_c, copy_bytes, sample_width, channels); + kpb_copy_samples(sink, source, copy_bytes, sample_width, channels); - comp_update_buffer_produce(sink_c, copy_bytes); - comp_update_buffer_consume(source_c, copy_bytes); + comp_update_buffer_produce(sink, copy_bytes); + comp_update_buffer_consume(source, copy_bytes); break; case KPB_STATE_INIT_DRAINING: @@ -1319,12 +1323,12 @@ static int kpb_copy(struct comp_dev *dev) /* In draining and init draining we only buffer data in * the internal history buffer. */ - avail_bytes = audio_stream_get_avail_bytes(&source_c->stream); + avail_bytes = audio_stream_get_avail_bytes(&source->stream); copy_bytes = MIN(avail_bytes, kpb->hd.free); ret = PPL_STATUS_PATH_STOP; if (copy_bytes) { - buffer_stream_invalidate(source_c, copy_bytes); - ret = kpb_buffer_data(dev, source_c, copy_bytes); + buffer_stream_invalidate(source, copy_bytes); + ret = kpb_buffer_data(dev, source, copy_bytes); dd->buffered_while_draining += copy_bytes; kpb->hd.free -= copy_bytes; @@ -1333,10 +1337,10 @@ static int kpb_copy(struct comp_dev *dev) break; } - comp_update_buffer_consume(source_c, copy_bytes); + comp_update_buffer_consume(source, copy_bytes); } else { comp_warn(dev, "kpb_copy(): buffering skipped (no data to copy, avail %d, free %d", - audio_stream_get_avail_bytes(&source_c->stream), + audio_stream_get_avail_bytes(&source->stream), kpb->hd.free); } @@ -1348,11 +1352,6 @@ static int kpb_copy(struct comp_dev *dev) break; } -out: - if (sink_c) - buffer_release(sink_c); - buffer_release(source_c); - return ret; } @@ -1365,7 +1364,7 @@ static int kpb_copy(struct comp_dev *dev) * */ static int kpb_buffer_data(struct comp_dev *dev, - const struct comp_buffer __sparse_cache *source, size_t size) + const struct comp_buffer *source, size_t size) { int ret = 0; size_t size_to_copy = size; @@ -1729,7 +1728,7 @@ static void kpb_init_draining(struct comp_dev *dev, struct kpb_client *cli) static enum task_state kpb_draining_task(void *arg) { struct draining_data *draining_data = (struct draining_data *)arg; - struct comp_buffer __sparse_cache *sink = buffer_acquire(draining_data->sink); + struct comp_buffer *sink = draining_data->sink; struct history_buffer *buff = draining_data->hb; size_t drain_req = draining_data->drain_req; size_t sample_width = draining_data->sample_width; @@ -1859,13 +1858,9 @@ static enum task_state kpb_draining_task(void *arg) out: draining_time_end = sof_cycle_get_64(); - buffer_release(sink); - /* Reset host-sink copy mode back to its pre-draining value */ - sink = buffer_acquire(kpb->host_sink); - comp_set_attribute(sink->sink, COMP_ATTR_COPY_TYPE, + comp_set_attribute(kpb->host_sink->sink, COMP_ATTR_COPY_TYPE, &kpb->draining_task_data.copy_type); - buffer_release(sink); draining_time_ms = k_cyc_to_ms_near64(draining_time_end - draining_time_start); if (draining_time_ms <= UINT_MAX) @@ -1880,7 +1875,7 @@ static enum task_state kpb_draining_task(void *arg) #ifdef KPB_HIFI3 static void kpb_convert_24b_to_32b(const void *linear_source, int ioffset, - struct audio_stream __sparse_cache *sink, int ooffset, + struct audio_stream *sink, int ooffset, unsigned int n_samples) { int ssize = audio_stream_sample_bytes(sink); @@ -1928,7 +1923,7 @@ static void kpb_convert_24b_to_32b(const void *linear_source, int ioffset, } #else static void kpb_convert_24b_to_32b(const void *source, int ioffset, - struct audio_stream __sparse_cache *sink, + struct audio_stream *sink, int ooffset, unsigned int samples) { int ssize = audio_stream_sample_bytes(sink); @@ -1960,7 +1955,7 @@ static void kpb_convert_24b_to_32b(const void *source, int ioffset, * * \return none. */ -static void kpb_drain_samples(void *source, struct audio_stream __sparse_cache *sink, +static void kpb_drain_samples(void *source, struct audio_stream *sink, size_t size, size_t sample_width) { unsigned int samples; @@ -1989,7 +1984,7 @@ static void kpb_drain_samples(void *source, struct audio_stream __sparse_cache * } #ifdef KPB_HIFI3 -static void kpb_convert_32b_to_24b(const struct audio_stream __sparse_cache *source, int ioffset, +static void kpb_convert_32b_to_24b(const struct audio_stream *source, int ioffset, void *linear_sink, int ooffset, unsigned int n_samples) { int ssize = audio_stream_sample_bytes(source); @@ -2027,7 +2022,7 @@ static void kpb_convert_32b_to_24b(const struct audio_stream __sparse_cache *sou } } #else -static void kpb_convert_32b_to_24b(const struct audio_stream __sparse_cache *source, int ioffset, +static void kpb_convert_32b_to_24b(const struct audio_stream *source, int ioffset, void *sink, int ooffset, unsigned int samples) { int ssize = audio_stream_sample_bytes(source); @@ -2060,7 +2055,7 @@ static void kpb_convert_32b_to_24b(const struct audio_stream __sparse_cache *sou * \param[in] size Requested copy size in bytes. * \param[in] sample_width Sample size. */ -static void kpb_buffer_samples(const struct audio_stream __sparse_cache *source, +static void kpb_buffer_samples(const struct audio_stream *source, int offset, void *sink, size_t size, size_t sample_width) { @@ -2147,8 +2142,8 @@ static inline bool kpb_is_sample_width_supported(uint32_t sampling_width) } #ifdef KPB_HIFI3 -static void kpb_copy_24b_in_32b(const struct audio_stream __sparse_cache *source, uint32_t ioffset, - struct audio_stream __sparse_cache *sink, uint32_t ooffset, +static void kpb_copy_24b_in_32b(const struct audio_stream *source, uint32_t ioffset, + struct audio_stream *sink, uint32_t ooffset, uint32_t n_samples) { int ssize = audio_stream_sample_bytes(source); /* src fmt == sink fmt */ @@ -2181,8 +2176,8 @@ static void kpb_copy_24b_in_32b(const struct audio_stream __sparse_cache *source } } #else -static void kpb_copy_24b_in_32b(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static void kpb_copy_24b_in_32b(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -2217,12 +2212,12 @@ static void kpb_copy_24b_in_32b(const struct audio_stream __sparse_cache *source * * \return none. */ -static void kpb_copy_samples(struct comp_buffer __sparse_cache *sink, - struct comp_buffer __sparse_cache *source, size_t size, +static void kpb_copy_samples(struct comp_buffer *sink, + struct comp_buffer *source, size_t size, size_t sample_width, uint32_t channels) { - struct audio_stream __sparse_cache *istream = &source->stream; - struct audio_stream __sparse_cache *ostream = &sink->stream; + struct audio_stream *istream = &source->stream; + struct audio_stream *ostream = &sink->stream; unsigned int samples; buffer_stream_invalidate(source, size); @@ -2378,15 +2373,196 @@ static int kpb_set_micselect(struct comp_dev *dev, const void *data, return 0; } +#ifdef CONFIG_IPC_MAJOR_4 + +static int devicelist_push(struct device_list *devlist, struct comp_dev **dev) +{ + if (devlist->count != DEVICE_LIST_SIZE) { + devlist->devs[devlist->count] = dev; + devlist->count++; + return 0; + } + return -EINVAL; +} + +static void devicelist_reset(struct device_list *devlist, bool remove_items) +{ + /* clear items */ + if (remove_items) { + for (int i = 0; i < DEVICE_LIST_SIZE; i++) + *devlist->devs[i] = NULL; + } + /* zero the pointers */ + for (int i = 0; i < DEVICE_LIST_SIZE; i++) + devlist->devs[i] = NULL; + + devlist->count = 0; +} + +static inline int alloc_fmt_module_list_item(struct kpb_fmt_dev_list *fmt_device_list, + struct comp_dev *mi_ptr, struct comp_dev ***item) +{ + /* -1 means we did not find the slot yet */ + int first_empty_slot_idx = -1; + + for (size_t module_slot_idx = 0; module_slot_idx < FAST_MODE_TASK_MAX_MODULES_COUNT; + ++module_slot_idx){ + /* check if module already added */ + if (fmt_device_list->modules_list_item[module_slot_idx] == mi_ptr) + return -EINVAL; + /* finding first available empty slot */ + if (first_empty_slot_idx < 0 && + !fmt_device_list->modules_list_item[module_slot_idx]) + first_empty_slot_idx = module_slot_idx; + } + /* add item to first available empty slot */ + if (first_empty_slot_idx >= 0) { + fmt_device_list->modules_list_item[first_empty_slot_idx] = mi_ptr; + *item = &fmt_device_list->modules_list_item[first_empty_slot_idx]; + return 0; + } + return -ENOMEM; +} + +static int prepare_fmt_modules_list(struct comp_dev *kpb_dev, + uint32_t outpin_idx, + const struct kpb_task_params *modules_to_prepare) +{ + int ret; + struct comp_dev *dev; + struct kpb_fmt_dev_list *fmt_device_list = + &((struct comp_data *)comp_get_drvdata(kpb_dev))->fmt_device_list; + + fmt_device_list->kpb_list_item[outpin_idx] = kpb_dev; + ret = devicelist_push(&fmt_device_list->device_list[outpin_idx], + &fmt_device_list->kpb_list_item[outpin_idx]); + if (ret < 0) + return ret; + + for (size_t mod_idx = 0; mod_idx < modules_to_prepare->number_of_modules; ++mod_idx) { + uint32_t comp_id = IPC4_COMP_ID(modules_to_prepare->dev_ids[mod_idx].module_id, + modules_to_prepare->dev_ids[mod_idx].instance_id); + + dev = ipc4_get_comp_dev(comp_id); + if (!dev) + return -EINVAL; + + struct comp_dev **new_list_item_ptr; + + ret = alloc_fmt_module_list_item(fmt_device_list, dev, &new_list_item_ptr); + if (ret < 0) + return ret; + *new_list_item_ptr = dev; + ret = devicelist_push(&fmt_device_list->device_list[outpin_idx], + new_list_item_ptr); + if (ret < 0) + return ret; + } + return 0; +} + +static int clear_fmt_modules_list(struct kpb_fmt_dev_list *fmt_device_list, + uint32_t outpin_idx) +{ + if (outpin_idx >= KPB_MAX_SINK_CNT) + return -EINVAL; + + devicelist_reset(&fmt_device_list->device_list[outpin_idx], true); + return 0; +} + +static int unregister_modules_list(struct fast_mode_task *fmt, + struct device_list *list_to_remove, size_t list_idx) +{ + if (list_to_remove == fmt->device_list[list_idx]) { + fmt->device_list[list_idx] = NULL; + return 0; + } + if (!fmt->device_list[list_idx]) { + /* Nothing to do here */ + return 0; + } + return -EINVAL; +} + +/* Comment from Old FW, may be outdated: + * Important: function below should be called only from within critical section + * (Goto KPB for more details) + */ +static int register_modules_list(struct fast_mode_task *fmt, + struct device_list *new_list, size_t list_idx) +{ + if (list_idx >= ARRAY_SIZE(fmt->device_list)) + return -EINVAL; + + /* Check if slot is free */ + if (!fmt->device_list[list_idx]) { + fmt->device_list[list_idx] = new_list; + return 0; + } + if (new_list == fmt->device_list[list_idx]) { + /* Already registered. */ + return 0; + } + /* was ADSP_ALREADY_IN_USE */ + return -EINVAL; +} + +static int configure_fast_mode_task(struct comp_dev *kpb_dev, const struct kpb_task_params *cfg, + size_t pin) +{ + if (pin >= KPB_MAX_SINK_CNT || pin == REALTIME_PIN_ID || !cfg) + return -EINVAL; + + struct comp_data *priv_data = (struct comp_data *)comp_get_drvdata(kpb_dev); + int ret = unregister_modules_list(&priv_data->fmt, + &priv_data->fmt_device_list.device_list[pin], + pin); + if (ret) + return -EINVAL; + + ret = clear_fmt_modules_list(&priv_data->fmt_device_list, pin); + if (ret) + return -EINVAL; + + /* When modules count IS 0 we only need to remove modules from Fast Mode. */ + if (cfg->number_of_modules > 0) { + ret = prepare_fmt_modules_list(kpb_dev, pin, cfg); + if (!ret) + ret = register_modules_list(&priv_data->fmt, + &priv_data->fmt_device_list.device_list[pin], + pin); + } + return ret; +} +#endif + static int kpb_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, bool last_block, uint32_t data_offset, const char *data) { + /* We can use extended param id for both extended and standard param id */ + union ipc4_extended_param_id extended_param_id; + comp_info(dev, "kpb_set_large_config()"); - switch (param_id) { + extended_param_id.full = param_id; + + switch (extended_param_id.part.parameter_type) { +#ifdef CONFIG_IPC_MAJOR_4 + case KP_BUF_CFG_FM_MODULE: { + /* Modules count equals 0 is a special case in which we want to clear list for + * given pin. Reference FW also allowed for cfg/data to be NULL, but this is no + * longer the case. + */ + const struct kpb_task_params *cfg = (struct kpb_task_params *)data; + uint32_t outpin_id = extended_param_id.part.parameter_instance; + + return configure_fast_mode_task(dev, cfg, outpin_id); + } +#endif case KP_BUF_CLIENT_MIC_SELECT: return kpb_set_micselect(dev, data, data_offset); default: diff --git a/src/audio/mfcc/mfcc.c b/src/audio/mfcc/mfcc.c index b93e49dab743..109c3636a4a1 100644 --- a/src/audio/mfcc/mfcc.c +++ b/src/audio/mfcc/mfcc.c @@ -161,8 +161,8 @@ static int mfcc_process(struct processing_module *mod, struct output_stream_buffer *output_buffers, int num_output_buffers) { struct mfcc_comp_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = input_buffers->data; - struct audio_stream __sparse_cache *sink = output_buffers->data; + struct audio_stream *source = input_buffers->data; + struct audio_stream *sink = output_buffers->data; int frames = input_buffers->size; comp_dbg(mod->dev, "mfcc_process(), start"); @@ -187,14 +187,12 @@ static void mfcc_set_alignment(struct audio_stream *source, struct audio_stream } static int mfcc_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct mfcc_comp_data *cd = module_get_private_data(mod); struct comp_buffer *sourceb; struct comp_buffer *sinkb; - struct comp_buffer __sparse_cache *source_c; - struct comp_buffer __sparse_cache *sink_c; struct comp_dev *dev = mod->dev; enum sof_ipc_frame source_format; enum sof_ipc_frame sink_format; @@ -206,23 +204,21 @@ static int mfcc_prepare(struct processing_module *mod, /* MFCC component will only ever have 1 source and 1 sink buffer */ sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); /* get source data format */ - source_format = audio_stream_get_frm_fmt(&source_c->stream); + source_format = audio_stream_get_frm_fmt(&sourceb->stream); /* set align requirements */ - mfcc_set_alignment(&source_c->stream, &sink_c->stream); + mfcc_set_alignment(&sourceb->stream, &sinkb->stream); /* get sink data format and period bytes */ - sink_format = audio_stream_get_frm_fmt(&sink_c->stream); - sink_period_bytes = audio_stream_period_bytes(&sink_c->stream, dev->frames); + sink_format = audio_stream_get_frm_fmt(&sinkb->stream); + sink_period_bytes = audio_stream_period_bytes(&sinkb->stream, dev->frames); comp_info(dev, "mfcc_prepare(), source_format = %d, sink_format = %d", source_format, sink_format); - if (audio_stream_get_size(&sink_c->stream) < sink_period_bytes) { + if (audio_stream_get_size(&sinkb->stream) < sink_period_bytes) { comp_err(dev, "mfcc_prepare(): sink buffer size %d is insufficient < %d", - audio_stream_get_size(&sink_c->stream), sink_period_bytes); + audio_stream_get_size(&sinkb->stream), sink_period_bytes); ret = -ENOMEM; goto err; } @@ -231,8 +227,8 @@ static int mfcc_prepare(struct processing_module *mod, /* Initialize MFCC, max_frames is set to dev->frames + 4 */ if (cd->config) { - ret = mfcc_setup(mod, dev->frames + 4, audio_stream_get_rate(&source_c->stream), - audio_stream_get_channels(&source_c->stream)); + ret = mfcc_setup(mod, dev->frames + 4, audio_stream_get_rate(&sourceb->stream), + audio_stream_get_channels(&sourceb->stream)); if (ret < 0) { comp_err(dev, "mfcc_prepare(), setup failed."); goto err; @@ -246,13 +242,9 @@ static int mfcc_prepare(struct processing_module *mod, goto err; } - buffer_release(sink_c); - buffer_release(source_c); return 0; err: - buffer_release(sink_c); - buffer_release(source_c); comp_set_state(dev, COMP_TRIGGER_RESET); return ret; } @@ -268,14 +260,14 @@ static int mfcc_reset(struct processing_module *mod) return 0; } -static struct module_interface mfcc_interface = { - .init = mfcc_init, - .free = mfcc_free, - .set_configuration = mfcc_set_config, - .get_configuration = mfcc_get_config, - .process_audio_stream = mfcc_process, - .prepare = mfcc_prepare, - .reset = mfcc_reset, +static const struct module_interface mfcc_interface = { + .init = mfcc_init, + .free = mfcc_free, + .set_configuration = mfcc_set_config, + .get_configuration = mfcc_get_config, + .process_audio_stream = mfcc_process, + .prepare = mfcc_prepare, + .reset = mfcc_reset, }; DECLARE_MODULE_ADAPTER(mfcc_interface, mfcc_uuid, mfcc_tr); diff --git a/src/audio/mfcc/mfcc_common.c b/src/audio/mfcc/mfcc_common.c index 8ea1d7db4184..63ab84943669 100644 --- a/src/audio/mfcc/mfcc_common.c +++ b/src/audio/mfcc/mfcc_common.c @@ -143,7 +143,7 @@ static int mfcc_stft_process(const struct comp_dev *dev, struct mfcc_state *stat void mfcc_s16_default(struct processing_module *mod, struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *sink = bsink->data; struct mfcc_comp_data *cd = module_get_private_data(mod); struct mfcc_state *state = &cd->state; struct mfcc_buffer *buf = &cd->state.buf; diff --git a/src/audio/mfcc/mfcc_generic.c b/src/audio/mfcc/mfcc_generic.c index 447b1382ce11..9384b16e0cee 100644 --- a/src/audio/mfcc/mfcc_generic.c +++ b/src/audio/mfcc/mfcc_generic.c @@ -27,7 +27,7 @@ void mfcc_source_copy_s16(struct input_stream_buffer *bsource, struct mfcc_buffer *buf, struct mfcc_pre_emph *emph, int frames, int source_channel) { - struct audio_stream __sparse_cache *source = bsource->data; + struct audio_stream *source = bsource->data; int32_t s; int16_t *x0; int16_t *x = audio_stream_get_rptr(source); diff --git a/src/audio/mfcc/mfcc_hifi3.c b/src/audio/mfcc/mfcc_hifi3.c index 6b274a58ae84..76f0a79da668 100644 --- a/src/audio/mfcc/mfcc_hifi3.c +++ b/src/audio/mfcc/mfcc_hifi3.c @@ -36,7 +36,7 @@ static inline void set_circular_buf0(const void *start, const void *end) void mfcc_source_copy_s16(struct input_stream_buffer *bsource, struct mfcc_buffer *buf, struct mfcc_pre_emph *emph, int frames, int source_channel) { - struct audio_stream __sparse_cache *source = bsource->data; + struct audio_stream *source = bsource->data; int copied; int nmax; int n; @@ -88,7 +88,7 @@ void mfcc_source_copy_s16(struct input_stream_buffer *bsource, struct mfcc_buffe } buf->s_avail += copied; buf->s_free -= copied; - buf->w_ptr = out; + buf->w_ptr = (int16_t *)out; } void mfcc_fill_prev_samples(struct mfcc_buffer *buf, int16_t *prev_data, @@ -121,7 +121,7 @@ void mfcc_fill_prev_samples(struct mfcc_buffer *buf, int16_t *prev_data, buf->s_avail -= prev_data_length; buf->s_free += prev_data_length; - buf->r_ptr = in; + buf->r_ptr = (void *)in; /* int16_t pointer but direct cast is not possible */ } void mfcc_fill_fft_buffer(struct mfcc_state *state) @@ -156,7 +156,7 @@ void mfcc_fill_fft_buffer(struct mfcc_state *state) buf->s_avail -= fft->fft_hop_size; buf->s_free += fft->fft_hop_size; - buf->r_ptr = in; + buf->r_ptr = (int16_t *)in; /* Copy for next time data back to overlap buffer */ idx = fft->fft_fill_start_idx + fft->fft_hop_size; diff --git a/src/audio/mfcc/mfcc_hifi4.c b/src/audio/mfcc/mfcc_hifi4.c index 4e8853a4903b..25df53b4ca06 100644 --- a/src/audio/mfcc/mfcc_hifi4.c +++ b/src/audio/mfcc/mfcc_hifi4.c @@ -42,7 +42,7 @@ static inline void set_circular_buf1(const void *start, const void *end) void mfcc_source_copy_s16(struct input_stream_buffer *bsource, struct mfcc_buffer *buf, struct mfcc_pre_emph *emph, int frames, int source_channel) { - struct audio_stream __sparse_cache *source = bsource->data; + struct audio_stream *source = bsource->data; int num_channels = audio_stream_get_channels(source); ae_int16 *in = (ae_int16 *)source->r_ptr + source_channel; ae_int16 *out = (ae_int16 *)buf->w_ptr; diff --git a/src/audio/mixer/mixer.c b/src/audio/mixer/mixer.c index 3dc6ee1407dc..fce964f4da1b 100644 --- a/src/audio/mixer/mixer.c +++ b/src/audio/mixer/mixer.c @@ -82,7 +82,7 @@ static int mixer_process(struct processing_module *mod, { struct mixer_data *md = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - const struct audio_stream __sparse_cache *sources_stream[PLATFORM_MAX_STREAMS]; + const struct audio_stream *sources_stream[PLATFORM_MAX_STREAMS]; int sources_indices[PLATFORM_MAX_STREAMS]; int32_t i = 0, j = 0; uint32_t frames = INT32_MAX; @@ -174,13 +174,11 @@ static int mixer_reset(struct processing_module *mod) /* FIXME: this is racy and implicitly protected by serialised IPCs */ struct comp_buffer *source = container_of(blist, struct comp_buffer, sink_list); - struct comp_buffer __sparse_cache *source_c = buffer_acquire(source); bool stop = false; - if (source_c->source && source_c->source->state > COMP_STATE_READY) + if (source->source && source->source->state > COMP_STATE_READY) stop = true; - buffer_release(source_c); /* only mix the sources with the same state with mixer */ if (stop) /* should not reset the downstream components */ @@ -194,7 +192,7 @@ static int mixer_reset(struct processing_module *mod) } /* init and calculate the aligned setting for available frames and free frames retrieve*/ -static inline void mixer_set_frame_alignment(struct audio_stream __sparse_cache *source) +static inline void mixer_set_frame_alignment(struct audio_stream *source) { #if XCHAL_HAVE_HIFI3 || XCHAL_HAVE_HIFI4 @@ -220,26 +218,22 @@ static inline void mixer_set_frame_alignment(struct audio_stream __sparse_cache } static int mixer_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct mixer_data *md = module_get_private_data(mod); - struct comp_buffer __sparse_cache *sink_c; struct comp_dev *dev = mod->dev; struct comp_buffer *sink; struct list_item *blist; sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); - md->mix_func = mixer_get_processing_function(dev, sink_c); - mixer_set_frame_alignment(&sink_c->stream); - buffer_release(sink_c); + md->mix_func = mixer_get_processing_function(dev, sink); + mixer_set_frame_alignment(&sink->stream); /* check each mixer source state */ list_for_item(blist, &dev->bsource_list) { struct comp_buffer *source; - struct comp_buffer __sparse_cache *source_c; bool stop; /* @@ -251,11 +245,9 @@ static int mixer_prepare(struct processing_module *mod, * done. */ source = container_of(blist, struct comp_buffer, sink_list); - source_c = buffer_acquire(source); - mixer_set_frame_alignment(&source_c->stream); - stop = source_c->source && (source_c->source->state == COMP_STATE_PAUSED || - source_c->source->state == COMP_STATE_ACTIVE); - buffer_release(source_c); + mixer_set_frame_alignment(&source->stream); + stop = source->source && (source->source->state == COMP_STATE_PAUSED || + source->source->state == COMP_STATE_ACTIVE); /* only prepare downstream if we have no active sources */ if (stop) @@ -266,8 +258,8 @@ static int mixer_prepare(struct processing_module *mod, return 0; } -static struct module_interface mixer_interface = { - .init = mixer_init, +static const struct module_interface mixer_interface = { + .init = mixer_init, .prepare = mixer_prepare, .process_audio_stream = mixer_process, .reset = mixer_reset, diff --git a/src/audio/mixer/mixer_generic.c b/src/audio/mixer/mixer_generic.c index b8be3ecf63a1..0deabe2093a7 100644 --- a/src/audio/mixer/mixer_generic.c +++ b/src/audio/mixer/mixer_generic.c @@ -11,8 +11,8 @@ #if CONFIG_FORMAT_S16LE /* Mix n 16 bit PCM source streams to one sink stream */ -static void mix_n_s16(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache **sources, uint32_t num_sources, +static void mix_n_s16(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream **sources, uint32_t num_sources, uint32_t frames) { int16_t *src[PLATFORM_MAX_CHANNELS]; @@ -57,8 +57,8 @@ static void mix_n_s16(struct comp_dev *dev, struct audio_stream __sparse_cache * #if CONFIG_FORMAT_S24LE /* Mix n 24 bit PCM source streams to one sink stream */ -static void mix_n_s24(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache **sources, uint32_t num_sources, +static void mix_n_s24(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream **sources, uint32_t num_sources, uint32_t frames) { int32_t *src[PLATFORM_MAX_CHANNELS]; @@ -105,8 +105,8 @@ static void mix_n_s24(struct comp_dev *dev, struct audio_stream __sparse_cache * #if CONFIG_FORMAT_S32LE /* Mix n 32 bit PCM source streams to one sink stream */ -static void mix_n_s32(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache **sources, uint32_t num_sources, +static void mix_n_s32(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream **sources, uint32_t num_sources, uint32_t frames) { int32_t *src[PLATFORM_MAX_CHANNELS]; diff --git a/src/audio/mixer/mixer_hifi3.c b/src/audio/mixer/mixer_hifi3.c index 3147ce0a35b6..2bba6c213df6 100644 --- a/src/audio/mixer/mixer_hifi3.c +++ b/src/audio/mixer/mixer_hifi3.c @@ -13,8 +13,8 @@ #if CONFIG_FORMAT_S16LE /* Mix n 16 bit PCM source streams to one sink stream */ -static void mix_n_s16(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache **sources, uint32_t num_sources, +static void mix_n_s16(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream **sources, uint32_t num_sources, uint32_t frames) { ae_int16x4 * in[PLATFORM_MAX_CHANNELS]; @@ -69,8 +69,8 @@ static void mix_n_s16(struct comp_dev *dev, struct audio_stream __sparse_cache * #if CONFIG_FORMAT_S24LE /* Mix n 24 bit PCM source streams to one sink stream */ -static void mix_n_s24(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache **sources, uint32_t num_sources, +static void mix_n_s24(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream **sources, uint32_t num_sources, uint32_t frames) { ae_int32x2 *in[PLATFORM_MAX_CHANNELS]; @@ -114,8 +114,8 @@ static void mix_n_s24(struct comp_dev *dev, struct audio_stream __sparse_cache * #if CONFIG_FORMAT_S32LE /* Mix n 32 bit PCM source streams to one sink stream */ -static void mix_n_s32(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache **sources, uint32_t num_sources, +static void mix_n_s32(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream **sources, uint32_t num_sources, uint32_t frames) { ae_q32s * in[PLATFORM_MAX_CHANNELS]; diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index 78d69223de56..ba3184c66e12 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -79,10 +79,22 @@ struct mixin_data { struct mixin_sink_config sink_config[MIXIN_MAX_SINKS]; }; -/* mixout component private data. This can be accessed from different cores. */ +/* + * Mixin calls "consume" on its source data but never calls "produce" -- that one is called + * by mixout for its sink data. So between mixin_process() and mixout_process() a number of + * consumed (in mixin) yet not produced (in mixout) frames should be stored for each mixin + * and mixout pair. + */ +struct pending_frames { + struct comp_dev *mixin; + uint32_t frames; +}; + +/* mixout component private data */ struct mixout_data { /* number of currently mixed frames in mixout sink buffer */ uint32_t mixed_frames; + /* * Source data is consumed by mixins in mixin_process() but sink data cannot be * immediately produced. Sink data is produced by mixout in mixout_process() after @@ -90,9 +102,22 @@ struct mixout_data { * So for each connected mixin, mixout keeps knowledge of data already consumed * by mixin but not yet produced in mixout. */ - uint32_t pending_frames[MIXOUT_MAX_SOURCES]; + struct pending_frames pending_frames[MIXOUT_MAX_SOURCES]; }; +/* NULL is also a valid mixin argument: in such case the function returns first unused entry */ +static struct pending_frames *get_mixin_pending_frames(struct mixout_data *mixout_data, + const struct comp_dev *mixin) +{ + int i; + + for (i = 0; i < MIXOUT_MAX_SOURCES; i++) + if (mixout_data->pending_frames[i].mixin == mixin) + return &mixout_data->pending_frames[i]; + + return NULL; +} + static int mixin_init(struct processing_module *mod) { struct module_data *mod_data = &mod->priv; @@ -121,7 +146,6 @@ static int mixin_init(struct processing_module *mod) static int mixout_init(struct processing_module *mod) { - struct module_source_info __sparse_cache *mod_source_info; struct comp_dev *dev = mod->dev; struct mixout_data *mo_data; @@ -131,9 +155,7 @@ static int mixout_init(struct processing_module *mod) if (!mo_data) return -ENOMEM; - mod_source_info = module_source_info_acquire(mod->source_info); - mod_source_info->private = mo_data; - module_source_info_release(mod_source_info); + mod->priv.private = mo_data; mod->skip_sink_buffer_writeback = true; @@ -154,22 +176,16 @@ static int mixin_free(struct processing_module *mod) static int mixout_free(struct processing_module *mod) { - struct module_source_info __sparse_cache *mod_source_info; - comp_dbg(mod->dev, "mixout_free()"); - - mod_source_info = module_source_info_acquire(mod->source_info); - rfree(mod_source_info->private); - mod_source_info->private = NULL; - module_source_info_release(mod_source_info); + rfree(module_get_private_data(mod)); return 0; } static int mix_and_remap(struct comp_dev *dev, const struct mixin_data *mixin_data, - uint16_t sink_index, struct audio_stream __sparse_cache *sink, + uint16_t sink_index, struct audio_stream *sink, uint32_t start_frame, uint32_t mixed_frames, - const struct audio_stream __sparse_cache *source, uint32_t frame_count) + const struct audio_stream *source, uint32_t frame_count) { const struct mixin_sink_config *sink_config; @@ -197,7 +213,7 @@ static int mix_and_remap(struct comp_dev *dev, const struct mixin_data *mixin_da } /* mix silence into stream, i.e. set not yet mixed data in stream to zero */ -static void silence(struct audio_stream __sparse_cache *stream, uint32_t start_frame, +static void silence(struct audio_stream *stream, uint32_t start_frame, uint32_t mixed_frames, uint32_t frame_count) { uint32_t skip_mixed_frames; @@ -236,9 +252,9 @@ static void silence(struct audio_stream __sparse_cache *stream, uint32_t start_f * Since there is no garantie that mixout processing is done in time we have * to account for a possibility having not yet produced data in mixout sink * buffer that was written there on previous run(s) of mixin_process(). So for each - * mixin <--> mixout pair we track consumed_yet_not_produced data amount. - * That value is also used in mixout_process() to calculate how many data was - * actually mixed and so xxx_produce() is called for that amount. + * mixin <--> mixout pair we track consumed yet not produced (pending_frames) data + * amount. That value is also used in mixout_process() to calculate how many data + * was actually mixed and so xxx_produce() is called for that amount. */ static int mixin_process(struct processing_module *mod, struct input_stream_buffer *input_buffers, int num_input_buffers, @@ -251,7 +267,7 @@ static int mixin_process(struct processing_module *mod, uint16_t sinks_ids[MIXIN_MAX_SINKS]; uint32_t bytes_to_consume_from_source_buf; uint32_t frames_to_copy; - int source_index; + struct pending_frames *pending_frames; int i, ret; comp_dbg(dev, "mixin_process()"); @@ -274,20 +290,17 @@ static int mixin_process(struct processing_module *mod, * and frames free in each connected mixout sink buffer. */ for (i = 0; i < num_output_buffers; i++) { - struct comp_buffer __sparse_cache *unused_in_between_buf_c; + struct comp_buffer *unused_in_between_buf_c; struct comp_dev *mixout; uint16_t sink_id; struct comp_buffer *sink; struct mixout_data *mixout_data; struct processing_module *mixout_mod; - struct module_source_info __sparse_cache *mod_source_info; - struct comp_buffer __sparse_cache *sink_c; - uint32_t free_frames, pending_frames; + uint32_t free_frames; /* unused buffer between mixin and mixout */ - unused_in_between_buf_c = attr_container_of(output_buffers[i].data, - struct comp_buffer __sparse_cache, - stream, __sparse_cache); + unused_in_between_buf_c = container_of(output_buffers[i].data, + struct comp_buffer, stream); mixout = unused_in_between_buf_c->sink; sink_id = IPC4_SRC_QUEUE_ID(unused_in_between_buf_c->id); @@ -297,53 +310,42 @@ static int mixin_process(struct processing_module *mod, sink = list_first_item(&mixout->bsink_list, struct comp_buffer, source_list); mixout_mod = comp_get_drvdata(mixout); - mod_source_info = module_source_info_acquire(mixout_mod->source_info); - mixout_data = mod_source_info->private; - source_index = find_module_source_index(mod_source_info, dev); - if (source_index < 0) { + mixout_data = module_get_private_data(mixout_mod); + pending_frames = get_mixin_pending_frames(mixout_data, dev); + if (!pending_frames) { comp_err(dev, "No source info"); - module_source_info_release(mod_source_info); return -EINVAL; } - sink_c = buffer_acquire(sink); - /* Normally this should never happen as we checked above * that mixout is in active state and so its sink buffer * should be already initialized in mixout .params(). */ - if (!sink_c->hw_params_configured) { + if (!sink->hw_params_configured) { comp_err(dev, "Uninitialized mixout sink buffer!"); - buffer_release(sink_c); - module_source_info_release(mod_source_info); return -EINVAL; } - free_frames = audio_stream_get_free_frames(&sink_c->stream); + free_frames = audio_stream_get_free_frames(&sink->stream); /* mixout sink buffer may still have not yet produced data -- data * consumed and written there by mixin on previous mixin_process() run. * We do NOT want to overwrite that data. */ - pending_frames = mixout_data->pending_frames[source_index]; - assert(free_frames >= pending_frames); - sinks_free_frames = MIN(sinks_free_frames, free_frames - pending_frames); - - buffer_release(sink_c); - module_source_info_release(mod_source_info); + assert(free_frames >= pending_frames->frames); + sinks_free_frames = MIN(sinks_free_frames, free_frames - pending_frames->frames); } if (source_avail_frames > 0) { - struct comp_buffer __sparse_cache *source_c; + struct comp_buffer *source_c; frames_to_copy = MIN(source_avail_frames, sinks_free_frames); bytes_to_consume_from_source_buf = audio_stream_period_bytes(input_buffers[0].data, frames_to_copy); if (bytes_to_consume_from_source_buf > 0) { input_buffers[0].consumed = bytes_to_consume_from_source_buf; - source_c = attr_container_of(input_buffers[0].data, - struct comp_buffer __sparse_cache, - stream, __sparse_cache); + source_c = container_of(input_buffers[0].data, struct comp_buffer, + stream); buffer_stream_invalidate(source_c, bytes_to_consume_from_source_buf); } } else { @@ -360,22 +362,18 @@ static int mixin_process(struct processing_module *mod, struct comp_dev *mixout; struct comp_buffer *sink; struct mixout_data *mixout_data; - struct module_source_info __sparse_cache *mod_source_info; struct processing_module *mixout_mod; uint32_t start_frame; - struct comp_buffer __sparse_cache *sink_c; uint32_t writeback_size; mixout = active_mixouts[i]; sink = list_first_item(&mixout->bsink_list, struct comp_buffer, source_list); mixout_mod = comp_get_drvdata(mixout); - mod_source_info = module_source_info_acquire(mixout_mod->source_info); - mixout_data = mod_source_info->private; - source_index = find_module_source_index(mod_source_info, dev); - if (source_index < 0) { + mixout_data = module_get_private_data(mixout_mod); + pending_frames = get_mixin_pending_frames(mixout_data, dev); + if (!pending_frames) { comp_err(dev, "No source info"); - module_source_info_release(mod_source_info); return -EINVAL; } @@ -383,28 +381,24 @@ static int mixin_process(struct processing_module *mod, * Normally start_frame would be 0 unless mixout pipeline has serious * performance problems with processing data on time in mixout. */ - start_frame = mixout_data->pending_frames[source_index]; - - sink_c = buffer_acquire(sink); + start_frame = pending_frames->frames; /* if source does not produce any data but mixin is in active state -- generate * silence instead of that source data */ if (source_avail_frames == 0) { /* generate silence */ - silence(&sink_c->stream, start_frame, mixout_data->mixed_frames, + silence(&sink->stream, start_frame, mixout_data->mixed_frames, frames_to_copy); } else { /* basically, if sink buffer has no data -- copy source data there, if * sink buffer has some data (written by another mixin) mix that data * with source data. */ - ret = mix_and_remap(dev, mixin_data, sinks_ids[i], &sink_c->stream, + ret = mix_and_remap(dev, mixin_data, sinks_ids[i], &sink->stream, start_frame, mixout_data->mixed_frames, input_buffers[0].data, frames_to_copy); if (ret < 0) { - buffer_release(sink_c); - module_source_info_release(mod_source_info); return ret; } } @@ -413,18 +407,15 @@ static int mixin_process(struct processing_module *mod, * of frames_to_copy size (converted to bytes, of course). However, seems * there is no appropreate API. Anyway, start_frame would be 0 most of the time. */ - writeback_size = audio_stream_period_bytes(&sink_c->stream, + writeback_size = audio_stream_period_bytes(&sink->stream, frames_to_copy + start_frame); if (writeback_size > 0) - buffer_stream_writeback(sink_c, writeback_size); - buffer_release(sink_c); + buffer_stream_writeback(sink, writeback_size); - mixout_data->pending_frames[source_index] += frames_to_copy; + pending_frames->frames += frames_to_copy; if (frames_to_copy + start_frame > mixout_data->mixed_frames) mixout_data->mixed_frames = frames_to_copy + start_frame; - - module_source_info_release(mod_source_info); } return 0; @@ -437,71 +428,60 @@ static int mixout_process(struct processing_module *mod, struct input_stream_buffer *input_buffers, int num_input_buffers, struct output_stream_buffer *output_buffers, int num_output_buffers) { - struct module_source_info __sparse_cache *mod_source_info; struct comp_dev *dev = mod->dev; struct mixout_data *md; uint32_t frames_to_produce = INT32_MAX; - uint32_t pending_frames; + struct pending_frames *pending_frames; uint32_t sink_bytes; int i; comp_dbg(dev, "mixout_process()"); - mod_source_info = module_source_info_acquire(mod->source_info); - md = mod_source_info->private; + md = module_get_private_data(mod); /* iterate over all connected mixins to find minimal value of frames they consumed * (i.e., mixed into mixout sink buffer). That is the amount that can/should be * produced now. */ for (i = 0; i < num_input_buffers; i++) { - const struct audio_stream __sparse_cache *source_stream; - struct comp_buffer __sparse_cache *unused_in_between_buf; + const struct audio_stream *source_stream; + struct comp_buffer *unused_in_between_buf; struct comp_dev *source; - int source_index; source_stream = input_buffers[i].data; - unused_in_between_buf = attr_container_of(source_stream, - struct comp_buffer __sparse_cache, - stream, __sparse_cache); + unused_in_between_buf = container_of(source_stream, struct comp_buffer, + stream); source = unused_in_between_buf->source; - source_index = find_module_source_index(mod_source_info, source); - /* this shouldn't happen but skip even if it does and move to the next source */ - if (source_index < 0) + pending_frames = get_mixin_pending_frames(md, source); + if (!pending_frames) continue; - pending_frames = md->pending_frames[source_index]; - - if (source->state == COMP_STATE_ACTIVE || pending_frames) - frames_to_produce = MIN(frames_to_produce, pending_frames); + if (source->state == COMP_STATE_ACTIVE || pending_frames->frames) + frames_to_produce = MIN(frames_to_produce, pending_frames->frames); } if (frames_to_produce > 0 && frames_to_produce < INT32_MAX) { for (i = 0; i < num_input_buffers; i++) { - const struct audio_stream __sparse_cache *source_stream; - struct comp_buffer __sparse_cache *unused_in_between_buf; + const struct audio_stream *source_stream; + struct comp_buffer *unused_in_between_buf; struct comp_dev *source; - int source_index; - uint32_t pending_frames; source_stream = input_buffers[i].data; - unused_in_between_buf = attr_container_of(source_stream, - struct comp_buffer __sparse_cache, - stream, __sparse_cache); + unused_in_between_buf = container_of(source_stream, + struct comp_buffer, stream); source = unused_in_between_buf->source; - source_index = find_module_source_index(mod_source_info, source); - if (source_index < 0) + pending_frames = get_mixin_pending_frames(md, source); + if (!pending_frames) continue; - pending_frames = md->pending_frames[source_index]; - if (pending_frames >= frames_to_produce) - md->pending_frames[source_index] -= frames_to_produce; + if (pending_frames->frames >= frames_to_produce) + pending_frames->frames -= frames_to_produce; else - md->pending_frames[source_index] = 0; + pending_frames->frames = 0; } assert(md->mixed_frames >= frames_to_produce); @@ -518,8 +498,6 @@ static int mixout_process(struct processing_module *mod, output_buffers[0].size = 0; } - module_source_info_release(mod_source_info); - return 0; } @@ -547,15 +525,12 @@ static int mixout_reset(struct processing_module *mod) if (dev->pipeline->source_comp->direction == SOF_IPC_STREAM_PLAYBACK) { list_for_item(blist, &dev->bsource_list) { struct comp_buffer *source; - struct comp_buffer __sparse_cache *source_c; bool stop; /* FIXME: this is racy and implicitly protected by serialised IPCs */ source = container_of(blist, struct comp_buffer, sink_list); - source_c = buffer_acquire(source); - stop = (dev->pipeline == source_c->source->pipeline && - source_c->source->state > COMP_STATE_PAUSED); - buffer_release(source_c); + stop = (dev->pipeline == source->source->pipeline && + source->source->state > COMP_STATE_PAUSED); if (stop) /* should not reset the downstream components */ @@ -584,28 +559,25 @@ static int mixin_params(struct processing_module *mod) */ list_for_item(blist, &dev->bsink_list) { struct comp_buffer *sink; - struct comp_buffer __sparse_cache *sink_c; enum sof_ipc_frame frame_fmt, valid_fmt; uint16_t sink_id; sink = buffer_from_list(blist, PPL_DIR_DOWNSTREAM); - sink_c = buffer_acquire(sink); - audio_stream_set_channels(&sink_c->stream, + audio_stream_set_channels(&sink->stream, mod->priv.cfg.base_cfg.audio_fmt.channels_count); /* Applying channel remapping may produce sink stream with channel count * different from source channel count. */ - sink_id = IPC4_SRC_QUEUE_ID(sink_c->id); + sink_id = IPC4_SRC_QUEUE_ID(sink->id); if (sink_id >= MIXIN_MAX_SINKS) { comp_err(dev, "Sink index out of range: %u, max sink count: %u", (uint32_t)sink_id, MIXIN_MAX_SINKS); - buffer_release(sink_c); return -EINVAL; } if (md->sink_config[sink_id].mixer_mode == IPC4_MIXER_CHANNEL_REMAPPING_MODE) - audio_stream_set_channels(&sink_c->stream, + audio_stream_set_channels(&sink->stream, md->sink_config[sink_id].output_channel_count); /* comp_verify_params() does not modify valid_sample_fmt (a BUG?), @@ -616,10 +588,8 @@ static int mixin_params(struct processing_module *mod) &frame_fmt, &valid_fmt, mod->priv.cfg.base_cfg.audio_fmt.s_type); - audio_stream_set_frm_fmt(&sink_c->stream, frame_fmt); - audio_stream_set_valid_fmt(&sink_c->stream, valid_fmt); - - buffer_release(sink_c); + audio_stream_set_frm_fmt(&sink->stream, frame_fmt); + audio_stream_set_valid_fmt(&sink->stream, valid_fmt); } /* use BUFF_PARAMS_CHANNELS to skip updating channel count */ @@ -641,13 +611,12 @@ static int mixin_params(struct processing_module *mod) * if downstream is not currently active. */ static int mixin_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct mixin_data *md = module_get_private_data(mod); struct comp_dev *dev = mod->dev; struct comp_buffer *sink; - struct comp_buffer __sparse_cache *sink_c; enum sof_ipc_frame fmt; int ret; @@ -658,9 +627,7 @@ static int mixin_prepare(struct processing_module *mod, return ret; sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); - fmt = audio_stream_get_valid_fmt(&sink_c->stream); - buffer_release(sink_c); + fmt = audio_stream_get_valid_fmt(&sink->stream); /* currently inactive so setup mixer */ switch (fmt) { @@ -687,7 +654,6 @@ static int mixout_params(struct processing_module *mod) { struct sof_ipc_stream_params *params = mod->stream_params; struct comp_buffer *sink; - struct comp_buffer __sparse_cache *sink_c; struct comp_dev *dev = mod->dev; enum sof_ipc_frame frame_fmt, valid_fmt; uint32_t sink_period_bytes, sink_stream_size; @@ -704,7 +670,6 @@ static int mixout_params(struct processing_module *mod) } sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); /* comp_verify_params() does not modify valid_sample_fmt (a BUG?), let's do this here */ audio_stream_fmt_conversion(mod->priv.cfg.base_cfg.audio_fmt.depth, @@ -712,15 +677,14 @@ static int mixout_params(struct processing_module *mod) &frame_fmt, &valid_fmt, mod->priv.cfg.base_cfg.audio_fmt.s_type); - audio_stream_set_valid_fmt(&sink_c->stream, valid_fmt); - audio_stream_set_channels(&sink_c->stream, params->channels); + audio_stream_set_valid_fmt(&sink->stream, valid_fmt); + audio_stream_set_channels(&sink->stream, params->channels); - sink_stream_size = audio_stream_get_size(&sink_c->stream); + sink_stream_size = audio_stream_get_size(&sink->stream); /* calculate period size based on config */ - sink_period_bytes = audio_stream_period_bytes(&sink_c->stream, + sink_period_bytes = audio_stream_period_bytes(&sink->stream, dev->frames); - buffer_release(sink_c); if (sink_period_bytes == 0) { comp_err(dev, "mixout_params(): period_bytes = 0"); @@ -737,10 +701,9 @@ static int mixout_params(struct processing_module *mod) } static int mixout_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { - struct module_source_info __sparse_cache *mod_source_info; struct comp_dev *dev = mod->dev; struct mixout_data *md; int ret, i; @@ -755,13 +718,95 @@ static int mixout_prepare(struct processing_module *mod, * Since mixout sink buffer stream is reset on .prepare(), let's * reset counters for not yet produced frames in that buffer. */ - mod_source_info = module_source_info_acquire(mod->source_info); - md = mod_source_info->private; + md = module_get_private_data(mod); md->mixed_frames = 0; for (i = 0; i < MIXOUT_MAX_SOURCES; i++) - md->pending_frames[i] = 0; - module_source_info_release(mod_source_info); + md->pending_frames[i].frames = 0; + + return 0; +} + +int mixout_bind(struct processing_module *mod, void *data) +{ + struct ipc4_module_bind_unbind *bu; + struct comp_dev *mixin; + struct pending_frames *pending_frames; + int src_id; + struct mixout_data *mixout_data; + + comp_dbg(mod->dev, "mixout_bind() %p", data); + + bu = (struct ipc4_module_bind_unbind *)data; + src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id); + + /* we are only interested in bind for mixin -> mixout pair */ + if (mod->dev->ipc_config.id == src_id) + return 0; + + mixin = ipc4_get_comp_dev(src_id); + if (!mixin) { + comp_err(mod->dev, "mixout_bind: no mixin with ID %d found", src_id); + return -EINVAL; + } + + mixout_data = module_get_private_data(mod); + + pending_frames = get_mixin_pending_frames(mixout_data, mixin); + /* + * this should never happen as pending_frames info for a particular mixin and mixout pair + * should have been already cleared in mixout_unbind() + */ + if (pending_frames) { + pending_frames->mixin = NULL; + pending_frames->frames = 0; + } + + /* find an empty slot in the pending_frames array */ + pending_frames = get_mixin_pending_frames(mixout_data, NULL); + if (!pending_frames) { + /* no free slot in pending_frames array */ + comp_err(mod->dev, "Too many inputs!"); + return -ENOMEM; + } + + pending_frames->frames = 0; + pending_frames->mixin = mixin; + + return 0; +} + +int mixout_unbind(struct processing_module *mod, void *data) +{ + struct ipc4_module_bind_unbind *bu; + struct comp_dev *mixin; + struct pending_frames *pending_frames; + int src_id; + struct mixout_data *mixout_data; + + comp_dbg(mod->dev, "mixout_unbind()"); + + bu = (struct ipc4_module_bind_unbind *)data; + src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id); + + /* we are only interested in unbind for mixin -> mixout pair */ + if (mod->dev->ipc_config.id == src_id) + return 0; + + mixin = ipc4_get_comp_dev(src_id); + if (!mixin) { + comp_err(mod->dev, "mixout_bind: no mixin with ID %d found", src_id); + return -EINVAL; + } + + mixout_data = module_get_private_data(mod); + + /* remove mixin from pending_frames array */ + pending_frames = get_mixin_pending_frames(mixout_data, mixin); + if (pending_frames) { + pending_frames->mixin = NULL; + pending_frames->frames = 0; + } return 0; } @@ -856,8 +901,8 @@ static int mixin_set_config(struct processing_module *mod, uint32_t config_id, return 0; } -static struct module_interface mixin_interface = { - .init = mixin_init, +static const struct module_interface mixin_interface = { + .init = mixin_init, .prepare = mixin_prepare, .process_audio_stream = mixin_process, .set_configuration = mixin_set_config, @@ -868,12 +913,14 @@ static struct module_interface mixin_interface = { DECLARE_MODULE_ADAPTER(mixin_interface, mixin_uuid, mixin_tr); SOF_MODULE_INIT(mixin, sys_comp_module_mixin_interface_init); -static struct module_interface mixout_interface = { - .init = mixout_init, +static const struct module_interface mixout_interface = { + .init = mixout_init, .prepare = mixout_prepare, .process_audio_stream = mixout_process, .reset = mixout_reset, - .free = mixout_free + .free = mixout_free, + .bind = mixout_bind, + .unbind = mixout_unbind }; DECLARE_MODULE_ADAPTER(mixout_interface, mixout_uuid, mixout_tr); diff --git a/src/audio/mixin_mixout/mixin_mixout_generic.c b/src/audio/mixin_mixout/mixin_mixout_generic.c index 75468fdb4d67..a99788be32bc 100644 --- a/src/audio/mixin_mixout/mixin_mixout_generic.c +++ b/src/audio/mixin_mixout/mixin_mixout_generic.c @@ -17,9 +17,9 @@ * parameters: multichannel stream is treated as single channel and so the entire stream * contents is mixed. */ -static void normal_mix_channel_s16(struct audio_stream __sparse_cache *sink, int32_t start_frame, +static void normal_mix_channel_s16(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, - const struct audio_stream __sparse_cache *source, + const struct audio_stream *source, int32_t frame_count, uint16_t gain) { int32_t frames_to_mix, frames_to_copy, left_frames; @@ -61,7 +61,7 @@ static void normal_mix_channel_s16(struct audio_stream __sparse_cache *sink, int } } -static void mute_channel_s16(struct audio_stream __sparse_cache *stream, int32_t channel_index, +static void mute_channel_s16(struct audio_stream *stream, int32_t channel_index, int32_t start_frame, int32_t mixed_frames, int32_t frame_count) { int32_t skip_mixed_frames, n, left_frames, i, channel_count, frames, samples; @@ -101,9 +101,9 @@ static void mute_channel_s16(struct audio_stream __sparse_cache *stream, int32_t * parameters: multichannel stream is treated as single channel and so the entire stream * contents is mixed. */ -static void normal_mix_channel_s24(struct audio_stream __sparse_cache *sink, int32_t start_frame, +static void normal_mix_channel_s24(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, - const struct audio_stream __sparse_cache *source, + const struct audio_stream *source, int32_t frame_count, uint16_t gain) { int32_t frames_to_mix, frames_to_copy, left_frames; @@ -153,9 +153,9 @@ static void normal_mix_channel_s24(struct audio_stream __sparse_cache *sink, int * parameters: multichannel stream is treated as single channel and so the entire stream * contents is mixed. */ -static void normal_mix_channel_s32(struct audio_stream __sparse_cache *sink, int32_t start_frame, +static void normal_mix_channel_s32(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, - const struct audio_stream __sparse_cache *source, + const struct audio_stream *source, int32_t frame_count, uint16_t gain) { int32_t frames_to_mix, frames_to_copy, left_frames; @@ -198,7 +198,7 @@ static void normal_mix_channel_s32(struct audio_stream __sparse_cache *sink, int #endif /* CONFIG_FORMAT_S32LE */ #if CONFIG_FORMAT_S32LE || CONFIG_FORMAT_S24LE -static void mute_channel_s32(struct audio_stream __sparse_cache *stream, int32_t channel_index, +static void mute_channel_s32(struct audio_stream *stream, int32_t channel_index, int32_t start_frame, int32_t mixed_frames, int32_t frame_count) { int32_t skip_mixed_frames, left_frames, n, channel_count, i, frames, samples; diff --git a/src/audio/mixin_mixout/mixin_mixout_hifi3.c b/src/audio/mixin_mixout/mixin_mixout_hifi3.c index 3fb46f2b74f6..93905a5d80af 100644 --- a/src/audio/mixin_mixout/mixin_mixout_hifi3.c +++ b/src/audio/mixin_mixout/mixin_mixout_hifi3.c @@ -16,9 +16,9 @@ * parameters: multichannel stream is treated as single channel and so the entire stream * contents is mixed. */ -static void normal_mix_channel_s16(struct audio_stream __sparse_cache *sink, int32_t start_frame, +static void normal_mix_channel_s16(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, - const struct audio_stream __sparse_cache *source, + const struct audio_stream *source, int32_t frame_count, uint16_t gain) { int frames_to_mix, frames_to_copy, left_frames; @@ -104,7 +104,7 @@ static void normal_mix_channel_s16(struct audio_stream __sparse_cache *sink, int } } -static void mute_channel_s16(struct audio_stream __sparse_cache *stream, int32_t channel_index, +static void mute_channel_s16(struct audio_stream *stream, int32_t channel_index, int32_t start_frame, int32_t mixed_frames, int32_t frame_count) { int skip_mixed_frames, left_frames; @@ -140,9 +140,9 @@ static void mute_channel_s16(struct audio_stream __sparse_cache *stream, int32_t * parameters: multichannel stream is treated as single channel and so the entire stream * contents is mixed. */ -static void normal_mix_channel_s24(struct audio_stream __sparse_cache *sink, int32_t start_frame, +static void normal_mix_channel_s24(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, - const struct audio_stream __sparse_cache *source, + const struct audio_stream *source, int32_t frame_count, uint16_t gain) { int frames_to_mix, frames_to_copy, left_frames; @@ -230,9 +230,9 @@ static void normal_mix_channel_s24(struct audio_stream __sparse_cache *sink, int * parameters: multichannel stream is treated as single channel and so the entire stream * contents is mixed. */ -static void normal_mix_channel_s32(struct audio_stream __sparse_cache *sink, int32_t start_frame, +static void normal_mix_channel_s32(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, - const struct audio_stream __sparse_cache *source, + const struct audio_stream *source, int32_t frame_count, uint16_t gain) { int frames_to_mix, frames_to_copy, left_frames; @@ -315,7 +315,7 @@ static void normal_mix_channel_s32(struct audio_stream __sparse_cache *sink, int #endif /* CONFIG_FORMAT_S32LE */ #if CONFIG_FORMAT_S32LE || CONFIG_FORMAT_S24LE -static void mute_channel_s32(struct audio_stream __sparse_cache *stream, int32_t channel_index, +static void mute_channel_s32(struct audio_stream *stream, int32_t channel_index, int32_t start_frame, int32_t mixed_frames, int32_t frame_count) { int skip_mixed_frames, left_frames; diff --git a/src/audio/module_adapter/CMakeLists.txt b/src/audio/module_adapter/CMakeLists.txt index e803f78ba91a..72dc1492b3ff 100644 --- a/src/audio/module_adapter/CMakeLists.txt +++ b/src/audio/module_adapter/CMakeLists.txt @@ -1,9 +1,13 @@ # SPDX-License-Identifier: BSD-3-Clause -add_local_sources(sof module_adapter.c module/generic.c) +if(CONFIG_IPC_MAJOR_3) + add_local_sources(sof module_adapter.c module_adapter_ipc3.c module/generic.c) +elseif(CONFIG_IPC_MAJOR_4) + add_local_sources(sof module_adapter.c module_adapter_ipc4.c module/generic.c) +endif() -if((NOT CONFIG_LIBRARY) OR CONFIG_LIBRARY_STATIC) +if(NOT CONFIG_COMP_MODULE_SHARED_LIBRARY_BUILD) if(CONFIG_CADENCE_CODEC) add_local_sources(sof module/cadence.c) diff --git a/src/audio/module_adapter/Kconfig b/src/audio/module_adapter/Kconfig index 1bd6da3e5cf9..ba8370bf6f6e 100644 --- a/src/audio/module_adapter/Kconfig +++ b/src/audio/module_adapter/Kconfig @@ -150,86 +150,6 @@ if CADENCE_CODEC endif # Cadence - config COMP_VOLUME - bool "Volume component" - default y - depends on COMP_MODULE_ADAPTER - help - Select for Volume component - -if COMP_VOLUME - -config COMP_VOLUME_WINDOWS_FADE - bool "Windows Fade shape volume transitions support" - help - This option enables volume ramp shape that follows - power of 1.75. The shape is not linear, not logarithmic. - The power function uses a lookup table that consumes - 256 bytes. The topology must set volume ramp token to - SOF_VOLUME_WINDOWS_FADE for the volume instance to use - this ramp shape. - -config COMP_VOLUME_LINEAR_RAMP - bool "Linear ramp volume transitions support" - default y - depends on IPC_MAJOR_3 - help - This option enables volume linear ramp shape. - -config COMP_PEAK_VOL - bool "Report peak vol data to host" - default y - depends on IPC_MAJOR_4 - help - This option enables reporting to host peak vol regs. - See: struct ipc4_peak_volume_regs - -choice "PEAK_METER_UPDATE_PERIOD_CHOICE" - prompt "The periods(ms) of updating peak meter value" - default PEAK_METER_UPDATE_10MS - depends on COMP_PEAK_VOL - - config PEAK_METER_UPDATE_1MS - bool "1ms" - help - Update the peak meter value every 1ms - - config PEAK_METER_UPDATE_10MS - bool "10ms" - help - Update the peak meter value every 10ms - - config PEAK_METER_UPDATE_100MS - bool "100ms" - help - Update the peak meter value every 100ms - - config PEAK_METER_UPDATE_1000MS - bool "1000ms" - help - Update the peak meter value every 1000ms - endchoice - -config PEAK_METER_UPDATE_PERIOD - int - depends on COMP_PEAK_VOL - default 1 if PEAK_METER_UPDATE_1MS - default 10 if PEAK_METER_UPDATE_10MS - default 100 if PEAK_METER_UPDATE_100MS - default 1000 if PEAK_METER_UPDATE_1000MS - help - Decide which period of update the peak volume meter value - -config COMP_GAIN - bool "GAIN component" - default y - depends on IPC_MAJOR_4 - help - This option enables gain to change volume. It works - as peak volume without updating peak vol to host - -endif # volume - config PASSTHROUGH_CODEC bool "Passthrough codec" default n diff --git a/src/audio/module_adapter/iadk/module_initial_settings_concrete.cpp b/src/audio/module_adapter/iadk/module_initial_settings_concrete.cpp index 2460aaee51b3..bf8909d8b543 100644 --- a/src/audio/module_adapter/iadk/module_initial_settings_concrete.cpp +++ b/src/audio/module_adapter/iadk/module_initial_settings_concrete.cpp @@ -49,6 +49,9 @@ ModuleInitialSettingsConcrete::ModuleInitialSettingsConcrete(DwordArray const &c /* It shall contain BaseModuleCfg + BaseModuleCfgExt + */ /* optionally some InputPinFormat[] + OutputPinFormat[] data */ CompoundCfg const * unvalidated_compound_cfg = cfg_ipc_msg.dataAs(); + if (!unvalidated_compound_cfg) + return; + const size_t computed_msg_size = sizeof(CompoundCfg) - /* CompoundCfg already contains one InputPinFormat and diff --git a/src/audio/module_adapter/library/native_system_agent.c b/src/audio/module_adapter/library/native_system_agent.c index b2d798c14238..58c24fadf31a 100644 --- a/src/audio/module_adapter/library/native_system_agent.c +++ b/src/audio/module_adapter/library/native_system_agent.c @@ -30,9 +30,6 @@ void *native_system_agent_start(uint32_t *sys_service, native_sys_agent.log_handle = log_handle; void *system_agent_p = &native_sys_agent; - uint32_t **sys_service_p = &sys_service; - - *sys_service_p = (uint32_t *)(&native_sys_agent.system_service); native_create_instance_f ci = (native_create_instance_f)entry_point; diff --git a/src/audio/module_adapter/module/cadence.c b/src/audio/module_adapter/module/cadence.c index 9279ce3a430a..14a849cebe85 100644 --- a/src/audio/module_adapter/module/cadence.c +++ b/src/audio/module_adapter/module/cadence.c @@ -633,8 +633,8 @@ static int cadence_codec_init_process(struct processing_module *mod) } static int cadence_codec_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { int ret = 0, mem_tabs_size; struct comp_dev *dev = mod->dev; @@ -716,7 +716,6 @@ cadence_codec_process(struct processing_module *mod, struct output_stream_buffer *output_buffers, int num_output_buffers) { struct comp_buffer *local_buff; - struct comp_buffer __sparse_cache *buffer_c; struct comp_dev *dev = mod->dev; struct module_data *codec = &mod->priv; struct cadence_codec_data *cd = codec->private; @@ -747,9 +746,7 @@ cadence_codec_process(struct processing_module *mod, /* do not proceed with processing if not enough free space left in the local buffer */ local_buff = list_first_item(&mod->sink_buffer_list, struct comp_buffer, sink_list); - buffer_c = buffer_acquire(local_buff); - free_bytes = audio_stream_get_free(&buffer_c->stream); - buffer_release(buffer_c); + free_bytes = audio_stream_get_free(&local_buff->stream); if (free_bytes < output_bytes) return -ENOSPC; @@ -879,8 +876,8 @@ cadence_codec_set_configuration(struct processing_module *mod, uint32_t config_i return 0; } -static struct module_interface cadence_interface = { - .init = cadence_codec_init, +static const struct module_interface cadence_interface = { + .init = cadence_codec_init, .prepare = cadence_codec_prepare, .process_raw_data = cadence_codec_process, .set_configuration = cadence_codec_set_configuration, diff --git a/src/audio/module_adapter/module/dts/dts.c b/src/audio/module_adapter/module/dts/dts.c index 62415f38c660..01eb8063e70d 100644 --- a/src/audio/module_adapter/module/dts/dts.c +++ b/src/audio/module_adapter/module/dts/dts.c @@ -78,8 +78,7 @@ static int dts_effect_populate_buffer_configuration(struct comp_dev *dev, { struct comp_buffer *source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - struct comp_buffer __sparse_cache *source_c; - const struct audio_stream __sparse_cache *stream; + const struct audio_stream *stream; DtsSofInterfaceBufferLayout buffer_layout; DtsSofInterfaceBufferFormat buffer_format; unsigned int buffer_fmt, frame_fmt, rate, channels; @@ -89,16 +88,12 @@ static int dts_effect_populate_buffer_configuration(struct comp_dev *dev, if (!source) return -EINVAL; - source_c = buffer_acquire(source); - - stream = &source_c->stream; + stream = &source->stream; buffer_fmt = audio_stream_get_buffer_fmt(stream); frame_fmt = audio_stream_get_frm_fmt(stream); rate = audio_stream_get_rate(stream); channels = audio_stream_get_channels(stream); - buffer_release(source_c); - switch (buffer_fmt) { case SOF_IPC_BUFFER_INTERLEAVED: buffer_layout = DTS_SOF_INTERFACE_BUFFER_LAYOUT_INTERLEAVED; @@ -184,8 +179,8 @@ static int dts_codec_init(struct processing_module *mod) } static int dts_codec_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { int ret; struct comp_dev *dev = mod->dev; @@ -451,8 +446,8 @@ dts_codec_set_configuration(struct processing_module *mod, uint32_t config_id, return 0; } -static struct module_interface dts_interface = { - .init = dts_codec_init, +static const struct module_interface dts_interface = { + .init = dts_codec_init, .prepare = dts_codec_prepare, .process_raw_data = dts_codec_process, .set_configuration = dts_codec_set_configuration, diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index 760652982245..3cba00e5b7bc 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -75,7 +75,7 @@ int module_load_config(struct comp_dev *dev, const void *cfg, size_t size) return ret; } -int module_init(struct processing_module *mod, struct module_interface *interface) +int module_init(struct processing_module *mod, const struct module_interface *interface) { int ret; struct module_data *md = &mod->priv; @@ -196,8 +196,8 @@ static int validate_config(struct module_config *cfg) } int module_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { int ret; struct module_data *md = &mod->priv; @@ -222,8 +222,7 @@ int module_prepare(struct processing_module *mod, * as it has been applied during the procedure - it is safe to * free it. */ - if (md->cfg.data) - rfree(md->cfg.data); + rfree(md->cfg.data); md->cfg.avail = false; md->cfg.data = NULL; @@ -283,8 +282,8 @@ int module_process_legacy(struct processing_module *mod, } int module_process_sink_src(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct comp_dev *dev = mod->dev; @@ -520,3 +519,14 @@ int module_unbind(struct processing_module *mod, void *data) return md->ops->unbind(mod, data); return 0; } + +void module_update_buffer_position(struct input_stream_buffer *input_buffers, + struct output_stream_buffer *output_buffers, + uint32_t frames) +{ + struct audio_stream *source = input_buffers->data; + struct audio_stream *sink = output_buffers->data; + + input_buffers->consumed += audio_stream_frame_bytes(source) * frames; + output_buffers->size += audio_stream_frame_bytes(sink) * frames; +} diff --git a/src/audio/module_adapter/module/modules.c b/src/audio/module_adapter/module/modules.c index 865aa945baea..3a2fd29abd04 100644 --- a/src/audio/module_adapter/module/modules.c +++ b/src/audio/module_adapter/module/modules.c @@ -155,8 +155,8 @@ static int modules_init(struct processing_module *mod) * There is one assumption - all IADK modules utilize IPC4 protocol. */ static int modules_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct comp_dev *dev = mod->dev; int ret = 0; @@ -375,8 +375,8 @@ static int modules_reset(struct processing_module *mod) } /* Processing Module Adapter API*/ -static struct module_interface interface = { - .init = modules_init, +static const struct module_interface interface = { + .init = modules_init, .prepare = modules_prepare, .process_raw_data = modules_process, .set_processing_mode = modules_set_processing_mode, diff --git a/src/audio/module_adapter/module/passthrough.c b/src/audio/module_adapter/module/passthrough.c index a7e41c04ff65..af8a7227f346 100644 --- a/src/audio/module_adapter/module/passthrough.c +++ b/src/audio/module_adapter/module/passthrough.c @@ -21,8 +21,8 @@ static int passthrough_codec_init(struct processing_module *mod) } static int passthrough_codec_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct comp_dev *dev = mod->dev; struct module_data *codec = &mod->priv; @@ -116,8 +116,8 @@ static int passthrough_codec_free(struct processing_module *mod) return 0; } -static struct module_interface passthrough_interface = { - .init = passthrough_codec_init, +static const struct module_interface passthrough_interface = { + .init = passthrough_codec_init, .prepare = passthrough_codec_prepare, .process_raw_data = passthrough_codec_process, .reset = passthrough_codec_reset, diff --git a/src/audio/module_adapter/module/waves/waves.c b/src/audio/module_adapter/module/waves/waves.c index 570a68f27b82..ab178b022eb9 100644 --- a/src/audio/module_adapter/module/waves/waves.c +++ b/src/audio/module_adapter/module/waves/waves.c @@ -220,11 +220,8 @@ static int waves_effect_check(struct comp_dev *dev) source_list); struct comp_buffer *source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - struct comp_buffer __sparse_cache *source_c = buffer_acquire(source); - struct comp_buffer __sparse_cache *sink_c = buffer_acquire(sink); - const struct audio_stream __sparse_cache *src_fmt = &source_c->stream; - const struct audio_stream __sparse_cache *snk_fmt = &sink_c->stream; - int ret = 0; + const struct audio_stream *src_fmt = &source->stream; + const struct audio_stream *snk_fmt = &sink->stream; /* Init sink & source buffers */ comp_dbg(dev, "waves_effect_check() start"); @@ -235,66 +232,53 @@ static int waves_effect_check(struct comp_dev *dev) if (audio_stream_get_rate(src_fmt) != audio_stream_get_rate(snk_fmt)) { comp_err(dev, "waves_effect_check() source %d sink %d rate mismatch", audio_stream_get_rate(src_fmt), audio_stream_get_rate(snk_fmt)); - ret = -EINVAL; - goto out; + return -EINVAL; } /* upmix/downmix not supported */ if (audio_stream_get_channels(src_fmt) != audio_stream_get_channels(snk_fmt)) { comp_err(dev, "waves_effect_check() source %d sink %d channels mismatch", audio_stream_get_channels(src_fmt), audio_stream_get_channels(snk_fmt)); - ret = -EINVAL; - goto out; + return -EINVAL; } /* different frame format not supported */ if (audio_stream_get_frm_fmt(src_fmt) != audio_stream_get_frm_fmt(snk_fmt)) { comp_err(dev, "waves_effect_check() source %d sink %d sample format mismatch", audio_stream_get_frm_fmt(src_fmt), audio_stream_get_frm_fmt(snk_fmt)); - ret = -EINVAL; - goto out; + return -EINVAL; } /* different interleaving is not supported */ if (audio_stream_get_buffer_fmt(src_fmt) != audio_stream_get_buffer_fmt(snk_fmt)) { comp_err(dev, "waves_effect_check() source %d sink %d buffer format mismatch"); - ret = -EINVAL; - goto out; + return -EINVAL; } if (!format_is_supported(audio_stream_get_frm_fmt(src_fmt))) { comp_err(dev, "waves_effect_check() float samples not supported"); - ret = -EINVAL; - goto out; + return -EINVAL; } if (!layout_is_supported(audio_stream_get_buffer_fmt(src_fmt))) { comp_err(dev, "waves_effect_check() non interleaved format not supported"); - ret = -EINVAL; - goto out; + return -EINVAL; } if (!rate_is_supported(audio_stream_get_rate(src_fmt))) { comp_err(dev, "waves_effect_check() rate %d not supported", audio_stream_get_rate(src_fmt)); - ret = -EINVAL; - goto out; + return -EINVAL; } if (audio_stream_get_channels(src_fmt) != 2) { comp_err(dev, "waves_effect_check() channels %d not supported", audio_stream_get_channels(src_fmt)); - ret = -EINVAL; - goto out; + return -EINVAL; } comp_dbg(dev, "waves_effect_check() done"); - -out: - buffer_release(sink_c); - buffer_release(source_c); - - return ret; + return 0; } /* initializes MaxxEffect based on stream parameters */ @@ -303,17 +287,15 @@ static int waves_effect_init(struct processing_module *mod) struct comp_dev *dev = mod->dev; struct comp_buffer *source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - struct comp_buffer __sparse_cache *source_c = buffer_acquire(source); struct module_data *codec = &mod->priv; struct waves_codec_data *waves_codec = codec->private; - const struct audio_stream __sparse_cache *src_fmt = &source_c->stream; + const struct audio_stream *src_fmt = &source->stream; MaxxStatus_t status; MaxxBuffer_Format_t sample_format; MaxxBuffer_Layout_t buffer_format; int32_t sample_bytes; MaxxStreamFormat_t *i_formats[NUM_IO_STREAMS] = { &waves_codec->i_format }; MaxxStreamFormat_t *o_formats[NUM_IO_STREAMS] = { &waves_codec->o_format }; - int ret = 0; comp_dbg(dev, "waves_effect_init() start"); @@ -321,24 +303,21 @@ static int waves_effect_init(struct processing_module *mod) if (sample_format < 0) { comp_err(dev, "waves_effect_init() sof sample format %d not supported", audio_stream_get_frm_fmt(src_fmt)); - ret = -EINVAL; - goto out; + return -EINVAL; } buffer_format = layout_convert_sof_to_me(audio_stream_get_buffer_fmt(src_fmt)); if (buffer_format < 0) { comp_err(dev, "waves_effect_init() sof buffer format %d not supported", audio_stream_get_buffer_fmt(src_fmt)); - ret = -EINVAL; - goto out; + return -EINVAL; } sample_bytes = sample_format_convert_to_bytes(sample_format); if (sample_bytes < 0) { comp_err(dev, "waves_effect_init() sample_format %d not supported", sample_format); - ret = -EINVAL; - goto out; + return -EINVAL; } waves_codec->request_max_bytes = 0; @@ -373,16 +352,11 @@ static int waves_effect_init(struct processing_module *mod) if (status) { comp_err(dev, "waves_effect_init() MaxxEffect_Initialize returned %d", status); - ret = -EINVAL; - goto out; + return -EINVAL; } comp_dbg(dev, "waves_effect_init() done"); - -out: - buffer_release(source_c); - - return ret; + return 0; } /* allocate additional buffers for MaxxEffect */ @@ -686,8 +660,8 @@ static int waves_codec_init(struct processing_module *mod) } static int waves_codec_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct comp_dev *dev = mod->dev; int ret; @@ -883,8 +857,8 @@ waves_codec_set_configuration(struct processing_module *mod, uint32_t config_id, return 0; } -static struct module_interface waves_interface = { - .init = waves_codec_init, +static const struct module_interface waves_interface = { + .init = waves_codec_init, .prepare = waves_codec_prepare, .process_raw_data = waves_codec_process, .set_configuration = waves_codec_set_configuration, diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index e28541560403..a1f18cd034b4 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -14,6 +14,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -24,19 +28,6 @@ LOG_MODULE_REGISTER(module_adapter, CONFIG_SOF_LOG_LEVEL); -/* - * helpers to determine processing type - * Needed till all the modules use PROCESSING_MODE_SINK_SOURCE - */ -#define IS_PROCESSING_MODE_AUDIO_STREAM(mod) \ - (!!((struct module_data *)&(mod)->priv)->ops->process_audio_stream) - -#define IS_PROCESSING_MODE_RAW_DATA(mod) \ - (!!((struct module_data *)&(mod)->priv)->ops->process_raw_data) - -#define IS_PROCESSING_MODE_SINK_SOURCE(mod) \ - (!!((struct module_data *)&(mod)->priv)->ops->process) - /* * \brief Create a module adapter component. * \param[in] drv - component driver pointer. @@ -46,7 +37,7 @@ LOG_MODULE_REGISTER(module_adapter, CONFIG_SOF_LOG_LEVEL); */ struct comp_dev *module_adapter_new(const struct comp_driver *drv, const struct comp_ipc_config *config, - struct module_interface *interface, const void *spec) + const struct module_interface *interface, const void *spec) { int ret; struct comp_dev *dev; @@ -69,83 +60,34 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, dev->ipc_config = *config; dev->drv = drv; - mod = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*mod)); + /* allocate module information. + * for DP shared modules this struct must be accessible from all cores + * Unfortunately at this point there's no information of components the module + * will be bound to. So we need to allocate shared memory for each DP module + * To be removed when pipeline 2.0 is ready + */ + enum mem_zone zone = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ? + SOF_MEM_ZONE_RUNTIME_SHARED : SOF_MEM_ZONE_RUNTIME; + + mod = rzalloc(zone, 0, SOF_MEM_CAPS_RAM, sizeof(*mod)); if (!mod) { comp_err(dev, "module_adapter_new(), failed to allocate memory for module"); rfree(dev); return NULL; } - /* align the allocation size to a cache line for the coherent API */ - mod->source_info = coherent_init_thread(struct module_source_info, c); - if (!mod->source_info) { - rfree(dev); - rfree(mod); - return NULL; - } - dst = &mod->priv.cfg; mod->dev = dev; comp_set_drvdata(dev, mod); list_init(&mod->sink_buffer_list); -#if CONFIG_IPC_MAJOR_3 - const unsigned char *data; - uint32_t size; - - switch (config->type) { - case SOF_COMP_VOLUME: - { - const struct ipc_config_volume *ipc_volume = spec; - - size = sizeof(*ipc_volume); - data = spec; - break; - } - case SOF_COMP_SRC: - { - const struct ipc_config_src *ipc_src = spec; - - size = sizeof(*ipc_src); - data = spec; - break; - } - default: - { - const struct ipc_config_process *ipc_module_adapter = spec; - - size = ipc_module_adapter->size; - data = ipc_module_adapter->data; - break; - } - } - - /* Copy initial config */ - if (size) { - ret = module_load_config(dev, data, size); - if (ret) { - comp_err(dev, "module_adapter_new() error %d: config loading has failed.", - ret); - goto err; - } - dst->init_data = dst->data; - } else { + ret = module_adapter_init_data(dev, dst, config, spec); + if (ret) { + comp_err(dev, "module_adapter_new() %d: module init data failed", + ret); goto err; } -#else - if (drv->type == SOF_COMP_MODULE_ADAPTER) { - const struct ipc_config_process *ipc_module_adapter = spec; - - dst->init_data = ipc_module_adapter->data; - dst->size = ipc_module_adapter->size; - dst->avail = true; - - memcpy(&dst->base_cfg, ipc_module_adapter->data, sizeof(dst->base_cfg)); - } else { - dst->init_data = spec; - } -#endif /* Modules must modify them if they support more than 1 source/sink */ mod->max_sources = 1; @@ -159,15 +101,19 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, goto err; } -#if CONFIG_IPC_MAJOR_4 - dst->init_data = NULL; -#endif +#if CONFIG_ZEPHYR_DP_SCHEDULER + /* create a task for DP processing */ + if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP) + pipeline_comp_dp_task_init(dev); +#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ + + module_adapter_reset_data(dst); + dev->state = COMP_STATE_READY; comp_dbg(dev, "module_adapter_new() done"); return dev; err: - coherent_free_thread(mod->source_info, c); rfree(mod); rfree(dev); return NULL; @@ -175,53 +121,181 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, static int module_adapter_sink_src_prepare(struct comp_dev *dev) { - struct comp_buffer __sparse_cache *source_buffers_c[PLATFORM_MAX_STREAMS]; - struct comp_buffer __sparse_cache *sinks_buffers_c[PLATFORM_MAX_STREAMS]; - struct sof_sink __sparse_cache *audio_sink[PLATFORM_MAX_STREAMS]; - struct sof_source __sparse_cache *audio_src[PLATFORM_MAX_STREAMS]; struct processing_module *mod = comp_get_drvdata(dev); struct list_item *blist; - uint32_t num_of_sources = 0; - uint32_t num_of_sinks = 0; int ret; - int i = 0; + int i; /* acquire all sink and source buffers, get handlers to sink/source API */ + i = 0; list_for_item(blist, &dev->bsink_list) { - struct comp_buffer *sink_buffer_uc; - - sink_buffer_uc = container_of(blist, struct comp_buffer, source_list); - sinks_buffers_c[num_of_sinks] = buffer_acquire(sink_buffer_uc); - audio_sink[num_of_sinks] = - audio_stream_get_sink(&sinks_buffers_c[num_of_sinks]->stream); - sink_reset_num_of_processed_bytes(audio_sink[num_of_sinks]); - num_of_sinks++; + struct comp_buffer *sink_buffer = + container_of(blist, struct comp_buffer, source_list); + mod->sinks[i] = audio_stream_get_sink(&sink_buffer->stream); + i++; } + mod->num_of_sinks = i; + i = 0; list_for_item(blist, &dev->bsource_list) { - struct comp_buffer *source_buffer_uc; + struct comp_buffer *source_buffer = + container_of(blist, struct comp_buffer, sink_list); - source_buffer_uc = container_of(blist, struct comp_buffer, sink_list); - source_buffers_c[num_of_sources] = buffer_acquire(source_buffer_uc); - audio_src[num_of_sources] = - audio_stream_get_source(&source_buffers_c[num_of_sources]->stream); - source_reset_num_of_processed_bytes(audio_src[num_of_sources]); - num_of_sources++; + mod->sources[i] = audio_stream_get_source(&source_buffer->stream); + i++; } + mod->num_of_sources = i; /* Prepare module */ - ret = module_prepare(mod, audio_src, num_of_sources, audio_sink, num_of_sinks); + ret = module_prepare(mod, mod->sources, mod->num_of_sources, mod->sinks, mod->num_of_sinks); + + return ret; +} + +#if CONFIG_ZEPHYR_DP_SCHEDULER +static int module_adapter_dp_queue_prepare(struct comp_dev *dev) +{ + int dp_mode = dev->is_shared ? DP_QUEUE_MODE_SHARED : DP_QUEUE_MODE_LOCAL; + struct processing_module *mod = comp_get_drvdata(dev); + struct dp_queue *dp_queue; + struct list_item *blist; + int ret; + int i; + + /* for DP processing we need to create a DP QUEUE for each module input/output + * till pipeline2.0 is ready, DP processing requires double buffering + * + * first, set all parameters by calling "module prepare" with pointers to + * "main" audio_stream buffers + */ + ret = module_adapter_sink_src_prepare(dev); + if (ret) + return ret; - /* release all source buffers in reverse order */ - for (i = num_of_sources - 1; i >= 0; i--) - buffer_release(source_buffers_c[i]); + /* + * second step - create a "shadow" cross-core DpQueue for existing buffers + * and copy stream parameters to shadow buffers + */ + i = 0; + list_init(&mod->dp_queue_ll_to_dp_list); + list_for_item(blist, &dev->bsource_list) { + struct comp_buffer *source_buffer = + container_of(blist, struct comp_buffer, sink_list); - /* release all sink buffers in reverse order */ - for (i = num_of_sinks - 1; i >= 0 ; i--) - buffer_release(sinks_buffers_c[i]); + /* copy IBS & OBS from buffer to be shadowed */ + size_t min_available = + source_get_min_available(audio_stream_get_source(&source_buffer->stream)); + size_t min_free_space = + sink_get_min_free_space(audio_stream_get_sink(&source_buffer->stream)); - return ret; + /* create a shadow dp queue */ + dp_queue = dp_queue_create(min_available, min_free_space, dp_mode); + + if (!dp_queue) + goto err; + dp_queue_append_to_list(dp_queue, &mod->dp_queue_ll_to_dp_list); + + /* it will override source pointers set by module_adapter_sink_src_prepare + * module will use shadow dpQueue for processing + */ + mod->sources[i] = dp_queue_get_source(dp_queue); + + /* copy parameters from buffer to be shadowed */ + memcpy_s(&dp_queue->audio_stream_params, + sizeof(dp_queue->audio_stream_params), + &source_buffer->stream.runtime_stream_params, + sizeof(source_buffer->stream.runtime_stream_params)); + i++; + } + mod->num_of_sources = i; + unsigned int period = UINT32_MAX; + + i = 0; + list_init(&mod->dp_queue_dp_to_ll_list); + list_for_item(blist, &dev->bsink_list) { + struct comp_buffer *sink_buffer = + container_of(blist, struct comp_buffer, source_list); + + /* copy IBS & OBS from buffer to be shadowed */ + size_t min_available = + source_get_min_available(audio_stream_get_source(&sink_buffer->stream)); + size_t min_free_space = + sink_get_min_free_space(audio_stream_get_sink(&sink_buffer->stream)); + + /* create a shadow dp queue */ + dp_queue = dp_queue_create(min_available, min_free_space, dp_mode); + + if (!dp_queue) + goto err; + + dp_queue_append_to_list(dp_queue, &mod->dp_queue_dp_to_ll_list); + /* it will override sink pointers set by module_adapter_sink_src_prepare + * module will use shadow dpQueue for processing + */ + mod->sinks[i] = dp_queue_get_sink(dp_queue); + + /* copy parameters from buffer to be shadowed */ + memcpy_s(&dp_queue->audio_stream_params, + sizeof(dp_queue->audio_stream_params), + &sink_buffer->stream.runtime_stream_params, + sizeof(sink_buffer->stream.runtime_stream_params)); + /* calculate time required the module to provide OBS data portion - a period */ + unsigned int sink_period = 1000000 * sink_get_min_free_space(mod->sinks[i]) / + (sink_get_frame_bytes(mod->sinks[i]) * + sink_get_rate(mod->sinks[i])); + /* note the minimal period for the module */ + if (period > sink_period) + period = sink_period; + + i++; + } + mod->num_of_sinks = i; + /* set the period for the module unless it has already been calculated by the + * module itself during prepare + * It may happen i.e. for modules like phrase detect that do not produce audio data + * but events and therefore don't have any deadline for processing + * Second example is a module with variable data rate on output (like MPEG encoder) + */ + if (!dev->period) { + comp_info(dev, "DP Module period set to %u", period); + dev->period = period; + } + + return 0; + +err:; + struct list_item *dp_queue_list_item; + struct list_item *tmp; + + i = 0; + list_for_item_safe(dp_queue_list_item, tmp, &mod->dp_queue_dp_to_ll_list) { + struct dp_queue *dp_queue = + container_of(dp_queue_list_item, struct dp_queue, list); + + /* dp free will also remove the queue from a list */ + dp_queue_free(dp_queue); + mod->sources[i++] = NULL; + } + mod->num_of_sources = 0; + + i = 0; + list_for_item_safe(dp_queue_list_item, tmp, &mod->dp_queue_ll_to_dp_list) { + struct dp_queue *dp_queue = + container_of(dp_queue_list_item, struct dp_queue, list); + + dp_queue_free(dp_queue); + mod->sinks[i++] = NULL; + } + mod->num_of_sinks = 0; + + return -ENOMEM; +} +#else +static inline int module_adapter_dp_queue_prepare(struct comp_dev *dev) +{ + return -EINVAL; } +#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ /* * \brief Prepare the module @@ -236,8 +310,6 @@ int module_adapter_prepare(struct comp_dev *dev) int ret; struct processing_module *mod = comp_get_drvdata(dev); struct module_data *md = &mod->priv; - struct comp_buffer __sparse_cache *buffer_c; - struct comp_buffer __sparse_cache *sink_c; struct comp_buffer *sink; struct list_item *blist, *_blist; uint32_t buff_periods; @@ -247,11 +319,21 @@ int module_adapter_prepare(struct comp_dev *dev) comp_dbg(dev, "module_adapter_prepare() start"); /* Prepare module */ - if (IS_PROCESSING_MODE_SINK_SOURCE(mod)) + if (IS_PROCESSING_MODE_SINK_SOURCE(mod) && + mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) + ret = module_adapter_dp_queue_prepare(dev); + + else if (IS_PROCESSING_MODE_SINK_SOURCE(mod) && + mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL) ret = module_adapter_sink_src_prepare(dev); - else + + else if ((IS_PROCESSING_MODE_RAW_DATA(mod) || IS_PROCESSING_MODE_AUDIO_STREAM(mod)) && + mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL) ret = module_prepare(mod, NULL, 0, NULL, 0); + else + ret = -EINVAL; + if (ret) { if (ret != PPL_STATUS_PATH_STOP) comp_err(dev, "module_adapter_prepare() error %x: module prepare failed", @@ -286,35 +368,25 @@ int module_adapter_prepare(struct comp_dev *dev) * parameter from sink buffer is settled, and still prior to all references to period_bytes. */ sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); - mod->period_bytes = audio_stream_period_bytes(&sink_c->stream, dev->frames); + mod->period_bytes = audio_stream_period_bytes(&sink->stream, dev->frames); comp_dbg(dev, "module_adapter_prepare(): got period_bytes = %u", mod->period_bytes); - buffer_release(sink_c); - - /* - * compute number of input buffers and make the source_info shared if the module is on a - * different core than any of it's sources - */ - list_for_item(blist, &dev->bsource_list) { - struct comp_buffer *buf; - struct comp_dev *source; - - buf = buffer_from_list(blist, PPL_DIR_UPSTREAM); - source = buffer_get_comp(buf, PPL_DIR_UPSTREAM); - - if (source->pipeline && source->pipeline->core != dev->pipeline->core) - coherent_shared_thread(mod->source_info, c); + /* no more to do for sink/source mode */ + if (IS_PROCESSING_MODE_SINK_SOURCE(mod)) + return 0; - mod->num_input_buffers++; - } + /* compute number of input buffers */ + mod->num_of_sources = 0; + list_for_item(blist, &dev->bsource_list) + mod->num_of_sources++; /* compute number of output buffers */ + mod->num_of_sinks = 0; list_for_item(blist, &dev->bsink_list) - mod->num_output_buffers++; + mod->num_of_sinks++; - if (!mod->num_input_buffers && !mod->num_output_buffers) { + if (!mod->num_of_sources && !mod->num_of_sinks) { comp_err(dev, "module_adapter_prepare(): no source and sink buffers connected!"); return -EINVAL; } @@ -325,18 +397,7 @@ int module_adapter_prepare(struct comp_dev *dev) return -EINVAL; } -#if CONFIG_IPC_MAJOR_3 - /* Check if audio stream client has only one source and one sink buffer to use a - * simplified copy function. - */ - if (IS_PROCESSING_MODE_AUDIO_STREAM(mod) && mod->num_input_buffers == 1 && - mod->num_output_buffers == 1) { - mod->source_comp_buffer = list_first_item(&dev->bsource_list, - struct comp_buffer, sink_list); - mod->sink_comp_buffer = sink; - mod->stream_copy_single_to_single = true; - } -#endif + module_adapter_check_data(mod, dev, sink); /* allocate memory for input buffers */ if (mod->max_sources) { @@ -421,8 +482,7 @@ int module_adapter_prepare(struct comp_dev *dev) list_for_item(blist, &dev->bsource_list) { size_t size = MAX(mod->deep_buff_bytes, mod->period_bytes); - mod->input_buffers[i].data = - (__sparse_force void __sparse_cache *)rballoc(0, SOF_MEM_CAPS_RAM, size); + mod->input_buffers[i].data = rballoc(0, SOF_MEM_CAPS_RAM, size); if (!mod->input_buffers[i].data) { comp_err(mod->dev, "module_adapter_prepare(): Failed to alloc input buffer data"); ret = -ENOMEM; @@ -434,9 +494,7 @@ int module_adapter_prepare(struct comp_dev *dev) /* allocate memory for output buffer data */ i = 0; list_for_item(blist, &dev->bsink_list) { - mod->output_buffers[i].data = - (__sparse_force void __sparse_cache *)rballoc(0, SOF_MEM_CAPS_RAM, - md->mpd.out_buff_size); + mod->output_buffers[i].data = rballoc(0, SOF_MEM_CAPS_RAM, md->mpd.out_buff_size); if (!mod->output_buffers[i].data) { comp_err(mod->dev, "module_adapter_prepare(): Failed to alloc output buffer data"); ret = -ENOMEM; @@ -447,9 +505,10 @@ int module_adapter_prepare(struct comp_dev *dev) /* allocate buffer for all sinks */ if (list_is_empty(&mod->sink_buffer_list)) { - for (i = 0; i < mod->num_output_buffers; i++) { + for (i = 0; i < mod->num_of_sinks; i++) { + /* allocate not shared buffer */ struct comp_buffer *buffer = buffer_alloc(buff_size, SOF_MEM_CAPS_RAM, - 0, PLATFORM_DCACHE_ALIGN); + 0, PLATFORM_DCACHE_ALIGN, false); uint32_t flags; if (!buffer) { @@ -462,28 +521,23 @@ int module_adapter_prepare(struct comp_dev *dev) buffer_attach(buffer, &mod->sink_buffer_list, PPL_DIR_UPSTREAM); irq_local_enable(flags); - buffer_c = buffer_acquire(buffer); - buffer_set_params(buffer_c, mod->stream_params, BUFFER_UPDATE_FORCE); - buffer_reset_pos(buffer_c, NULL); - buffer_release(buffer_c); + buffer_set_params(buffer, mod->stream_params, BUFFER_UPDATE_FORCE); + buffer_reset_pos(buffer, NULL); } } else { list_for_item(blist, &mod->sink_buffer_list) { struct comp_buffer *buffer = container_of(blist, struct comp_buffer, sink_list); - buffer_c = buffer_acquire(buffer); - ret = buffer_set_size(buffer_c, buff_size, 0); + ret = buffer_set_size(buffer, buff_size, 0); if (ret < 0) { - buffer_release(buffer_c); comp_err(dev, "module_adapter_prepare(): buffer_set_size() failed, buff_size = %u", buff_size); goto free; } - buffer_set_params(buffer_c, mod->stream_params, BUFFER_UPDATE_FORCE); - buffer_reset_pos(buffer_c, NULL); - buffer_release(buffer_c); + buffer_set_params(buffer, mod->stream_params, BUFFER_UPDATE_FORCE); + buffer_reset_pos(buffer, NULL); } } @@ -504,16 +558,18 @@ int module_adapter_prepare(struct comp_dev *dev) } out_data_free: - for (i = 0; i < mod->num_output_buffers; i++) - rfree((__sparse_force void *)mod->output_buffers[i].data); + for (i = 0; i < mod->num_of_sinks; i++) + rfree(mod->output_buffers[i].data); in_data_free: - for (i = 0; i < mod->num_input_buffers; i++) - rfree((__sparse_force void *)mod->input_buffers[i].data); + for (i = 0; i < mod->num_of_sources; i++) + rfree(mod->input_buffers[i].data); in_out_free: rfree(mod->output_buffers); + mod->output_buffers = NULL; rfree(mod->input_buffers); + mod->input_buffers = NULL; return ret; } @@ -551,10 +607,7 @@ int module_adapter_params(struct comp_dev *dev, struct sof_ipc_stream_params *pa return ret; } -#if CONFIG_IPC_MAJOR_4 - ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); - ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, mod->stream_params); -#endif + module_adapter_set_params(mod, params); return 0; } @@ -566,8 +619,8 @@ int module_adapter_params(struct comp_dev *dev, struct sof_ipc_stream_params *pa * @bytes: number of bytes available in the source buffer */ static void -ca_copy_from_source_to_module(const struct audio_stream __sparse_cache *source, - void __sparse_cache *buff, uint32_t buff_size, size_t bytes) +ca_copy_from_source_to_module(const struct audio_stream *source, + void *buff, uint32_t buff_size, size_t bytes) { /* head_size - available data until end of source buffer */ const int without_wrap = audio_stream_bytes_without_wrap(source, @@ -594,8 +647,8 @@ ca_copy_from_source_to_module(const struct audio_stream __sparse_cache *source, * @bytes: number of bytes available in the module output buffer */ static void -ca_copy_from_module_to_sink(const struct audio_stream __sparse_cache *sink, - void __sparse_cache *buff, size_t bytes) +ca_copy_from_module_to_sink(const struct audio_stream *sink, + void *buff, size_t bytes) { /* head_size - free space until end of sink buffer */ const int without_wrap = audio_stream_bytes_without_wrap(sink, audio_stream_get_wptr(sink)); @@ -623,7 +676,7 @@ ca_copy_from_module_to_sink(const struct audio_stream __sparse_cache *sink, * * \return: none. */ -static void generate_zeroes(struct comp_buffer __sparse_cache *sink, uint32_t bytes) +static void generate_zeroes(struct comp_buffer *sink, uint32_t bytes) { uint32_t tmp, copy_bytes = bytes; void *ptr; @@ -638,8 +691,8 @@ static void generate_zeroes(struct comp_buffer __sparse_cache *sink, uint32_t by comp_update_buffer_produce(sink, bytes); } -static void module_copy_samples(struct comp_dev *dev, struct comp_buffer __sparse_cache *src_buffer, - struct comp_buffer __sparse_cache *sink_buffer, uint32_t produced) +static void module_copy_samples(struct comp_dev *dev, struct comp_buffer *src_buffer, + struct comp_buffer *sink_buffer, uint32_t produced) { struct processing_module *mod = comp_get_drvdata(dev); struct comp_copy_limits cl; @@ -680,7 +733,6 @@ static void module_adapter_process_output(struct comp_dev *dev) { struct processing_module *mod = comp_get_drvdata(dev); struct comp_buffer *sink; - struct comp_buffer __sparse_cache *sink_c; struct list_item *blist; int i = 0; @@ -691,15 +743,12 @@ static void module_adapter_process_output(struct comp_dev *dev) list_for_item(blist, &mod->sink_buffer_list) { if (mod->output_buffers[i].size > 0) { struct comp_buffer *buffer; - struct comp_buffer __sparse_cache *buffer_c; buffer = container_of(blist, struct comp_buffer, sink_list); - buffer_c = buffer_acquire(buffer); - ca_copy_from_module_to_sink(&buffer_c->stream, mod->output_buffers[i].data, + ca_copy_from_module_to_sink(&buffer->stream, mod->output_buffers[i].data, mod->output_buffers[i].size); - audio_stream_produce(&buffer_c->stream, mod->output_buffers[i].size); - buffer_release(buffer_c); + audio_stream_produce(&buffer->stream, mod->output_buffers[i].size); } i++; } @@ -713,17 +762,12 @@ static void module_adapter_process_output(struct comp_dev *dev) list_for_item(_blist, &mod->sink_buffer_list) { if (i == j) { struct comp_buffer *source; - struct comp_buffer __sparse_cache *source_c; sink = container_of(blist, struct comp_buffer, source_list); source = container_of(_blist, struct comp_buffer, sink_list); - sink_c = buffer_acquire(sink); - source_c = buffer_acquire(source); - module_copy_samples(dev, source_c, sink_c, + module_copy_samples(dev, source, sink, mod->output_buffers[i].size); - buffer_release(source_c); - buffer_release(sink_c); mod->output_buffers[i].size = 0; break; @@ -738,8 +782,8 @@ static void module_adapter_process_output(struct comp_dev *dev) static uint32_t module_single_sink_setup(struct comp_dev *dev, - struct comp_buffer __sparse_cache **source_c, - struct comp_buffer __sparse_cache **sinks_c) + struct comp_buffer **source, + struct comp_buffer **sinks) { struct processing_module *mod = comp_get_drvdata(dev); struct list_item *blist; @@ -748,14 +792,14 @@ module_single_sink_setup(struct comp_dev *dev, int i = 0; list_for_item(blist, &dev->bsource_list) { - frames = audio_stream_avail_frames_aligned(&source_c[i]->stream, - &sinks_c[0]->stream); + frames = audio_stream_avail_frames_aligned(&source[i]->stream, + &sinks[0]->stream); if (!mod->skip_src_buffer_invalidate) { uint32_t source_frame_bytes; - source_frame_bytes = audio_stream_frame_bytes(&source_c[i]->stream); - buffer_stream_invalidate(source_c[i], frames * source_frame_bytes); + source_frame_bytes = audio_stream_frame_bytes(&source[i]->stream); + buffer_stream_invalidate(source[i], frames * source_frame_bytes); } /* @@ -765,22 +809,22 @@ module_single_sink_setup(struct comp_dev *dev, mod->input_buffers[i].size = frames; mod->input_buffers[i].consumed = 0; - mod->input_buffers[i].data = &source_c[i]->stream; + mod->input_buffers[i].data = &source[i]->stream; i++; } num_input_buffers = i; mod->output_buffers[0].size = 0; - mod->output_buffers[0].data = &sinks_c[0]->stream; + mod->output_buffers[0].data = &sinks[0]->stream; return num_input_buffers; } static uint32_t module_single_source_setup(struct comp_dev *dev, - struct comp_buffer __sparse_cache **source_c, - struct comp_buffer __sparse_cache **sinks_c) + struct comp_buffer **source, + struct comp_buffer **sinks) { struct processing_module *mod = comp_get_drvdata(dev); struct list_item *blist; @@ -789,20 +833,20 @@ module_single_source_setup(struct comp_dev *dev, uint32_t source_frame_bytes; int i = 0; - source_frame_bytes = audio_stream_frame_bytes(&source_c[0]->stream); + source_frame_bytes = audio_stream_frame_bytes(&source[0]->stream); if (list_is_empty(&dev->bsink_list)) { - min_frames = audio_stream_get_avail_frames(&source_c[0]->stream); + min_frames = audio_stream_get_avail_frames(&source[0]->stream); } else { uint32_t frames; list_for_item(blist, &dev->bsink_list) { - frames = audio_stream_avail_frames_aligned(&source_c[0]->stream, - &sinks_c[i]->stream); + frames = audio_stream_avail_frames_aligned(&source[0]->stream, + &sinks[i]->stream); min_frames = MIN(min_frames, frames); mod->output_buffers[i].size = 0; - mod->output_buffers[i].data = &sinks_c[i]->stream; + mod->output_buffers[i].data = &sinks[i]->stream; i++; } } @@ -810,12 +854,12 @@ module_single_source_setup(struct comp_dev *dev, num_output_buffers = i; if (!mod->skip_src_buffer_invalidate) - buffer_stream_invalidate(source_c[0], min_frames * source_frame_bytes); + buffer_stream_invalidate(source[0], min_frames * source_frame_bytes); /* note that the size is in number of frames not the number of bytes */ mod->input_buffers[0].size = min_frames; mod->input_buffers[0].consumed = 0; - mod->input_buffers[0].data = &source_c[0]->stream; + mod->input_buffers[0].data = &source[0]->stream; return num_output_buffers; } @@ -823,28 +867,30 @@ module_single_source_setup(struct comp_dev *dev, static int module_adapter_audio_stream_copy_1to1(struct comp_dev *dev) { struct processing_module *mod = comp_get_drvdata(dev); - struct comp_buffer __sparse_cache *source_c; - struct comp_buffer __sparse_cache *sink_c; uint32_t num_output_buffers = 0; uint32_t frames; int ret; - source_c = buffer_acquire(mod->source_comp_buffer); - sink_c = buffer_acquire(mod->sink_comp_buffer); - frames = audio_stream_avail_frames_aligned(&source_c->stream, &sink_c->stream); + frames = audio_stream_avail_frames_aligned(&mod->source_comp_buffer->stream, + &mod->sink_comp_buffer->stream); mod->input_buffers[0].size = frames; mod->input_buffers[0].consumed = 0; - mod->input_buffers[0].data = &source_c->stream; + mod->input_buffers[0].data = &mod->source_comp_buffer->stream; mod->output_buffers[0].size = 0; - mod->output_buffers[0].data = &sink_c->stream; - if (!mod->skip_src_buffer_invalidate) /* TODO: add mod->is_multi_core && optimization */ - buffer_stream_invalidate(source_c, - frames * audio_stream_frame_bytes(&source_c->stream)); + mod->output_buffers[0].data = &mod->sink_comp_buffer->stream; + + if (!mod->skip_src_buffer_invalidate) { /* TODO: add mod->is_multi_core && optimization */ + /* moved bytes to its own variable to fix checkpatch */ + uint32_t bytes = + frames * audio_stream_frame_bytes(&mod->source_comp_buffer->stream); + buffer_stream_invalidate(mod->source_comp_buffer, + bytes); + } /* Note: Source buffer state is not checked to enable mixout to generate zero * PCM codes when source is not active. */ - if (sink_c->sink->state == dev->state) + if (mod->sink_comp_buffer->sink->state == dev->state) num_output_buffers = 1; ret = module_process_legacy(mod, mod->input_buffers, 1, @@ -853,26 +899,24 @@ static int module_adapter_audio_stream_copy_1to1(struct comp_dev *dev) /* consume from the input buffer */ mod->total_data_consumed += mod->input_buffers[0].consumed; if (mod->input_buffers[0].consumed) - audio_stream_consume(&source_c->stream, mod->input_buffers[0].consumed); + audio_stream_consume(&mod->source_comp_buffer->stream, + mod->input_buffers[0].consumed); /* produce data into the output buffer */ mod->total_data_produced += mod->output_buffers[0].size; if (!mod->skip_sink_buffer_writeback) /* TODO: add mod->is_multi_core && optimization */ - buffer_stream_writeback(sink_c, mod->output_buffers[0].size); + buffer_stream_writeback(mod->sink_comp_buffer, mod->output_buffers[0].size); if (mod->output_buffers[0].size) - comp_update_buffer_produce(sink_c, mod->output_buffers[0].size); + comp_update_buffer_produce(mod->sink_comp_buffer, mod->output_buffers[0].size); - /* release all buffers */ - buffer_release(sink_c); - buffer_release(source_c); return ret; } static int module_adapter_audio_stream_type_copy(struct comp_dev *dev) { - struct comp_buffer __sparse_cache *source_c[PLATFORM_MAX_STREAMS]; - struct comp_buffer __sparse_cache *sinks_c[PLATFORM_MAX_STREAMS]; + struct comp_buffer *sources[PLATFORM_MAX_STREAMS]; + struct comp_buffer *sinks[PLATFORM_MAX_STREAMS]; struct processing_module *mod = comp_get_drvdata(dev); struct list_item *blist; uint32_t num_input_buffers, num_output_buffers; @@ -880,11 +924,7 @@ static int module_adapter_audio_stream_type_copy(struct comp_dev *dev) /* handle special case of HOST/DAI type components */ if (dev->ipc_config.type == SOF_COMP_HOST || dev->ipc_config.type == SOF_COMP_DAI) -#if CONFIG_IPC_MAJOR_3 - return module_process_legacy(mod, NULL, 0, NULL, 0); -#else - return module_process_stream(mod, NULL, 0, NULL, 0); -#endif + return module_process_endpoint(mod, NULL, 0, NULL, 0); if (mod->stream_copy_single_to_single) return module_adapter_audio_stream_copy_1to1(dev); @@ -894,7 +934,7 @@ static int module_adapter_audio_stream_type_copy(struct comp_dev *dev) struct comp_buffer *sink; sink = container_of(blist, struct comp_buffer, source_list); - sinks_c[i++] = buffer_acquire(sink); + sinks[i++] = sink; } num_output_buffers = i; if (num_output_buffers > mod->max_sinks) { @@ -907,26 +947,23 @@ static int module_adapter_audio_stream_type_copy(struct comp_dev *dev) struct comp_buffer *source; source = container_of(blist, struct comp_buffer, sink_list); - source_c[i++] = buffer_acquire(source); + sources[i++] = source; } num_input_buffers = i; if (num_input_buffers > mod->max_sources) { - comp_err(dev, "Invalid number of sinks %d\n", num_input_buffers); + comp_err(dev, "Invalid number of sources %d\n", num_input_buffers); return -EINVAL; } /* setup active input/output buffers for processing */ if (num_output_buffers == 1) { - module_single_sink_setup(dev, source_c, sinks_c); - if (sinks_c[0]->sink->state != dev->state) { + module_single_sink_setup(dev, sources, sinks); + if (sinks[0]->sink->state != dev->state) num_output_buffers = 0; - buffer_release(sinks_c[0]); - } } else if (num_input_buffers == 1) { - module_single_source_setup(dev, source_c, sinks_c); - if (source_c[0]->source->state != dev->state) { + module_single_source_setup(dev, sources, sinks); + if (sources[0]->source->state != dev->state) { num_input_buffers = 0; - buffer_release(source_c[0]); } } else { ret = -EINVAL; @@ -948,13 +985,11 @@ static int module_adapter_audio_stream_type_copy(struct comp_dev *dev) /* consume from all active input buffers */ for (i = 0; i < num_input_buffers; i++) { - struct comp_buffer __sparse_cache *src_c; + struct comp_buffer *src = + container_of(mod->input_buffers[i].data, struct comp_buffer, stream); - src_c = attr_container_of(mod->input_buffers[i].data, - struct comp_buffer __sparse_cache, - stream, __sparse_cache); if (mod->input_buffers[i].consumed) - audio_stream_consume(&src_c->stream, mod->input_buffers[i].consumed); + audio_stream_consume(&src->stream, mod->input_buffers[i].consumed); } /* compute data consumed based on pin 0 since it is processed with base config @@ -964,42 +999,35 @@ static int module_adapter_audio_stream_type_copy(struct comp_dev *dev) /* release all source buffers */ for (i = 0; i < num_input_buffers; i++) { - buffer_release(source_c[i]); mod->input_buffers[i].size = 0; mod->input_buffers[i].consumed = 0; } /* produce data into all active output buffers */ for (i = 0; i < num_output_buffers; i++) { - struct comp_buffer __sparse_cache *sink_c; - - sink_c = attr_container_of(mod->output_buffers[i].data, - struct comp_buffer __sparse_cache, - stream, __sparse_cache); + struct comp_buffer *sink = + container_of(mod->output_buffers[i].data, struct comp_buffer, stream); if (!mod->skip_sink_buffer_writeback) - buffer_stream_writeback(sink_c, mod->output_buffers[i].size); + buffer_stream_writeback(sink, mod->output_buffers[i].size); if (mod->output_buffers[i].size) - comp_update_buffer_produce(sink_c, mod->output_buffers[i].size); + comp_update_buffer_produce(sink, mod->output_buffers[i].size); } mod->total_data_produced += mod->output_buffers[0].size; /* release all sink buffers */ for (i = 0; i < num_output_buffers; i++) { - buffer_release(sinks_c[i]); mod->output_buffers[i].size = 0; } return 0; out: for (i = 0; i < num_output_buffers; i++) { - buffer_release(sinks_c[i]); mod->output_buffers[i].size = 0; } for (i = 0; i < num_input_buffers; i++) { - buffer_release(source_c[i]); mod->input_buffers[i].size = 0; mod->input_buffers[i].consumed = 0; } @@ -1007,62 +1035,96 @@ static int module_adapter_audio_stream_type_copy(struct comp_dev *dev) return ret; } -static int module_adapter_sink_source_copy(struct comp_dev *dev) +#if CONFIG_ZEPHYR_DP_SCHEDULER +static int module_adapter_copy_dp_queues(struct comp_dev *dev) { - struct comp_buffer __sparse_cache *source_buffers_c[PLATFORM_MAX_STREAMS]; - struct comp_buffer __sparse_cache *sinks_buffers_c[PLATFORM_MAX_STREAMS]; - struct sof_sink __sparse_cache *audio_sink[PLATFORM_MAX_STREAMS]; - struct sof_source __sparse_cache *audio_src[PLATFORM_MAX_STREAMS]; + /* + * copy data from component audio streams to dp_queue + * DP module processing itself will take place in DP thread + * This is an adapter, to be removed when pipeline2.0 is ready + */ struct processing_module *mod = comp_get_drvdata(dev); + struct dp_queue *dp_queue; struct list_item *blist; - uint32_t num_of_sources = 0; - uint32_t num_of_sinks = 0; - int ret; - int i = 0; + int err; - comp_dbg(dev, "module_adapter_sink_source_copy(): start"); + dp_queue = dp_queue_get_first_item(&mod->dp_queue_ll_to_dp_list); + list_for_item(blist, &dev->bsource_list) { + /* input - we need to copy data from audio_stream (as source) + * to dp_queue (as sink) + */ + assert(dp_queue); + struct comp_buffer *buffer = + container_of(blist, struct comp_buffer, sink_list); + struct sof_source *data_src = audio_stream_get_source(&buffer->stream); + struct sof_sink *data_sink = dp_queue_get_sink(dp_queue); + uint32_t to_copy = MIN(sink_get_free_size(data_sink), + source_get_data_available(data_src)); - /* acquire all sink and source buffers, get handlers to sink/source API */ - list_for_item(blist, &dev->bsink_list) { - struct comp_buffer *sink_buffer; + err = source_to_sink_copy(data_src, data_sink, true, to_copy); + if (err) + return err; - sink_buffer = container_of(blist, struct comp_buffer, source_list); - sinks_buffers_c[num_of_sinks] = buffer_acquire(sink_buffer); - audio_sink[num_of_sinks] = - audio_stream_get_sink(&sinks_buffers_c[num_of_sinks]->stream); - sink_reset_num_of_processed_bytes(audio_sink[num_of_sinks]); - num_of_sinks++; + dp_queue = dp_queue_get_next_item(dp_queue); } - list_for_item(blist, &dev->bsource_list) { - struct comp_buffer *source_buffer; + dp_queue = dp_queue_get_first_item(&mod->dp_queue_dp_to_ll_list); + list_for_item(blist, &dev->bsink_list) { + /* output - we need to copy data from dp_queue (as source) + * to audio_stream (as sink) + */ + assert(dp_queue); + struct comp_buffer *buffer = + container_of(blist, struct comp_buffer, source_list); + struct sof_sink *data_sink = audio_stream_get_sink(&buffer->stream); + struct sof_source *data_src = dp_queue_get_source(dp_queue); + uint32_t to_copy = MIN(sink_get_free_size(data_sink), + source_get_data_available(data_src)); - source_buffer = container_of(blist, struct comp_buffer, sink_list); - source_buffers_c[num_of_sources] = buffer_acquire(source_buffer); - audio_src[num_of_sources] = - audio_stream_get_source(&source_buffers_c[num_of_sources]->stream); - source_reset_num_of_processed_bytes(audio_src[num_of_sources]); - num_of_sources++; + err = source_to_sink_copy(data_src, data_sink, true, to_copy); + if (err) + return err; + + dp_queue = dp_queue_get_next_item(dp_queue); } + return 0; +} +#else +static inline int module_adapter_copy_dp_queues(struct comp_dev *dev) +{ + return -ENOTSUP; +} +#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ + +static int module_adapter_sink_source_copy(struct comp_dev *dev) +{ + struct processing_module *mod = comp_get_drvdata(dev); + int ret; + int i = 0; + + comp_dbg(dev, "module_adapter_sink_source_copy(): start"); + + /* reset number of processed bytes */ + for (i = 0; i < mod->num_of_sources; i++) + source_reset_num_of_processed_bytes(mod->sources[i]); - ret = module_process_sink_src(mod, audio_src, num_of_sources, audio_sink, num_of_sinks); + for (i = 0; i < mod->num_of_sinks; i++) + sink_reset_num_of_processed_bytes(mod->sinks[i]); + + ret = module_process_sink_src(mod, mod->sources, mod->num_of_sources, + mod->sinks, mod->num_of_sinks); if (ret != -ENOSPC && ret != -ENODATA && ret) { comp_err(dev, "module_adapter_sink_source_copy() process failed with error: %x", ret); } - /* release all source buffers in reverse order */ - for (i = num_of_sources - 1; i >= 0; i--) { - mod->total_data_consumed += source_get_num_of_processed_bytes(audio_src[i]); - buffer_release(source_buffers_c[i]); - } + /* count number of processed data. To be removed in pipeline 2.0 */ + for (i = 0; i < mod->num_of_sources; i++) + mod->total_data_consumed += source_get_num_of_processed_bytes(mod->sources[i]); - /* release all sink buffers in reverse order */ - for (i = num_of_sinks - 1; i >= 0 ; i--) { - mod->total_data_produced += sink_get_num_of_processed_bytes(audio_sink[i]); - buffer_release(sinks_buffers_c[i]); - } + for (i = 0; i < mod->num_of_sinks; i++) + mod->total_data_produced += sink_get_num_of_processed_bytes(mod->sinks[i]); comp_dbg(dev, "module_adapter_sink_source_copy(): done"); @@ -1074,7 +1136,6 @@ static int module_adapter_raw_data_type_copy(struct comp_dev *dev) struct processing_module *mod = comp_get_drvdata(dev); struct module_data *md = &mod->priv; struct comp_buffer *source, *sink; - struct comp_buffer __sparse_cache *sink_c = NULL; struct list_item *blist; size_t size = MAX(mod->deep_buff_bytes, mod->period_bytes); uint32_t min_free_frames = UINT_MAX; @@ -1085,45 +1146,38 @@ static int module_adapter_raw_data_type_copy(struct comp_dev *dev) list_for_item(blist, &mod->sink_buffer_list) { sink = container_of(blist, struct comp_buffer, sink_list); - sink_c = buffer_acquire(sink); min_free_frames = MIN(min_free_frames, - audio_stream_get_free_frames(&sink_c->stream)); - buffer_release(sink_c); + audio_stream_get_free_frames(&sink->stream)); } /* copy source samples into input buffer */ list_for_item(blist, &dev->bsource_list) { - struct comp_buffer __sparse_cache *src_c; uint32_t bytes_to_process; int frames, source_frame_bytes; source = container_of(blist, struct comp_buffer, sink_list); - src_c = buffer_acquire(source); /* check if the source dev is in the same state as the dev */ - if (!src_c->source || src_c->source->state != dev->state) { - buffer_release(src_c); + if (!source->source || source->source->state != dev->state) continue; - } frames = MIN(min_free_frames, - audio_stream_get_avail_frames(&src_c->stream)); - source_frame_bytes = audio_stream_frame_bytes(&src_c->stream); + audio_stream_get_avail_frames(&source->stream)); + source_frame_bytes = audio_stream_frame_bytes(&source->stream); bytes_to_process = MIN(frames * source_frame_bytes, md->mpd.in_buff_size); - buffer_stream_invalidate(src_c, bytes_to_process); + buffer_stream_invalidate(source, bytes_to_process); mod->input_buffers[i].size = bytes_to_process; mod->input_buffers[i].consumed = 0; - ca_copy_from_source_to_module(&src_c->stream, mod->input_buffers[i].data, + ca_copy_from_source_to_module(&source->stream, mod->input_buffers[i].data, md->mpd.in_buff_size, bytes_to_process); - buffer_release(src_c); i++; } - ret = module_process_legacy(mod, mod->input_buffers, mod->num_input_buffers, - mod->output_buffers, mod->num_output_buffers); + ret = module_process_legacy(mod, mod->input_buffers, mod->num_of_sources, + mod->output_buffers, mod->num_of_sinks); if (ret) { if (ret != -ENOSPC && ret != -ENODATA) { comp_err(dev, @@ -1138,13 +1192,10 @@ static int module_adapter_raw_data_type_copy(struct comp_dev *dev) i = 0; /* consume from all input buffers */ list_for_item(blist, &dev->bsource_list) { - struct comp_buffer __sparse_cache *src_c; source = container_of(blist, struct comp_buffer, sink_list); - src_c = buffer_acquire(source); - comp_update_buffer_consume(src_c, mod->input_buffers[i].consumed); - buffer_release(src_c); + comp_update_buffer_consume(source, mod->input_buffers[i].consumed); bzero((__sparse_force void *)mod->input_buffers[i].data, size); mod->input_buffers[i].size = 0; @@ -1162,10 +1213,10 @@ static int module_adapter_raw_data_type_copy(struct comp_dev *dev) return 0; out: - for (i = 0; i < mod->num_output_buffers; i++) + for (i = 0; i < mod->num_of_sinks; i++) mod->output_buffers[i].size = 0; - for (i = 0; i < mod->num_input_buffers; i++) { + for (i = 0; i < mod->num_of_sources; i++) { bzero((__sparse_force void *)mod->input_buffers[i].data, size); mod->input_buffers[i].size = 0; mod->input_buffers[i].consumed = 0; @@ -1186,8 +1237,13 @@ int module_adapter_copy(struct comp_dev *dev) if (IS_PROCESSING_MODE_RAW_DATA(mod)) return module_adapter_raw_data_type_copy(dev); - if (IS_PROCESSING_MODE_SINK_SOURCE(mod)) - return module_adapter_sink_source_copy(dev); + if (IS_PROCESSING_MODE_SINK_SOURCE(mod)) { + if (mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) + return module_adapter_copy_dp_queues(dev); + else + return module_adapter_sink_source_copy(dev); + + } comp_err(dev, "module_adapter_copy(): unknown processing_data_type"); return -EINVAL; @@ -1316,34 +1372,6 @@ int module_adapter_cmd(struct comp_dev *dev, int cmd, void *data, int max_data_s return ret; } -#if CONFIG_IPC_MAJOR_3 -static int module_source_status_count(struct comp_dev *dev, uint32_t status) -{ - struct list_item *blist; - int count = 0; - - /* count source with state == status */ - list_for_item(blist, &dev->bsource_list) { - /* - * FIXME: this is racy, state can be changed by another core. - * This is implicitly protected by serialised IPCs. Even when - * IPCs are processed in the pipeline thread, the next IPC will - * not be sent until the thread has processed and replied to the - * current one. - */ - struct comp_buffer *source = container_of(blist, struct comp_buffer, - sink_list); - struct comp_buffer __sparse_cache *source_c = buffer_acquire(source); - - if (source_c->source && source_c->source->state == status) - count++; - buffer_release(source_c); - } - - return count; -} -#endif - int module_adapter_trigger(struct comp_dev *dev, int cmd) { struct processing_module *mod = comp_get_drvdata(dev); @@ -1366,28 +1394,7 @@ int module_adapter_trigger(struct comp_dev *dev, int cmd) return PPL_STATUS_PATH_STOP; } -#if CONFIG_IPC_MAJOR_3 - if (mod->num_input_buffers > 1) { - bool sources_active; - int ret; - - sources_active = module_source_status_count(dev, COMP_STATE_ACTIVE) || - module_source_status_count(dev, COMP_STATE_PAUSED); - - /* don't stop/start module if one of the sources is active/paused */ - if ((cmd == COMP_TRIGGER_STOP || cmd == COMP_TRIGGER_PRE_START) && sources_active) { - dev->state = COMP_STATE_ACTIVE; - return PPL_STATUS_PATH_STOP; - } - - ret = comp_set_state(dev, cmd); - if (ret == COMP_STATUS_STATE_ALREADY_SET) - return PPL_STATUS_PATH_STOP; - - return ret; - } -#endif - return comp_set_state(dev, cmd); + return module_adapter_set_state(mod, dev, cmd); } int module_adapter_reset(struct comp_dev *dev) @@ -1406,16 +1413,50 @@ int module_adapter_reset(struct comp_dev *dev) } if (IS_PROCESSING_MODE_RAW_DATA(mod)) { - for (i = 0; i < mod->num_output_buffers; i++) + for (i = 0; i < mod->num_of_sinks; i++) rfree((__sparse_force void *)mod->output_buffers[i].data); - for (i = 0; i < mod->num_input_buffers; i++) + for (i = 0; i < mod->num_of_sources; i++) rfree((__sparse_force void *)mod->input_buffers[i].data); } - rfree(mod->output_buffers); - rfree(mod->input_buffers); - mod->num_input_buffers = 0; - mod->num_output_buffers = 0; + if (IS_PROCESSING_MODE_RAW_DATA(mod) || IS_PROCESSING_MODE_AUDIO_STREAM(mod)) { + rfree(mod->output_buffers); + rfree(mod->input_buffers); + + mod->num_of_sources = 0; + mod->num_of_sinks = 0; + } +#if CONFIG_ZEPHYR_DP_SCHEDULER + if (IS_PROCESSING_MODE_SINK_SOURCE(mod) && + mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) { + /* for DP processing - free DP Queues */ + struct list_item *dp_queue_list_item; + struct list_item *tmp; + + list_for_item_safe(dp_queue_list_item, tmp, &mod->dp_queue_dp_to_ll_list) { + struct dp_queue *dp_queue = + container_of(dp_queue_list_item, struct dp_queue, list); + + /* dp free will also remove the queue from a list */ + dp_queue_free(dp_queue); + } + list_for_item_safe(dp_queue_list_item, tmp, &mod->dp_queue_ll_to_dp_list) { + struct dp_queue *dp_queue = + container_of(dp_queue_list_item, struct dp_queue, list); + + dp_queue_free(dp_queue); + } + } +#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ + if (IS_PROCESSING_MODE_SINK_SOURCE(mod)) { + /* for both LL and DP processing */ + for (i = 0; i < mod->num_of_sources; i++) + mod->sources[i] = NULL; + for (i = 0; i < mod->num_of_sinks; i++) + mod->sinks[i] = NULL; + mod->num_of_sinks = 0; + mod->num_of_sources = 0; + } mod->total_data_consumed = 0; mod->total_data_produced = 0; @@ -1423,10 +1464,7 @@ int module_adapter_reset(struct comp_dev *dev) list_for_item(blist, &mod->sink_buffer_list) { struct comp_buffer *buffer = container_of(blist, struct comp_buffer, sink_list); - struct comp_buffer __sparse_cache *buffer_c = buffer_acquire(buffer); - - buffer_zero(buffer_c); - buffer_release(buffer_c); + buffer_zero(buffer); } rfree(mod->stream_params); @@ -1460,7 +1498,6 @@ void module_adapter_free(struct comp_dev *dev) buffer_free(buffer); } - coherent_free_thread(mod->source_info, c); rfree(mod); rfree(dev); } @@ -1573,7 +1610,11 @@ int module_adapter_ts_stop_op(struct comp_dev *dev) * 0 - success * value < 0 - failure. */ +#if CONFIG_ZEPHYR_NATIVE_DRIVERS +int module_adapter_ts_get_op(struct comp_dev *dev, struct dai_ts_data *tsd) +#else int module_adapter_ts_get_op(struct comp_dev *dev, struct timestamp_data *tsd) +#endif { struct processing_module *mod = comp_get_drvdata(dev); struct module_data *md = &mod->priv; @@ -1584,253 +1625,3 @@ int module_adapter_ts_get_op(struct comp_dev *dev, struct timestamp_data *tsd) return -EOPNOTSUPP; } -#if CONFIG_IPC_MAJOR_4 -int module_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, - bool last_block, uint32_t data_offset_size, const char *data) -{ - struct processing_module *mod = comp_get_drvdata(dev); - struct module_data *md = &mod->priv; - enum module_cfg_fragment_position pos; - size_t fragment_size; - - /* set fragment position */ - pos = first_last_block_to_frag_pos(first_block, last_block); - - switch (pos) { - case MODULE_CFG_FRAGMENT_SINGLE: - fragment_size = data_offset_size; - break; - case MODULE_CFG_FRAGMENT_MIDDLE: - fragment_size = MAILBOX_DSPBOX_SIZE; - break; - case MODULE_CFG_FRAGMENT_FIRST: - md->new_cfg_size = data_offset_size; - fragment_size = MAILBOX_DSPBOX_SIZE; - break; - case MODULE_CFG_FRAGMENT_LAST: - fragment_size = md->new_cfg_size - data_offset_size; - break; - default: - comp_err(dev, "module_set_large_config(): invalid fragment position"); - return -EINVAL; - } - - if (md->ops->set_configuration) - return md->ops->set_configuration(mod, param_id, pos, data_offset_size, - (const uint8_t *)data, - fragment_size, NULL, 0); - return 0; -} - -int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, - bool last_block, uint32_t *data_offset_size, char *data) -{ - struct processing_module *mod = comp_get_drvdata(dev); - struct module_data *md = &mod->priv; - size_t fragment_size; - - /* set fragment size */ - if (first_block) { - if (last_block) - fragment_size = md->cfg.size; - else - fragment_size = SOF_IPC_MSG_MAX_SIZE; - } else { - if (!last_block) - fragment_size = SOF_IPC_MSG_MAX_SIZE; - else - fragment_size = md->cfg.size - *data_offset_size; - } - - if (md->ops->get_configuration) - return md->ops->get_configuration(mod, param_id, data_offset_size, - (uint8_t *)data, fragment_size); - return 0; -} - -int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *value) -{ - struct processing_module *mod = comp_get_drvdata(dev); - - switch (type) { - case COMP_ATTR_BASE_CONFIG: - memcpy_s(value, sizeof(struct ipc4_base_module_cfg), - &mod->priv.cfg.base_cfg, sizeof(mod->priv.cfg.base_cfg)); - break; - default: - return -EINVAL; - } - - return 0; -} - -static bool module_adapter_multi_sink_source_check(struct comp_dev *dev) -{ - struct processing_module *mod = comp_get_drvdata(dev); - struct list_item *blist; - int num_sources = 0; - int num_sinks = 0; - - list_for_item(blist, &dev->bsource_list) - num_sources++; - - list_for_item(blist, &dev->bsink_list) - num_sinks++; - - comp_dbg(dev, "num_sources=%d num_sinks=%d", num_sources, num_sinks); - - if (num_sources != 1 || num_sinks != 1) - return true; - - /* re-assign the source/sink modules */ - mod->sink_comp_buffer = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - mod->source_comp_buffer = list_first_item(&dev->bsource_list, - struct comp_buffer, sink_list); - - return false; -} - -int module_adapter_bind(struct comp_dev *dev, void *data) -{ - struct module_source_info __sparse_cache *mod_source_info; - struct processing_module *mod = comp_get_drvdata(dev); - struct ipc4_module_bind_unbind *bu; - struct comp_dev *source_dev; - int source_index; - int src_id; - int ret; - - ret = module_bind(mod, data); - if (ret < 0) - return ret; - - bu = (struct ipc4_module_bind_unbind *)data; - src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id); - - mod->stream_copy_single_to_single = !module_adapter_multi_sink_source_check(dev); - - /* nothing to do if this module is the source during bind */ - if (dev->ipc_config.id == src_id) - return 0; - - source_dev = ipc4_get_comp_dev(src_id); - if (!source_dev) { - comp_err(dev, "module_adapter_bind: no source with ID %d found", src_id); - return -EINVAL; - } - - mod_source_info = module_source_info_acquire(mod->source_info); - - source_index = find_module_source_index(mod_source_info, source_dev); - /* - * this should never happen as source_info should have been already cleared in - * module_adapter_unbind() - */ - if (source_index >= 0) - mod_source_info->sources[source_index] = NULL; - - /* find an empty slot in the source_info array */ - source_index = find_module_source_index(mod_source_info, NULL); - if (source_index < 0) { - /* no free slot in module source_info array */ - comp_err(dev, "Too many inputs!"); - module_source_info_release(mod_source_info); - return -ENOMEM; - } - - /* set the source dev pointer */ - mod_source_info->sources[source_index] = source_dev; - - module_source_info_release(mod_source_info); - - return 0; -} - -int module_adapter_unbind(struct comp_dev *dev, void *data) -{ - struct module_source_info __sparse_cache *mod_source_info; - struct processing_module *mod = comp_get_drvdata(dev); - struct ipc4_module_bind_unbind *bu; - struct comp_dev *source_dev; - int source_index; - int src_id; - int ret; - - ret = module_unbind(mod, data); - if (ret < 0) - return ret; - - bu = (struct ipc4_module_bind_unbind *)data; - src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id); - - mod->stream_copy_single_to_single = !module_adapter_multi_sink_source_check(dev); - - /* nothing to do if this module is the source during unbind */ - if (dev->ipc_config.id == src_id) - return 0; - - source_dev = ipc4_get_comp_dev(src_id); - if (!source_dev) { - comp_err(dev, "module_adapter_bind: no source with ID %d found", src_id); - return -EINVAL; - } - - mod_source_info = module_source_info_acquire(mod->source_info); - - /* find the index of the source in the sources array and clear it */ - source_index = find_module_source_index(mod_source_info, source_dev); - if (source_index >= 0) - mod_source_info->sources[source_index] = NULL; - - module_source_info_release(mod_source_info); - - return 0; -} - -uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, - uint32_t stream_no, bool input) -{ - struct processing_module *mod = comp_get_drvdata(dev); - struct module_data *md = &mod->priv; - - if (md->ops->endpoint_ops && md->ops->endpoint_ops->get_total_data_processed) - return md->ops->endpoint_ops->get_total_data_processed(dev, stream_no, input); - - if (input) - return mod->total_data_produced; - else - return mod->total_data_consumed; -} -#else -int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *value) -{ - return -EINVAL; -} -int module_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, - bool last_block, uint32_t data_offset, const char *data) -{ - return 0; -} - -int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, - bool last_block, uint32_t *data_offset, char *data) -{ - return 0; -} - -int module_adapter_bind(struct comp_dev *dev, void *data) -{ - return 0; -} - -int module_adapter_unbind(struct comp_dev *dev, void *data) -{ - return 0; -} - -uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, - uint32_t stream_no, bool input) -{ - return 0; -} -#endif diff --git a/src/audio/module_adapter/module_adapter_ipc3.c b/src/audio/module_adapter/module_adapter_ipc3.c new file mode 100644 index 000000000000..0f9a31be4139 --- /dev/null +++ b/src/audio/module_adapter/module_adapter_ipc3.c @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. +// +// Author: Baofeng Tian + +/** + * \file + * \brief Module Adapter ipc3: module adapter ipc3 specific code + * \author Baofeng Tian + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(module_adapter, CONFIG_SOF_LOG_LEVEL); + +/* + * \module adapter data initialize. + * \param[in] dev - device. + * \param[in] config - component ipc descriptor pointer. + * \param[in] dst - module adapter config data. + * \param[in] spec - passdowned data from driver. + * + * \return: 0 - no error; < 0, error happened. + */ +int module_adapter_init_data(struct comp_dev *dev, + struct module_config *dst, + const struct comp_ipc_config *config, + const void *spec) +{ + int ret; + + const unsigned char *data; + uint32_t size; + + switch (config->type) { + case SOF_COMP_VOLUME: + { + const struct ipc_config_volume *ipc_volume = spec; + + size = sizeof(*ipc_volume); + data = spec; + break; + } + case SOF_COMP_SRC: + { + const struct ipc_config_src *ipc_src = spec; + + size = sizeof(*ipc_src); + data = spec; + break; + } + default: + { + const struct ipc_config_process *ipc_module_adapter = spec; + + size = ipc_module_adapter->size; + data = ipc_module_adapter->data; + break; + } + } + + /* Copy initial config */ + if (size) { + ret = module_load_config(dev, data, size); + if (ret < 0) { + comp_err(dev, "module_adapter_new() error %d: config loading has failed.", + ret); + return ret; + } + dst->init_data = dst->data; + } + + return 0; +} + +void module_adapter_reset_data(struct module_config *dst) +{ +} + +void module_adapter_check_data(struct processing_module *mod, struct comp_dev *dev, + struct comp_buffer *sink) +{ + /* Check if audio stream client has only one source and one sink buffer to use a + * simplified copy function. + */ + if (IS_PROCESSING_MODE_AUDIO_STREAM(mod) && mod->num_of_sources == 1 && + mod->num_of_sinks == 1) { + mod->source_comp_buffer = list_first_item(&dev->bsource_list, + struct comp_buffer, sink_list); + mod->sink_comp_buffer = sink; + mod->stream_copy_single_to_single = true; + } +} + +void module_adapter_set_params(struct processing_module *mod, struct sof_ipc_stream_params *params) +{ +} + +static int module_source_status_count(struct comp_dev *dev, uint32_t status) +{ + struct list_item *blist; + int count = 0; + + /* count source with state == status */ + list_for_item(blist, &dev->bsource_list) { + /* + * FIXME: this is racy, state can be changed by another core. + * This is implicitly protected by serialised IPCs. Even when + * IPCs are processed in the pipeline thread, the next IPC will + * not be sent until the thread has processed and replied to the + * current one. + */ + struct comp_buffer *source = container_of(blist, struct comp_buffer, + sink_list); + + if (source->source && source->source->state == status) + count++; + } + + return count; +} + +int module_adapter_set_state(struct processing_module *mod, struct comp_dev *dev, + int cmd) +{ + if (mod->num_of_sources > 1) { + bool sources_active; + int ret; + + sources_active = module_source_status_count(dev, COMP_STATE_ACTIVE) || + module_source_status_count(dev, COMP_STATE_PAUSED); + + /* don't stop/start module if one of the sources is active/paused */ + if ((cmd == COMP_TRIGGER_STOP || cmd == COMP_TRIGGER_PRE_START) && sources_active) { + dev->state = COMP_STATE_ACTIVE; + return PPL_STATUS_PATH_STOP; + } + + ret = comp_set_state(dev, cmd); + if (ret == COMP_STATUS_STATE_ALREADY_SET) + return PPL_STATUS_PATH_STOP; + + return ret; + } + + return comp_set_state(dev, cmd); +} + diff --git a/src/audio/module_adapter/module_adapter_ipc4.c b/src/audio/module_adapter/module_adapter_ipc4.c new file mode 100644 index 000000000000..65ca8e806e3f --- /dev/null +++ b/src/audio/module_adapter/module_adapter_ipc4.c @@ -0,0 +1,226 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. +// +// Author: Baofeng Tian + +/** + * \file + * \brief Module Adapter ipc4: module adapter ipc4 specific code + * \author Baofeng Tian + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(module_adapter, CONFIG_SOF_LOG_LEVEL); + +/* + * \module adapter data initialize. + * \param[in] dev - device. + * \param[in] config - component ipc descriptor pointer. + * \param[in] dst - module adapter config data. + * \param[in] spec - passdowned data from driver. + * + * \return: 0 - no error; < 0, error happened. + */ +int module_adapter_init_data(struct comp_dev *dev, + struct module_config *dst, + const struct comp_ipc_config *config, + const void *spec) +{ + if (dev->drv->type == SOF_COMP_MODULE_ADAPTER) { + const struct ipc_config_process *ipc_module_adapter = spec; + + dst->init_data = ipc_module_adapter->data; + dst->size = ipc_module_adapter->size; + dst->avail = true; + + memcpy_s(&dst->base_cfg, sizeof(dst->base_cfg), ipc_module_adapter->data, + sizeof(dst->base_cfg)); + } else { + dst->init_data = spec; + } + + return 0; +} + +void module_adapter_reset_data(struct module_config *dst) +{ + dst->init_data = NULL; +} + +void module_adapter_check_data(struct processing_module *mod, struct comp_dev *dev, + struct comp_buffer *sink) +{ +} + +void module_adapter_set_params(struct processing_module *mod, struct sof_ipc_stream_params *params) +{ + ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); + ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, mod->stream_params); +} + +int module_adapter_set_state(struct processing_module *mod, struct comp_dev *dev, + int cmd) +{ + return comp_set_state(dev, cmd); +} + +int module_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, + bool last_block, uint32_t data_offset_size, const char *data) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct module_data *md = &mod->priv; + enum module_cfg_fragment_position pos; + size_t fragment_size; + + /* set fragment position */ + pos = first_last_block_to_frag_pos(first_block, last_block); + + switch (pos) { + case MODULE_CFG_FRAGMENT_SINGLE: + fragment_size = data_offset_size; + break; + case MODULE_CFG_FRAGMENT_MIDDLE: + fragment_size = MAILBOX_DSPBOX_SIZE; + break; + case MODULE_CFG_FRAGMENT_FIRST: + md->new_cfg_size = data_offset_size; + fragment_size = MAILBOX_DSPBOX_SIZE; + break; + case MODULE_CFG_FRAGMENT_LAST: + fragment_size = md->new_cfg_size - data_offset_size; + break; + default: + comp_err(dev, "module_set_large_config(): invalid fragment position"); + return -EINVAL; + } + + if (md->ops->set_configuration) + return md->ops->set_configuration(mod, param_id, pos, data_offset_size, + (const uint8_t *)data, + fragment_size, NULL, 0); + return 0; +} + +int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, + bool last_block, uint32_t *data_offset_size, char *data) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct module_data *md = &mod->priv; + size_t fragment_size; + + /* set fragment size */ + if (first_block) { + if (last_block) + fragment_size = md->cfg.size; + else + fragment_size = SOF_IPC_MSG_MAX_SIZE; + } else { + if (!last_block) + fragment_size = SOF_IPC_MSG_MAX_SIZE; + else + fragment_size = md->cfg.size - *data_offset_size; + } + + if (md->ops->get_configuration) + return md->ops->get_configuration(mod, param_id, data_offset_size, + (uint8_t *)data, fragment_size); + return 0; +} + +int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *value) +{ + struct processing_module *mod = comp_get_drvdata(dev); + + switch (type) { + case COMP_ATTR_BASE_CONFIG: + memcpy_s(value, sizeof(struct ipc4_base_module_cfg), + &mod->priv.cfg.base_cfg, sizeof(mod->priv.cfg.base_cfg)); + break; + default: + return -EINVAL; + } + + return 0; +} + +static bool module_adapter_multi_sink_source_check(struct comp_dev *dev) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct list_item *blist; + int num_sources = 0; + int num_sinks = 0; + + list_for_item(blist, &dev->bsource_list) + num_sources++; + + list_for_item(blist, &dev->bsink_list) + num_sinks++; + + comp_dbg(dev, "num_sources=%d num_sinks=%d", num_sources, num_sinks); + + if (num_sources != 1 || num_sinks != 1) + return true; + + /* re-assign the source/sink modules */ + mod->sink_comp_buffer = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + mod->source_comp_buffer = list_first_item(&dev->bsource_list, + struct comp_buffer, sink_list); + + return false; +} + +int module_adapter_bind(struct comp_dev *dev, void *data) +{ + struct processing_module *mod = comp_get_drvdata(dev); + int ret; + + ret = module_bind(mod, data); + if (ret < 0) + return ret; + + mod->stream_copy_single_to_single = !module_adapter_multi_sink_source_check(dev); + + return 0; +} + +int module_adapter_unbind(struct comp_dev *dev, void *data) +{ + struct processing_module *mod = comp_get_drvdata(dev); + int ret; + + ret = module_unbind(mod, data); + if (ret < 0) + return ret; + + mod->stream_copy_single_to_single = !module_adapter_multi_sink_source_check(dev); + + return 0; +} + +uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, + uint32_t stream_no, bool input) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct module_data *md = &mod->priv; + + if (md->ops->endpoint_ops && md->ops->endpoint_ops->get_total_data_processed) + return md->ops->endpoint_ops->get_total_data_processed(dev, stream_no, input); + + if (input) + return mod->total_data_produced; + else + return mod->total_data_consumed; +} + diff --git a/src/audio/multiband_drc/multiband_drc.c b/src/audio/multiband_drc/multiband_drc.c index a23a6eebc830..fe1c11f3cdab 100644 --- a/src/audio/multiband_drc/multiband_drc.c +++ b/src/audio/multiband_drc/multiband_drc.c @@ -251,11 +251,10 @@ static int multiband_drc_init(struct processing_module *mod) cd->multiband_drc_func = NULL; cd->crossover_split = NULL; #if CONFIG_IPC_MAJOR_4 - /* Note: Currently there is no ALSA switch control in IPC4 to control - * processing on/off. This workaround can be removed after is available. - * Binary control for configuration blob can be used instead. There is - * no processing bypass control in the blob but all processing can be - * switched to neutral with supported min. 2-band mode. + /* Initialize to enabled is a workaround for IPC4 kernel version 6.6 and + * before where the processing is never enabled via switch control. New + * kernel sends the IPC4 switch control and sets this to desired state + * before prepare. */ cd->process_enabled = true; #else @@ -321,18 +320,42 @@ static int multiband_drc_cmd_set_value(struct processing_module *mod, } #endif -static int multiband_drc_set_config(struct processing_module *mod, uint32_t config_id, +static int multiband_drc_set_config(struct processing_module *mod, uint32_t param_id, enum module_cfg_fragment_position pos, uint32_t data_offset_size, const uint8_t *fragment, size_t fragment_size, uint8_t *response, size_t response_size) { struct multiband_drc_comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; - comp_dbg(mod->dev, "multiband_drc_set_config()"); + comp_dbg(dev, "multiband_drc_set_config()"); -#if CONFIG_IPC_MAJOR_3 - /* Other control types are possible only with IPC3 */ +#if CONFIG_IPC_MAJOR_4 + struct sof_ipc4_control_msg_payload *ctl = (struct sof_ipc4_control_msg_payload *)fragment; + + switch (param_id) { + case SOF_IPC4_SWITCH_CONTROL_PARAM_ID: + comp_dbg(dev, "SOF_IPC4_SWITCH_CONTROL_PARAM_ID id = %d, num_elems = %d", + ctl->id, ctl->num_elems); + + if (ctl->id == 0 && ctl->num_elems == 1) { + cd->process_enabled = ctl->chanv[0].value; + comp_info(dev, "process_enabled = %d", cd->process_enabled); + } else { + comp_err(dev, "Illegal control id = %d, num_elems = %d", + ctl->id, ctl->num_elems); + return -EINVAL; + } + + return 0; + + case SOF_IPC4_ENUM_CONTROL_PARAM_ID: + comp_err(dev, "multiband_drc_set_config(), illegal control."); + return -EINVAL; + } + +#elif CONFIG_IPC_MAJOR_3 struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; if (cdata->cmd != SOF_CTRL_CMD_BINARY) @@ -388,8 +411,8 @@ static int multiband_drc_get_config(struct processing_module *mod, return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); } -static void multiband_drc_set_alignment(struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink) +static void multiband_drc_set_alignment(struct audio_stream *source, + struct audio_stream *sink) { /* Currently no optimizations those would use wider loads and stores */ audio_stream_init_alignment_constants(1, 1, source); @@ -403,8 +426,8 @@ static int multiband_drc_process(struct processing_module *mod, { struct multiband_drc_comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - struct audio_stream __sparse_cache *source = input_buffers[0].data; - struct audio_stream __sparse_cache *sink = output_buffers[0].data; + struct audio_stream *source = input_buffers[0].data; + struct audio_stream *sink = output_buffers[0].data; int frames = input_buffers[0].size; int ret; @@ -435,7 +458,6 @@ static int multiband_drc_params(struct processing_module *mod) struct sof_ipc_stream_params comp_params; struct comp_dev *dev = mod->dev; struct comp_buffer *sinkb; - struct comp_buffer __sparse_cache *sink_c; enum sof_ipc_frame valid_fmt, frame_fmt; int i, ret; @@ -458,21 +480,19 @@ static int multiband_drc_params(struct processing_module *mod) component_set_nearest_period_frames(dev, comp_params.rate); sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sinkb); - ret = buffer_set_params(sink_c, &comp_params, true); - buffer_release(sink_c); + ret = buffer_set_params(sinkb, &comp_params, true); + return ret; } #endif /* CONFIG_IPC_MAJOR_4 */ static int multiband_drc_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct multiband_drc_comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; int channels; int rate; int ret = 0; @@ -489,17 +509,12 @@ static int multiband_drc_prepare(struct processing_module *mod, sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - multiband_drc_set_alignment(&source_c->stream, &sink_c->stream); + multiband_drc_set_alignment(&sourceb->stream, &sinkb->stream); /* get source data format */ - cd->source_format = audio_stream_get_frm_fmt(&source_c->stream); - channels = audio_stream_get_channels(&source_c->stream); - rate = audio_stream_get_rate(&source_c->stream); - - buffer_release(sink_c); - buffer_release(source_c); + cd->source_format = audio_stream_get_frm_fmt(&sourceb->stream); + channels = audio_stream_get_channels(&sourceb->stream); + rate = audio_stream_get_rate(&sourceb->stream); /* Initialize DRC */ comp_dbg(dev, "multiband_drc_prepare(), source_format=%d, sink_format=%d", @@ -551,8 +566,8 @@ static int multiband_drc_reset(struct processing_module *mod) return 0; } -static struct module_interface multiband_drc_interface = { - .init = multiband_drc_init, +static const struct module_interface multiband_drc_interface = { + .init = multiband_drc_init, .prepare = multiband_drc_prepare, .process_audio_stream = multiband_drc_process, .set_configuration = multiband_drc_set_config, diff --git a/src/audio/multiband_drc/multiband_drc_generic.c b/src/audio/multiband_drc/multiband_drc_generic.c index e4d3014c9270..fff21e2653bf 100644 --- a/src/audio/multiband_drc/multiband_drc_generic.c +++ b/src/audio/multiband_drc/multiband_drc_generic.c @@ -11,8 +11,8 @@ #include static void multiband_drc_default_pass(const struct processing_module *mod, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, uint32_t frames) { audio_stream_copy(source, 0, sink, 0, audio_stream_get_channels(source) * frames); @@ -203,8 +203,8 @@ static void multiband_drc_process_deemp(struct multiband_drc_state *state, */ #if CONFIG_FORMAT_S16LE static void multiband_drc_s16_default(const struct processing_module *mod, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, uint32_t frames) { struct multiband_drc_comp_data *cd = module_get_private_data(mod); @@ -270,8 +270,8 @@ static void multiband_drc_s16_default(const struct processing_module *mod, #if CONFIG_FORMAT_S24LE static void multiband_drc_s24_default(const struct processing_module *mod, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, uint32_t frames) { struct multiband_drc_comp_data *cd = module_get_private_data(mod); @@ -337,8 +337,8 @@ static void multiband_drc_s24_default(const struct processing_module *mod, #if CONFIG_FORMAT_S32LE static void multiband_drc_s32_default(const struct processing_module *mod, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, uint32_t frames) { struct multiband_drc_comp_data *cd = module_get_private_data(mod); diff --git a/src/audio/mux/mux.c b/src/audio/mux/mux.c index 3223f515438c..92d278a22186 100644 --- a/src/audio/mux/mux.c +++ b/src/audio/mux/mux.c @@ -274,7 +274,6 @@ static void set_mux_params(struct processing_module *mod) struct comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; struct comp_buffer *sink, *source; - struct comp_buffer __sparse_cache *sink_c, *source_c; struct list_item *source_list; int j; const uint32_t byte_align = 1; @@ -298,15 +297,13 @@ static void set_mux_params(struct processing_module *mod) /* update sink format */ if (!list_is_empty(&dev->bsink_list)) { sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); audio_stream_init_alignment_constants(byte_align, frame_align_req, - &sink_c->stream); + &sink->stream); - if (!sink_c->hw_params_configured) { - ipc4_update_buffer_format(sink_c, &cd->md.output_format); - params->frame_fmt = audio_stream_get_frm_fmt(&sink_c->stream); + if (!sink->hw_params_configured) { + ipc4_update_buffer_format(sink, &cd->md.output_format); + params->frame_fmt = audio_stream_get_frm_fmt(&sink->stream); } - buffer_release(sink_c); } /* update each source format */ @@ -316,18 +313,16 @@ static void set_mux_params(struct processing_module *mod) list_for_item(source_list, &dev->bsource_list) { source = container_of(source_list, struct comp_buffer, sink_list); - source_c = buffer_acquire(source); audio_stream_init_alignment_constants(byte_align, frame_align_req, - &source_c->stream); - j = source_c->id; - cd->config.streams[j].pipeline_id = source_c->pipeline_id; + &source->stream); + j = source->id; + cd->config.streams[j].pipeline_id = source->pipeline_id; if (j == BASE_CFG_QUEUED_ID) audio_fmt = &cd->md.base_cfg.audio_fmt; else audio_fmt = &cd->md.reference_format; - ipc4_update_buffer_format(source_c, audio_fmt); - buffer_release(source_c); + ipc4_update_buffer_format(source, audio_fmt); } } @@ -375,10 +370,10 @@ static struct mux_look_up *get_lookup_table(struct comp_dev *dev, struct comp_da } static void mux_prepare_active_look_up(struct comp_data *cd, - struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache **sources) + struct audio_stream *sink, + const struct audio_stream **sources) { - const struct audio_stream __sparse_cache *source; + const struct audio_stream *source; int elem; int active_elem = 0; @@ -400,8 +395,8 @@ static void mux_prepare_active_look_up(struct comp_data *cd, } static void demux_prepare_active_look_up(struct comp_data *cd, - struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *source, + struct audio_stream *sink, + const struct audio_stream *source, struct mux_look_up *look_up) { int elem; @@ -429,8 +424,7 @@ static int demux_process(struct processing_module *mod, struct comp_dev *dev = mod->dev; struct list_item *clist; struct comp_buffer *sink; - struct comp_buffer __sparse_cache *sink_c; - struct audio_stream __sparse_cache *sinks_stream[MUX_MAX_STREAMS] = { NULL }; + struct audio_stream *sinks_stream[MUX_MAX_STREAMS] = { NULL }; struct mux_look_up *look_ups[MUX_MAX_STREAMS] = { NULL }; int frames; int sink_bytes; @@ -442,20 +436,16 @@ static int demux_process(struct processing_module *mod, /* align sink streams with their respective configurations */ list_for_item(clist, &dev->bsink_list) { sink = container_of(clist, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); - if (sink_c->sink->state == dev->state) { - i = get_stream_index(dev, cd, sink_c->pipeline_id); + if (sink->sink->state == dev->state) { + i = get_stream_index(dev, cd, sink->pipeline_id); /* return if index wrong */ if (i < 0) { - buffer_release(sink_c); return i; } - look_ups[i] = get_lookup_table(dev, cd, sink_c->pipeline_id); - sinks_stream[i] = &sink_c->stream; + look_ups[i] = get_lookup_table(dev, cd, sink->pipeline_id); + sinks_stream[i] = &sink->stream; } - - buffer_release(sink_c); } /* if there are no sinks active, then sinks[] is also empty */ @@ -487,9 +477,8 @@ static int mux_process(struct processing_module *mod, struct comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; struct comp_buffer *source; - struct comp_buffer __sparse_cache *source_c; struct list_item *clist; - const struct audio_stream __sparse_cache *sources_stream[MUX_MAX_STREAMS] = { NULL }; + const struct audio_stream *sources_stream[MUX_MAX_STREAMS] = { NULL }; int frames = 0; int sink_bytes; int source_bytes; @@ -501,23 +490,20 @@ static int mux_process(struct processing_module *mod, j = 0; list_for_item(clist, &dev->bsource_list) { source = container_of(clist, struct comp_buffer, sink_list); - source_c = buffer_acquire(source); - if (source_c->source->state == dev->state) { + if (source->source->state == dev->state) { if (frames) frames = MIN(frames, input_buffers[j].size); else frames = input_buffers[j].size; - i = get_stream_index(dev, cd, source_c->pipeline_id); + i = get_stream_index(dev, cd, source->pipeline_id); /* return if index wrong */ if (i < 0) { - buffer_release(source_c); return i; } - sources_stream[i] = &source_c->stream; + sources_stream[i] = &source->stream; } - buffer_release(source_c); j++; } @@ -536,11 +522,8 @@ static int mux_process(struct processing_module *mod, j = 0; list_for_item(clist, &dev->bsource_list) { source = container_of(clist, struct comp_buffer, sink_list); - source_c = buffer_acquire(source); - if (source_c->source->state == dev->state) + if (source->source->state == dev->state) mod->input_buffers[j].consumed = source_bytes; - - buffer_release(source_c); j++; } mod->output_buffers[0].size = sink_bytes; @@ -560,10 +543,7 @@ static int mux_reset(struct processing_module *mod) list_for_item(blist, &dev->bsource_list) { struct comp_buffer *source = container_of(blist, struct comp_buffer, sink_list); - struct comp_buffer __sparse_cache *source_c = buffer_acquire(source); - int state = source_c->source->state; - - buffer_release(source_c); + int state = source->source->state; /* only mux the sources with the same state with mux */ if (state > COMP_STATE_READY) @@ -578,16 +558,14 @@ static int mux_reset(struct processing_module *mod) } static int mux_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct comp_dev *dev = mod->dev; struct comp_data *cd = module_get_private_data(mod); struct list_item *blist; struct comp_buffer *source; struct comp_buffer *sink; - struct comp_buffer __sparse_cache *source_c; - struct comp_buffer __sparse_cache *sink_c; struct sof_mux_config *config; size_t blob_size; int state; @@ -628,10 +606,8 @@ static int mux_prepare(struct processing_module *mod, /* check each mux source state, set source align to 1 byte, 1 frame */ list_for_item(blist, &dev->bsource_list) { source = container_of(blist, struct comp_buffer, sink_list); - source_c = buffer_acquire(source); - state = source_c->source->state; - audio_stream_init_alignment_constants(1, 1, &source_c->stream); - buffer_release(source_c); + state = source->source->state; + audio_stream_init_alignment_constants(1, 1, &source->stream); /* only prepare downstream if we have no active sources */ if (state == COMP_STATE_PAUSED || state == COMP_STATE_ACTIVE) @@ -641,9 +617,7 @@ static int mux_prepare(struct processing_module *mod, /* set sink align to 1 byte, 1 frame */ list_for_item(blist, &dev->bsink_list) { sink = container_of(blist, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); - audio_stream_init_alignment_constants(1, 1, &sink_c->stream); - buffer_release(sink_c); + audio_stream_init_alignment_constants(1, 1, &sink->stream); } /* prepare downstream */ @@ -675,8 +649,8 @@ static int mux_set_config(struct processing_module *mod, uint32_t config_id, fragment, fragment_size); } -static struct module_interface mux_interface = { - .init = mux_init, +static const struct module_interface mux_interface = { + .init = mux_init, .set_configuration = mux_set_config, .get_configuration = mux_get_config, .prepare = mux_prepare, @@ -688,8 +662,8 @@ static struct module_interface mux_interface = { DECLARE_MODULE_ADAPTER(mux_interface, mux_uuid, mux_tr); SOF_MODULE_INIT(mux, sys_comp_module_mux_interface_init); -static struct module_interface demux_interface = { - .init = demux_init, +static const struct module_interface demux_interface = { + .init = demux_init, .set_configuration = mux_set_config, .get_configuration = mux_get_config, .prepare = mux_prepare, diff --git a/src/audio/mux/mux_generic.c b/src/audio/mux/mux_generic.c index dd58cedbbd6b..f2b513759f61 100644 --- a/src/audio/mux/mux_generic.c +++ b/src/audio/mux/mux_generic.c @@ -19,11 +19,11 @@ LOG_MODULE_DECLARE(muxdemux, CONFIG_SOF_LOG_LEVEL); -static void mux_check_for_wrap(struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache **sources, +static void mux_check_for_wrap(struct audio_stream *sink, + const struct audio_stream **sources, struct mux_look_up *lookup) { - const struct audio_stream __sparse_cache *source; + const struct audio_stream *source; uint32_t elem; /* check sources and destinations for wrap */ @@ -36,8 +36,8 @@ static void mux_check_for_wrap(struct audio_stream __sparse_cache *sink, } } -static void demux_check_for_wrap(struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *source, +static void demux_check_for_wrap(struct audio_stream *sink, + const struct audio_stream *source, struct mux_look_up *lookup) { uint32_t elem; @@ -53,9 +53,8 @@ static void demux_check_for_wrap(struct audio_stream __sparse_cache *sink, #if CONFIG_FORMAT_S16LE -static uint32_t demux_calc_frames_without_wrap_s16(struct audio_stream __sparse_cache *sink, - const struct audio_stream - __sparse_cache *source, +static uint32_t demux_calc_frames_without_wrap_s16(struct audio_stream *sink, + const struct audio_stream *source, struct mux_look_up *lookup) { uint32_t frames; @@ -79,12 +78,11 @@ static uint32_t demux_calc_frames_without_wrap_s16(struct audio_stream __sparse_ return min_frames; } -static uint32_t mux_calc_frames_without_wrap_s16(struct audio_stream __sparse_cache *sink, - const struct audio_stream - __sparse_cache **sources, +static uint32_t mux_calc_frames_without_wrap_s16(struct audio_stream *sink, + const struct audio_stream **sources, struct mux_look_up *lookup) { - const struct audio_stream __sparse_cache *source; + const struct audio_stream *source; uint32_t frames; uint32_t min_frames; uint32_t elem; @@ -111,11 +109,11 @@ static uint32_t mux_calc_frames_without_wrap_s16(struct audio_stream __sparse_ca return min_frames; } -static void mux_init_look_up_pointers_s16(struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache **sources, +static void mux_init_look_up_pointers_s16(struct audio_stream *sink, + const struct audio_stream **sources, struct mux_look_up *lookup) { - const struct audio_stream __sparse_cache *source; + const struct audio_stream *source; uint32_t elem; /* init pointers */ @@ -132,8 +130,8 @@ static void mux_init_look_up_pointers_s16(struct audio_stream __sparse_cache *si } } -static void demux_init_look_up_pointers_s16(struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *source, +static void demux_init_look_up_pointers_s16(struct audio_stream *sink, + const struct audio_stream *source, struct mux_look_up *lookup) { uint32_t elem; @@ -162,8 +160,8 @@ static void demux_init_look_up_pointers_s16(struct audio_stream __sparse_cache * * @param[in] frames Number of frames to process. * @param[in] lookup mux look up table. */ -static void demux_s16le(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *source, uint32_t frames, +static void demux_s16le(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream *source, uint32_t frames, struct mux_look_up *lookup) { uint32_t i; @@ -215,8 +213,8 @@ static void demux_s16le(struct comp_dev *dev, struct audio_stream __sparse_cache * @param[in] frames Number of frames to process. * @param[in] lookup mux look up table. */ -static void mux_s16le(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache **sources, uint32_t frames, +static void mux_s16le(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream **sources, uint32_t frames, struct mux_look_up *lookup) { uint32_t i; @@ -259,12 +257,11 @@ static void mux_s16le(struct comp_dev *dev, struct audio_stream __sparse_cache * #if CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE -static uint32_t mux_calc_frames_without_wrap_s32(struct audio_stream __sparse_cache *sink, - const struct audio_stream - __sparse_cache **sources, +static uint32_t mux_calc_frames_without_wrap_s32(struct audio_stream *sink, + const struct audio_stream **sources, struct mux_look_up *lookup) { - const struct audio_stream __sparse_cache *source; + const struct audio_stream *source; uint32_t frames; uint32_t min_frames; uint32_t elem; @@ -289,9 +286,8 @@ static uint32_t mux_calc_frames_without_wrap_s32(struct audio_stream __sparse_ca return min_frames; } -static uint32_t demux_calc_frames_without_wrap_s32(struct audio_stream __sparse_cache *sink, - const struct audio_stream - __sparse_cache *source, +static uint32_t demux_calc_frames_without_wrap_s32(struct audio_stream *sink, + const struct audio_stream *source, struct mux_look_up *lookup) { uint32_t frames; @@ -313,11 +309,11 @@ static uint32_t demux_calc_frames_without_wrap_s32(struct audio_stream __sparse_ return min_frames; } -static void mux_init_look_up_pointers_s32(struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache **sources, +static void mux_init_look_up_pointers_s32(struct audio_stream *sink, + const struct audio_stream **sources, struct mux_look_up *lookup) { - const struct audio_stream __sparse_cache *source; + const struct audio_stream *source; uint32_t elem; /* init pointers */ @@ -334,8 +330,8 @@ static void mux_init_look_up_pointers_s32(struct audio_stream __sparse_cache *si } } -static void demux_init_look_up_pointers_s32(struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *source, +static void demux_init_look_up_pointers_s32(struct audio_stream *sink, + const struct audio_stream *source, struct mux_look_up *lookup) { uint32_t elem; @@ -364,8 +360,8 @@ static void demux_init_look_up_pointers_s32(struct audio_stream __sparse_cache * * @param[in] frames Number of frames to process. * @param[in] lookup mux look up table. */ -static void demux_s32le(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *source, uint32_t frames, +static void demux_s32le(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream *source, uint32_t frames, struct mux_look_up *lookup) { uint32_t i; @@ -417,8 +413,8 @@ static void demux_s32le(struct comp_dev *dev, struct audio_stream __sparse_cache * @param[in] frames Number of frames to process. * @param[in] lookup mux look up table. */ -static void mux_s32le(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache **sources, uint32_t frames, +static void mux_s32le(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream **sources, uint32_t frames, struct mux_look_up *lookup) { uint32_t i; @@ -534,8 +530,7 @@ mux_func mux_get_processing_function(struct processing_module *mod) source_list); for (i = 0; i < ARRAY_SIZE(mux_func_map); i++) { - struct comp_buffer __sparse_cache *sink_c = buffer_acquire(sinkb); - enum sof_ipc_frame fmt = audio_stream_get_frm_fmt(&sink_c->stream); + enum sof_ipc_frame fmt = audio_stream_get_frm_fmt(&sinkb->stream); if (fmt == mux_func_map[i].frame_format) @@ -558,10 +553,7 @@ demux_func demux_get_processing_function(struct processing_module *mod) sink_list); for (i = 0; i < ARRAY_SIZE(mux_func_map); i++) { - struct comp_buffer __sparse_cache *source_c = buffer_acquire(sourceb); - enum sof_ipc_frame fmt = audio_stream_get_frm_fmt(&source_c->stream); - - buffer_release(source_c); + enum sof_ipc_frame fmt = audio_stream_get_frm_fmt(&sourceb->stream); if (fmt == mux_func_map[i].frame_format) return mux_func_map[i].demux_proc_func; diff --git a/src/audio/pcm_converter/pcm_converter.c b/src/audio/pcm_converter/pcm_converter.c index 6c3753b8d8e7..5335ee295b51 100644 --- a/src/audio/pcm_converter/pcm_converter.c +++ b/src/audio/pcm_converter/pcm_converter.c @@ -15,8 +15,8 @@ #include #include -int pcm_convert_as_linear(const struct audio_stream __sparse_cache *source, uint32_t ioffset, - struct audio_stream __sparse_cache *sink, uint32_t ooffset, +int pcm_convert_as_linear(const struct audio_stream *source, uint32_t ioffset, + struct audio_stream *sink, uint32_t ooffset, uint32_t samples, pcm_converter_lin_func converter) { const int s_size_in = audio_stream_sample_bytes(source); diff --git a/src/audio/pcm_converter/pcm_converter_generic.c b/src/audio/pcm_converter/pcm_converter_generic.c index db3bbe9b88d4..6de32bd52495 100644 --- a/src/audio/pcm_converter/pcm_converter_generic.c +++ b/src/audio/pcm_converter/pcm_converter_generic.c @@ -34,9 +34,9 @@ #define BYTES_TO_S32_SAMPLES 2 #if CONFIG_PCM_CONVERTER_FORMAT_U8 && CONFIG_PCM_CONVERTER_FORMAT_S32LE -static int pcm_convert_u8_to_s32(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_u8_to_s32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { uint8_t *src = audio_stream_get_rptr(source); int32_t *dst = audio_stream_get_wptr(sink); @@ -63,9 +63,9 @@ static int pcm_convert_u8_to_s32(const struct audio_stream __sparse_cache *sourc return samples; } -static int pcm_convert_s32_to_u8(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s32_to_u8(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); uint8_t *dst = audio_stream_get_wptr(sink); @@ -95,8 +95,8 @@ static int pcm_convert_s32_to_u8(const struct audio_stream __sparse_cache *sourc #if CONFIG_PCM_CONVERTER_FORMAT_S16LE && CONFIG_PCM_CONVERTER_FORMAT_S24LE -static int pcm_convert_s16_to_s24(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s16_to_s24(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int16_t *src = audio_stream_get_rptr(source); @@ -124,8 +124,8 @@ static int pcm_convert_s16_to_s24(const struct audio_stream __sparse_cache *sour return samples; } -static int pcm_convert_s24_to_s16(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s24_to_s16(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -157,8 +157,8 @@ static int pcm_convert_s24_to_s16(const struct audio_stream __sparse_cache *sour #if CONFIG_PCM_CONVERTER_FORMAT_S16LE && CONFIG_PCM_CONVERTER_FORMAT_S32LE -static int pcm_convert_s16_to_s32(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s16_to_s32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int16_t *src = audio_stream_get_rptr(source); @@ -186,8 +186,8 @@ static int pcm_convert_s16_to_s32(const struct audio_stream __sparse_cache *sour return samples; } -static int pcm_convert_s32_to_s16(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s32_to_s16(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -219,8 +219,8 @@ static int pcm_convert_s32_to_s16(const struct audio_stream __sparse_cache *sour #if CONFIG_PCM_CONVERTER_FORMAT_S24LE && CONFIG_PCM_CONVERTER_FORMAT_S32LE -static int pcm_convert_s24_to_s32(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s24_to_s32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -248,8 +248,8 @@ static int pcm_convert_s24_to_s32(const struct audio_stream __sparse_cache *sour return samples; } -static int pcm_convert_s32_to_s24(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s32_to_s24(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -277,8 +277,8 @@ static int pcm_convert_s32_to_s24(const struct audio_stream __sparse_cache *sour return samples; } -static int pcm_convert_s32_to_s24_be(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s32_to_s24_be(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -442,16 +442,16 @@ static void pcm_convert_f_to_s16_lin(const void *psrc, void *pdst, dst[i] = sat_int16(_pcm_convert_f_to_i(src[i], 15)); } -static int pcm_convert_s16_to_f(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s16_to_f(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, pcm_convert_s16_to_f_lin); } -static int pcm_convert_f_to_s16(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_f_to_s16(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, @@ -486,16 +486,16 @@ static void pcm_convert_f_to_s24_lin(const void *psrc, void *pdst, dst[i] = sat_int24(_pcm_convert_f_to_i(src[i], 23)); } -static int pcm_convert_s24_to_f(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s24_to_f(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, pcm_convert_s24_to_f_lin); } -static int pcm_convert_f_to_s24(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_f_to_s24(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, @@ -530,16 +530,16 @@ static void pcm_convert_f_to_s32_lin(const void *psrc, void *pdst, dst[i] = _pcm_convert_f_to_i(src[i], 31); } -static int pcm_convert_s32_to_f(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s32_to_f(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, pcm_convert_s32_to_f_lin); } -static int pcm_convert_f_to_s32(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_f_to_s32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, @@ -599,8 +599,8 @@ const struct pcm_func_map pcm_func_map[] = { const size_t pcm_func_count = ARRAY_SIZE(pcm_func_map); #if CONFIG_PCM_CONVERTER_FORMAT_S16_C16_AND_S16_C32 -static int pcm_convert_s16_c16_to_s16_c32(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s16_c16_to_s16_c32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int16_t *src = audio_stream_get_rptr(source); @@ -628,8 +628,8 @@ static int pcm_convert_s16_c16_to_s16_c32(const struct audio_stream __sparse_cac return samples; } -static int pcm_convert_s16_c32_to_s16_c16(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s16_c32_to_s16_c16(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -658,8 +658,8 @@ static int pcm_convert_s16_c32_to_s16_c16(const struct audio_stream __sparse_cac } #endif #if CONFIG_PCM_CONVERTER_FORMAT_S16_C32_AND_S32_C32 -static int pcm_convert_s16_c32_to_s32_c32(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s16_c32_to_s32_c32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -687,8 +687,8 @@ static int pcm_convert_s16_c32_to_s32_c32(const struct audio_stream __sparse_cac return samples; } -static int pcm_convert_s32_c32_to_s16_c32(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s32_c32_to_s16_c32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -717,8 +717,8 @@ static int pcm_convert_s32_c32_to_s16_c32(const struct audio_stream __sparse_cac } #endif #if CONFIG_PCM_CONVERTER_FORMAT_S16_C32_AND_S24_C32 -static int pcm_convert_s16_c32_to_s24_c32(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s16_c32_to_s24_c32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -746,8 +746,8 @@ static int pcm_convert_s16_c32_to_s24_c32(const struct audio_stream __sparse_cac return samples; } -static int pcm_convert_s24_c32_to_s16_c32(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s24_c32_to_s16_c32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -777,8 +777,8 @@ static int pcm_convert_s24_c32_to_s16_c32(const struct audio_stream __sparse_cac #endif #if CONFIG_PCM_CONVERTER_FORMAT_S24_C24_AND_S24_C32 -static int pcm_convert_s24_c24_to_s24_c32(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s24_c24_to_s24_c32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { uint8_t *src = audio_stream_get_rptr(source); @@ -807,8 +807,8 @@ static int pcm_convert_s24_c24_to_s24_c32(const struct audio_stream __sparse_cac return samples; } -static int pcm_convert_s24_c32_to_s24_c24(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s24_c32_to_s24_c24(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -841,8 +841,8 @@ static int pcm_convert_s24_c32_to_s24_c24(const struct audio_stream __sparse_cac } /* 2x24bit samples are packed into 3x16bit samples for hda link dma */ -static int pcm_convert_s24_c32_to_s24_c24_link_gtw(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s24_c32_to_s24_c24_link_gtw(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); diff --git a/src/audio/pcm_converter/pcm_converter_hifi3.c b/src/audio/pcm_converter/pcm_converter_hifi3.c index ac5c14b379bc..da7e2ff1c7d1 100644 --- a/src/audio/pcm_converter/pcm_converter_hifi3.c +++ b/src/audio/pcm_converter/pcm_converter_hifi3.c @@ -36,8 +36,8 @@ * \param[in,out] sink Destination buffer. * \param[in] samples Number of samples to process. */ -static int pcm_convert_s16_to_s24(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s16_to_s24(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { ae_int16x4 sample = AE_ZERO16(); @@ -110,8 +110,8 @@ static ae_int32x2 pcm_shift_s24_to_s16(ae_int32x2 sample) * \param[in] samples Number of samples to process. * \return error code or number of processed samples. */ -static int pcm_convert_s24_to_s16(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s24_to_s16(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { ae_int16x4 sample = AE_ZERO16(); @@ -181,8 +181,8 @@ static int pcm_convert_s24_to_s16(const struct audio_stream __sparse_cache *sour * \param[in] samples Number of samples to process. * \return error code or number of processed samples. */ -static int pcm_convert_s16_to_s32(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s16_to_s32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int16_t *src = audio_stream_get_rptr(source); @@ -237,8 +237,8 @@ static int pcm_convert_s16_to_s32(const struct audio_stream __sparse_cache *sour * \param[in] samples Number of samples to process. * \return error code or number of processed samples. */ -static int pcm_convert_s32_to_s16(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s32_to_s16(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -303,8 +303,8 @@ static int pcm_convert_s32_to_s16(const struct audio_stream __sparse_cache *sour * \param[in] samples Number of samples to process. * \return error code or number of processed samples. */ -static int pcm_convert_s24_to_s32(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s24_to_s32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -368,8 +368,8 @@ static ae_int32x2 pcm_shift_s32_to_s24(ae_int32x2 sample) * \param[in] samples Number of samples to process. * \return error code or number of processed samples. */ -static int pcm_convert_s32_to_s24(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s32_to_s24(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -413,8 +413,8 @@ static int pcm_convert_s32_to_s24(const struct audio_stream __sparse_cache *sour return samples; } -static int pcm_convert_s32_to_s24_be(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s32_to_s24_be(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -541,8 +541,8 @@ static void pcm_convert_f_to_s16_lin(const void *psrc, void *pdst, * \param[in] samples Number of samples to process. * \return error code or number of processed samples. */ -static int pcm_convert_s16_to_f(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s16_to_f(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, @@ -556,8 +556,8 @@ static int pcm_convert_s16_to_f(const struct audio_stream __sparse_cache *source * \param[in] samples Number of samples to process. * \return error code or number of processed samples. */ -static int pcm_convert_f_to_s16(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_f_to_s16(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, @@ -642,8 +642,8 @@ static void pcm_convert_f_to_s24_lin(const void *psrc, void *pdst, * \param[in] samples Number of samples to process. * \return error code or number of processed samples. */ -static int pcm_convert_s24_to_f(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s24_to_f(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, @@ -657,8 +657,8 @@ static int pcm_convert_s24_to_f(const struct audio_stream __sparse_cache *source * \param[in] samples Number of samples to process. * \return error code or number of processed samples. */ -static int pcm_convert_f_to_s24(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_f_to_s24(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, @@ -739,8 +739,8 @@ static void pcm_convert_f_to_s32_lin(const void *psrc, void *pdst, * \param[in] samples Number of samples to process. * \return error code or number of processed samples. */ -static int pcm_convert_s32_to_f(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_s32_to_f(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, @@ -754,8 +754,8 @@ static int pcm_convert_s32_to_f(const struct audio_stream __sparse_cache *source * \param[in] samples Number of samples to process. * \return error code or number of processed samples. */ -static int pcm_convert_f_to_s32(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +static int pcm_convert_f_to_s32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, @@ -810,9 +810,9 @@ const struct pcm_func_map pcm_func_map[] = { const size_t pcm_func_count = ARRAY_SIZE(pcm_func_map); #if CONFIG_PCM_CONVERTER_FORMAT_S16_C16_AND_S16_C32 -static int pcm_convert_s16_c16_to_s16_c32(const struct audio_stream __sparse_cache *source, +static int pcm_convert_s16_c16_to_s16_c32(const struct audio_stream *source, uint32_t ioffset, - struct audio_stream __sparse_cache *sink, + struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int16_t *src = audio_stream_get_rptr(source); @@ -860,9 +860,9 @@ static int pcm_convert_s16_c16_to_s16_c32(const struct audio_stream __sparse_cac return samples; } -static int pcm_convert_s16_c32_to_s16_c16(const struct audio_stream __sparse_cache *source, +static int pcm_convert_s16_c32_to_s16_c16(const struct audio_stream *source, uint32_t ioffset, - struct audio_stream __sparse_cache *sink, + struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -919,9 +919,9 @@ static int pcm_convert_s16_c32_to_s16_c16(const struct audio_stream __sparse_cac #endif #if CONFIG_PCM_CONVERTER_FORMAT_S16_C32_AND_S32_C32 -static int pcm_convert_s16_c32_to_s32_c32(const struct audio_stream __sparse_cache *source, +static int pcm_convert_s16_c32_to_s32_c32(const struct audio_stream *source, uint32_t ioffset, - struct audio_stream __sparse_cache *sink, + struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -962,9 +962,9 @@ static int pcm_convert_s16_c32_to_s32_c32(const struct audio_stream __sparse_cac return samples; } -static int pcm_convert_s32_c32_to_s16_c32(const struct audio_stream __sparse_cache *source, +static int pcm_convert_s32_c32_to_s16_c32(const struct audio_stream *source, uint32_t ioffset, - struct audio_stream __sparse_cache *sink, + struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -1007,9 +1007,9 @@ static int pcm_convert_s32_c32_to_s16_c32(const struct audio_stream __sparse_cac #endif #if CONFIG_PCM_CONVERTER_FORMAT_S16_C32_AND_S24_C32 -static int pcm_convert_s16_c32_to_s24_c32(const struct audio_stream __sparse_cache *source, +static int pcm_convert_s16_c32_to_s24_c32(const struct audio_stream *source, uint32_t ioffset, - struct audio_stream __sparse_cache *sink, + struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -1062,9 +1062,9 @@ static ae_int32x2 pcm_shift_s24_c32_to_s16(ae_int32x2 sample) return sample; } -static int pcm_convert_s24_c32_to_s16_c32(const struct audio_stream __sparse_cache *source, +static int pcm_convert_s24_c32_to_s16_c32(const struct audio_stream *source, uint32_t ioffset, - struct audio_stream __sparse_cache *sink, + struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); @@ -1109,9 +1109,9 @@ static int pcm_convert_s24_c32_to_s16_c32(const struct audio_stream __sparse_cac #endif #if CONFIG_PCM_CONVERTER_FORMAT_S24_C24_AND_S24_C32 -static int pcm_convert_s24_c24_to_s24_c32(const struct audio_stream __sparse_cache *source, +static int pcm_convert_s24_c24_to_s24_c32(const struct audio_stream *source, uint32_t ioffset, - struct audio_stream __sparse_cache *sink, + struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { uint8_t *src = audio_stream_get_rptr(source); @@ -1156,9 +1156,9 @@ static int pcm_convert_s24_c24_to_s24_c32(const struct audio_stream __sparse_cac return samples; } -static int pcm_convert_s24_c32_to_s24_c24(const struct audio_stream __sparse_cache *source, +static int pcm_convert_s24_c32_to_s24_c24(const struct audio_stream *source, uint32_t ioffset, - struct audio_stream __sparse_cache *sink, + struct audio_stream *sink, uint32_t ooffset, uint32_t samples) { int32_t *src = audio_stream_get_rptr(source); diff --git a/src/audio/pipeline/pipeline-graph.c b/src/audio/pipeline/pipeline-graph.c index 71645c69fa84..82fe49bbed20 100644 --- a/src/audio/pipeline/pipeline-graph.c +++ b/src/audio/pipeline/pipeline-graph.c @@ -168,18 +168,10 @@ struct pipeline *pipeline_new(uint32_t pipeline_id, uint32_t priority, uint32_t static void buffer_set_comp(struct comp_buffer *buffer, struct comp_dev *comp, int dir) { - struct comp_buffer __sparse_cache *buffer_c = buffer_acquire(buffer); - if (dir == PPL_CONN_DIR_COMP_TO_BUFFER) - buffer_c->source = comp; + buffer->source = comp; else - buffer_c->sink = comp; - - buffer_release(buffer_c); - - /* The buffer might be marked as shared later, write back the cache */ - if (!buffer->c.shared) - dcache_writeback_invalidate_region(uncache_to_cache(buffer), sizeof(*buffer)); + buffer->sink = comp; } int pipeline_connect(struct comp_dev *comp, struct comp_buffer *buffer, @@ -235,7 +227,9 @@ int pipeline_free(struct pipeline *p) /* remove from any scheduling */ if (p->pipe_task) { +#if !CONFIG_LIBRARY || UNIT_TEST schedule_task_free(p->pipe_task); +#endif rfree(p->pipe_task); } @@ -268,7 +262,14 @@ static int pipeline_comp_complete(struct comp_dev *current, /* complete component init */ current->pipeline = ppl_data->p; - current->period = ppl_data->p->period; + /* LL module has its period always eq period of the pipeline + * DP period is set to 0 as sink format may not yet been set + * It will be calculated during module prepare operation + * either by the module or to default value based on module's OBS + */ + if (current->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL) + current->period = ppl_data->p->period; + current->priority = ppl_data->p->priority; return pipeline_for_each_comp(current, ctx, dir); @@ -414,7 +415,6 @@ int pipeline_for_each_comp(struct comp_dev *current, /* run this operation further */ list_for_item(clist, buffer_list) { struct comp_buffer *buffer = buffer_from_list(clist, dir); - struct comp_buffer __sparse_cache *buffer_c; struct comp_dev *buffer_comp; int err = 0; @@ -438,28 +438,22 @@ int pipeline_for_each_comp(struct comp_dev *current, buffer_comp = buffer_get_comp(buffer, dir); - buffer_c = buffer_acquire(buffer); - /* execute operation on buffer */ if (ctx->buff_func) - ctx->buff_func(buffer_c, ctx->buff_data); + ctx->buff_func(buffer, ctx->buff_data); /* don't go further if this component is not connected */ if (buffer_comp && (!ctx->skip_incomplete || buffer_comp->pipeline) && ctx->comp_func) { - buffer_c->walking = true; - buffer_release(buffer_c); + buffer->walking = true; err = ctx->comp_func(buffer_comp, buffer, ctx, dir); - buffer_c = buffer_acquire(buffer); - buffer_c->walking = false; + buffer->walking = false; } - buffer_release(buffer_c); - if (err < 0 || err == PPL_STATUS_PATH_STOP) return err; } diff --git a/src/audio/pipeline/pipeline-params.c b/src/audio/pipeline/pipeline-params.c index 43974e290fb4..ecf27bfa3d3c 100644 --- a/src/audio/pipeline/pipeline-params.c +++ b/src/audio/pipeline/pipeline-params.c @@ -30,7 +30,6 @@ static int pipeline_comp_params_neg(struct comp_dev *current, int dir) { struct pipeline_data *ppl_data = ctx->comp_data; - struct comp_buffer __sparse_cache *buf_c = buffer_acquire(calling_buf); int err = 0; pipe_dbg(current->pipeline, "pipeline_comp_params_neg(), current->comp.id = %u, dir = %u", @@ -48,12 +47,12 @@ static int pipeline_comp_params_neg(struct comp_dev *current, * a component who has different channels input/output buffers * should explicitly configure the channels of the branched buffers. */ - err = buffer_set_params(buf_c, &ppl_data->params->params, + err = buffer_set_params(calling_buf, &ppl_data->params->params, BUFFER_UPDATE_FORCE); break; default: /* return 0 if params matches */ - if (!buffer_params_match(buf_c, + if (!buffer_params_match(calling_buf, &ppl_data->params->params, BUFF_PARAMS_FRAME_FMT | BUFF_PARAMS_RATE)) { @@ -66,8 +65,6 @@ static int pipeline_comp_params_neg(struct comp_dev *current, err = -EINVAL; } } - - buffer_release(buf_c); return err; } @@ -131,7 +128,7 @@ static int pipeline_comp_params(struct comp_dev *current, } /* save params changes made by component */ -static void pipeline_update_buffer_pcm_params(struct comp_buffer __sparse_cache *buffer, +static void pipeline_update_buffer_pcm_params(struct comp_buffer *buffer, void *data) { struct sof_ipc_stream_params *params = data; @@ -188,11 +185,8 @@ static int pipeline_comp_hw_params_buf(struct comp_dev *current, return ret; /* set buffer parameters */ if (calling_buf) { - struct comp_buffer __sparse_cache *buf_c = buffer_acquire(calling_buf); - - ret = buffer_set_params(buf_c, &ppl_data->params->params, + ret = buffer_set_params(calling_buf, &ppl_data->params->params, BUFFER_UPDATE_IF_UNSET); - buffer_release(buf_c); if (ret < 0) pipe_err(current->pipeline, "pipeline_comp_hw_params(): buffer_set_params(): %d", ret); @@ -317,36 +311,13 @@ static int pipeline_comp_prepare(struct comp_dev *current, } } - switch (current->ipc_config.proc_domain) { - case COMP_PROCESSING_DOMAIN_LL: - /* this is a LL scheduled module */ + if (current->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL) { + /* init a task for LL module, DP task has been created in during init_instance */ err = pipeline_comp_ll_task_init(current->pipeline); - break; - -#if CONFIG_ZEPHYR_DP_SCHEDULER - case COMP_PROCESSING_DOMAIN_DP: - /* this is a DP scheduled module */ - - /* - * workaround - because of some issues with cache, currently we can allow DP - * modules to run on the same core as LL pipeline only. - * to be removed once buffering is fixed - */ - if (current->pipeline->core != current->ipc_config.core) - err = -EINVAL; - else - err = pipeline_comp_dp_task_init(current); - - break; -#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ - - default: - err = -EINVAL; + if (err < 0) + return err; } - if (err < 0) - return err; - err = comp_prepare(current); if (err < 0 || err == PPL_STATUS_PATH_STOP) return err; diff --git a/src/audio/pipeline/pipeline-schedule.c b/src/audio/pipeline/pipeline-schedule.c index a4a7a71da50f..e354ff0f79dc 100644 --- a/src/audio/pipeline/pipeline-schedule.c +++ b/src/audio/pipeline/pipeline-schedule.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -47,7 +48,7 @@ DECLARE_SOF_UUID("dp-task", dp_task_uuid, 0xee755917, 0x96b9, 0x4130, /** * \brief a priority of the DP threads in the system. */ -#define ZEPHYR_DP_THREAD_PRIORITY (CONFIG_NUM_PREEMPT_PRIORITIES - 1) +#define ZEPHYR_DP_THREAD_PRIORITY (CONFIG_NUM_PREEMPT_PRIORITIES - 2) #endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ @@ -378,15 +379,18 @@ int pipeline_comp_ll_task_init(struct pipeline *p) #if CONFIG_ZEPHYR_DP_SCHEDULER static enum task_state dp_task_run(void *data) { - struct comp_dev *comp = data; + struct processing_module *mod = data; + + module_process_sink_src(mod, mod->sources, mod->num_of_sources, + mod->sinks, mod->num_of_sinks); - comp->drv->ops.copy(comp); return SOF_TASK_STATE_RESCHEDULE; } int pipeline_comp_dp_task_init(struct comp_dev *comp) { int ret; + struct processing_module *mod = comp_get_drvdata(comp); struct task_ops ops = { .run = dp_task_run, .get_deadline = NULL, @@ -397,7 +401,7 @@ int pipeline_comp_dp_task_init(struct comp_dev *comp) ret = scheduler_dp_task_init(&comp->task, SOF_UUID(dp_task_uuid), &ops, - comp, + mod, comp->ipc_config.core, TASK_DP_STACK_SIZE, ZEPHYR_DP_THREAD_PRIORITY); diff --git a/src/audio/pipeline/pipeline-stream.c b/src/audio/pipeline/pipeline-stream.c index 6fe795cf54f5..547b3198f311 100644 --- a/src/audio/pipeline/pipeline-stream.c +++ b/src/audio/pipeline/pipeline-stream.c @@ -147,6 +147,37 @@ int pipeline_copy(struct pipeline *p) return ret; } +#if CONFIG_LIBRARY && !CONFIG_LIBRARY_STATIC +/* trigger pipeline immediately in IPC context. TODO: Add support for XRUN */ +int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd) +{ + int ret; + + pipe_info(p, "pipe trigger cmd %d", cmd); + + p->trigger.aborted = false; + + ret = pipeline_trigger_run(p, host, cmd); + if (ret < 0) + return ret; + + switch (cmd) { + case COMP_TRIGGER_PRE_START: + case COMP_TRIGGER_START: + case COMP_TRIGGER_PRE_RELEASE: + p->status = COMP_STATE_ACTIVE; + break; + case COMP_TRIGGER_STOP: + case COMP_TRIGGER_PAUSE: + p->status = COMP_STATE_PAUSED; + break; + default: + break; + } + + return 0; +} +#else /* only collect scheduling components */ static int pipeline_comp_list(struct comp_dev *current, struct comp_buffer *calling_buf, @@ -304,6 +335,7 @@ int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd) return 0; } +#endif /* Runs in IPC or in pipeline task context */ static int pipeline_comp_trigger(struct comp_dev *current, diff --git a/src/audio/rtnr/rtnr.c b/src/audio/rtnr/rtnr.c index 8c3ce8496c14..49db44eac1cb 100644 --- a/src/audio/rtnr/rtnr.c +++ b/src/audio/rtnr/rtnr.c @@ -325,7 +325,6 @@ static int rtnr_params(struct comp_dev *dev, struct sof_ipc_stream_params *param int ret; struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *sinkb, *sourceb; - struct comp_buffer __sparse_cache *sink_c, *source_c; bool channels_valid; comp_info(dev, "rtnr_params()"); @@ -341,21 +340,17 @@ static int rtnr_params(struct comp_dev *dev, struct sof_ipc_stream_params *param sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - /* set source/sink_frames/rate */ - cd->source_rate = audio_stream_get_rate(&source_c->stream); - cd->sink_rate = audio_stream_get_rate(&sink_c->stream); - cd->sources_stream[0].rate = audio_stream_get_rate(&source_c->stream); - cd->sink_stream.rate = audio_stream_get_rate(&sink_c->stream); - channels_valid = audio_stream_get_channels(&source_c->stream) == - audio_stream_get_channels(&sink_c->stream); + cd->source_rate = audio_stream_get_rate(&sourceb->stream); + cd->sink_rate = audio_stream_get_rate(&sinkb->stream); + cd->sources_stream[0].rate = audio_stream_get_rate(&sourceb->stream); + cd->sink_stream.rate = audio_stream_get_rate(&sinkb->stream); + channels_valid = audio_stream_get_channels(&sourceb->stream) == + audio_stream_get_channels(&sinkb->stream); if (!cd->sink_rate) { comp_err(dev, "rtnr_nr_params(), zero sink rate"); - ret = -EINVAL; - goto out; + return -EINVAL; } /* Currently support 16kHz sample rate only. */ @@ -369,31 +364,25 @@ static int rtnr_params(struct comp_dev *dev, struct sof_ipc_stream_params *param default: comp_err(dev, "rtnr_nr_params(), invalid sample rate(%d kHz)", cd->source_rate); - ret = -EINVAL; - goto out; + return -EINVAL; } if (!channels_valid) { comp_err(dev, "rtnr_params(), source/sink stream must have same channels"); - ret = -EINVAL; - goto out; + return -EINVAL; } /* set source/sink stream channels */ - cd->sources_stream[0].channels = audio_stream_get_channels(&source_c->stream); - cd->sink_stream.channels = audio_stream_get_channels(&sink_c->stream); + cd->sources_stream[0].channels = audio_stream_get_channels(&sourceb->stream); + cd->sink_stream.channels = audio_stream_get_channels(&sinkb->stream); /* set source/sink stream overrun/underrun permitted */ - cd->sources_stream[0].overrun_permitted = audio_stream_get_overrun(&source_c->stream); - cd->sink_stream.overrun_permitted = audio_stream_get_overrun(&sink_c->stream); - cd->sources_stream[0].underrun_permitted = audio_stream_get_underrun(&source_c->stream); - cd->sink_stream.underrun_permitted = audio_stream_get_underrun(&sink_c->stream); - -out: - buffer_release(sink_c); - buffer_release(source_c); + cd->sources_stream[0].overrun_permitted = audio_stream_get_overrun(&sourceb->stream); + cd->sink_stream.overrun_permitted = audio_stream_get_overrun(&sinkb->stream); + cd->sources_stream[0].underrun_permitted = audio_stream_get_underrun(&sourceb->stream); + cd->sink_stream.underrun_permitted = audio_stream_get_underrun(&sinkb->stream); - return ret; + return 0; } static int rtnr_get_comp_config(struct comp_data *cd, struct sof_ipc_ctrl_data *cdata, @@ -727,7 +716,7 @@ static int rtnr_trigger(struct comp_dev *dev, int cmd) } static void rtnr_copy_from_sof_stream(struct audio_stream_rtnr *dst, - struct audio_stream __sparse_cache *src) + struct audio_stream *src) { dst->size = audio_stream_get_size(src); @@ -739,7 +728,7 @@ static void rtnr_copy_from_sof_stream(struct audio_stream_rtnr *dst, dst->end_addr = audio_stream_get_end_addr(src); } -static void rtnr_copy_to_sof_stream(struct audio_stream __sparse_cache *dst, +static void rtnr_copy_to_sof_stream(struct audio_stream *dst, struct audio_stream_rtnr *src) { audio_stream_set_size(dst, src->size); @@ -832,7 +821,7 @@ static int rtnr_copy(struct comp_dev *dev) comp_dbg(dev, "rtnr_copy() passthrough"); /* Get source, sink, number of frames etc. to process. */ - comp_get_copy_limits_with_lock(source, sink, &cl); + comp_get_copy_limits(source, sink, &cl); buffer_stream_invalidate(source, cl.source_bytes); @@ -851,7 +840,7 @@ static int rtnr_prepare(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *sinkb; - struct comp_buffer __sparse_cache *sink_c; + struct comp_buffer *sink_c; int ret; comp_dbg(dev, "rtnr_prepare()"); @@ -874,10 +863,8 @@ static int rtnr_prepare(struct comp_dev *dev) /* Get sink data format */ sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sinkb); - cd->sink_format = audio_stream_get_frm_fmt(&sink_c->stream); - cd->sink_stream.frame_fmt = audio_stream_get_frm_fmt(&sink_c->stream); - buffer_release(sink_c); + cd->sink_format = audio_stream_get_frm_fmt(&sinkb->stream); + cd->sink_stream.frame_fmt = audio_stream_get_frm_fmt(&sinkb->stream); /* Check source and sink PCM format and get processing function */ comp_info(dev, "rtnr_prepare(), sink_format=%d", cd->sink_format); diff --git a/src/audio/selector/selector.c b/src/audio/selector/selector.c index 8a39db81b2ef..97126168ac77 100644 --- a/src/audio/selector/selector.c +++ b/src/audio/selector/selector.c @@ -60,7 +60,6 @@ static int selector_verify_params(struct comp_dev *dev, { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *buffer, *sinkb; - struct comp_buffer __sparse_cache *buffer_c, *sink_c; uint32_t in_channels; uint32_t out_channels; @@ -86,15 +85,13 @@ static int selector_verify_params(struct comp_dev *dev, } in_channels = cd->config.in_channels_count; - buffer_c = buffer_acquire(buffer); - /* if cd->config.out_channels_count are equal to 0 * (it can vary), we set params->channels to sink buffer * channels, which were previously set in * pipeline_comp_hw_params() */ out_channels = cd->config.out_channels_count ? - cd->config.out_channels_count : audio_stream_get_channels(&buffer_c->stream); + cd->config.out_channels_count : audio_stream_get_channels(&buffer->stream); params->channels = out_channels; } else { /* fetch source buffer for capture */ @@ -107,27 +104,21 @@ static int selector_verify_params(struct comp_dev *dev, } out_channels = cd->config.out_channels_count; - buffer_c = buffer_acquire(buffer); - /* if cd->config.in_channels_count are equal to 0 * (it can vary), we set params->channels to source buffer * channels, which were previously set in * pipeline_comp_hw_params() */ in_channels = cd->config.in_channels_count ? - cd->config.in_channels_count : audio_stream_get_channels(&buffer_c->stream); + cd->config.in_channels_count : audio_stream_get_channels(&buffer->stream); params->channels = in_channels; } /* Set buffer params */ - buffer_set_params(buffer_c, params, BUFFER_UPDATE_FORCE); - - buffer_release(buffer_c); + buffer_set_params(buffer, params, BUFFER_UPDATE_FORCE); /* set component period frames */ - sink_c = buffer_acquire(sinkb); - component_set_nearest_period_frames(dev, audio_stream_get_rate(&sink_c->stream)); - buffer_release(sink_c); + component_set_nearest_period_frames(dev, audio_stream_get_rate(&sinkb->stream)); /* verify input channels */ switch (in_channels) { @@ -358,7 +349,6 @@ static int selector_cmd(struct comp_dev *dev, int cmd, void *data, static int selector_trigger(struct comp_dev *dev, int cmd) { struct comp_buffer *sourceb; - struct comp_buffer __sparse_cache *source_c; enum sof_comp_type type; int ret; @@ -367,17 +357,13 @@ static int selector_trigger(struct comp_dev *dev, int cmd) sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - source_c = buffer_acquire(sourceb); - ret = comp_set_state(dev, cmd); /* TODO: remove in the future after adding support for case when * kpb_init_draining() and kpb_draining_task() are interrupted by * new pipeline_task() */ - type = dev_comp_type(source_c->source); - - buffer_release(source_c); + type = dev_comp_type(sourceb->source); return type == SOF_COMP_KPB ? PPL_STATUS_PATH_TERMINATE : ret; } @@ -391,7 +377,6 @@ static int selector_copy(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *sink, *source; - struct comp_buffer __sparse_cache *sink_c, *source_c; uint32_t frames; uint32_t source_bytes; uint32_t sink_bytes; @@ -404,33 +389,24 @@ static int selector_copy(struct comp_dev *dev) sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(source); - - if (!audio_stream_get_avail(&source_c->stream)) { - buffer_release(source_c); + if (!audio_stream_get_avail(&source->stream)) return PPL_STATUS_PATH_STOP; - } - sink_c = buffer_acquire(sink); - - frames = audio_stream_avail_frames(&source_c->stream, &sink_c->stream); - source_bytes = frames * audio_stream_frame_bytes(&source_c->stream); - sink_bytes = frames * audio_stream_frame_bytes(&sink_c->stream); + frames = audio_stream_avail_frames(&source->stream, &sink->stream); + source_bytes = frames * audio_stream_frame_bytes(&source->stream); + sink_bytes = frames * audio_stream_frame_bytes(&sink->stream); comp_dbg(dev, "selector_copy(), source_bytes = 0x%x, sink_bytes = 0x%x", source_bytes, sink_bytes); /* copy selected channels from in to out */ - buffer_stream_invalidate(source_c, source_bytes); - cd->sel_func(dev, &sink_c->stream, &source_c->stream, frames); - buffer_stream_writeback(sink_c, sink_bytes); + buffer_stream_invalidate(source, source_bytes); + cd->sel_func(dev, &sink->stream, &source->stream, frames); + buffer_stream_writeback(sink, sink_bytes); /* calculate new free and available */ - comp_update_buffer_produce(sink_c, sink_bytes); - comp_update_buffer_consume(source_c, source_bytes); - - buffer_release(sink_c); - buffer_release(source_c); + comp_update_buffer_produce(sink, sink_bytes); + comp_update_buffer_consume(source, source_bytes); return 0; } @@ -444,7 +420,6 @@ static int selector_prepare(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *sinkb, *sourceb; - struct comp_buffer __sparse_cache *sink_c, *source_c; size_t sink_size; int ret; @@ -463,30 +438,24 @@ static int selector_prepare(struct comp_dev *dev) sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - /* get source data format and period bytes */ - cd->source_format = audio_stream_get_frm_fmt(&source_c->stream); - cd->source_period_bytes = audio_stream_period_bytes(&source_c->stream, dev->frames); + cd->source_format = audio_stream_get_frm_fmt(&sourceb->stream); + cd->source_period_bytes = audio_stream_period_bytes(&sourceb->stream, dev->frames); /* get sink data format and period bytes */ - cd->sink_format = audio_stream_get_frm_fmt(&sink_c->stream); - cd->sink_period_bytes = audio_stream_period_bytes(&sink_c->stream, dev->frames); + cd->sink_format = audio_stream_get_frm_fmt(&sinkb->stream); + cd->sink_period_bytes = audio_stream_period_bytes(&sinkb->stream, dev->frames); /* There is an assumption that sink component will report out * proper number of channels [1] for selector to actually * reduce channel count between source and sink */ comp_dbg(dev, "selector_prepare(): sourceb->schannels = %u", - audio_stream_get_channels(&source_c->stream)); + audio_stream_get_channels(&sourceb->stream)); comp_dbg(dev, "selector_prepare(): sinkb->channels = %u", - audio_stream_get_channels(&sink_c->stream)); - - sink_size = audio_stream_get_size(&sink_c->stream); + audio_stream_get_channels(&sinkb->stream)); - buffer_release(sink_c); - buffer_release(source_c); + sink_size = audio_stream_get_size(&sinkb->stream); if (sink_size < cd->sink_period_bytes) { comp_err(dev, "selector_prepare(): sink buffer size %d is insufficient < %d", @@ -673,7 +642,6 @@ static void set_selector_params(struct processing_module *mod, { struct comp_dev *dev = mod->dev; struct comp_data *cd = module_get_private_data(mod); - struct comp_buffer __sparse_cache *source; const struct sof_selector_ipc4_config *sel_cfg = &cd->sel_ipc4_cfg; const struct ipc4_audio_format *out_fmt = NULL; struct comp_buffer *src_buf; @@ -700,12 +668,10 @@ static void set_selector_params(struct processing_module *mod, list_for_item(sink_list, &dev->bsink_list) { struct comp_buffer *sink_buf = container_of(sink_list, struct comp_buffer, source_list); - struct comp_buffer __sparse_cache *sink = buffer_acquire(sink_buf); - ipc4_update_buffer_format(sink, out_fmt); - audio_stream_set_channels(&sink->stream, params->channels); - audio_stream_set_rate(&sink->stream, params->rate); - buffer_release(sink); + ipc4_update_buffer_format(sink_buf, out_fmt); + audio_stream_set_channels(&sink_buf->stream, params->channels); + audio_stream_set_rate(&sink_buf->stream, params->rate); } /* update the source format @@ -715,12 +681,9 @@ static void set_selector_params(struct processing_module *mod, * and the first one is not ready yet along with sink buffers params */ src_buf = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - source = buffer_acquire(src_buf); - if (!source->hw_params_configured) - ipc4_update_buffer_format(source, &mod->priv.cfg.base_cfg.audio_fmt); - - buffer_release(source); + if (!src_buf->hw_params_configured) + ipc4_update_buffer_format(src_buf, &mod->priv.cfg.base_cfg.audio_fmt); } static int selector_verify_params(struct processing_module *mod, @@ -729,7 +692,6 @@ static int selector_verify_params(struct processing_module *mod, struct comp_dev *dev = mod->dev; struct comp_data *cd = module_get_private_data(mod); struct comp_buffer *buffer; - struct comp_buffer __sparse_cache *buffer_c; uint32_t in_channels = cd->config.in_channels_count; uint32_t out_channels = cd->config.out_channels_count; @@ -755,15 +717,11 @@ static int selector_verify_params(struct processing_module *mod, params->channels = in_channels; buffer = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); } - buffer_c = buffer_acquire(buffer); - buffer_set_params(buffer_c, params, BUFFER_UPDATE_FORCE); - buffer_release(buffer_c); + buffer_set_params(buffer, params, BUFFER_UPDATE_FORCE); /* set component period frames */ buffer = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - buffer_c = buffer_acquire(buffer); - component_set_nearest_period_frames(dev, audio_stream_get_rate(&buffer_c->stream)); - buffer_release(buffer_c); + component_set_nearest_period_frames(dev, audio_stream_get_rate(&buffer->stream)); return 0; } @@ -862,14 +820,13 @@ static int selector_process(struct processing_module *mod, * \return Error code. */ static int selector_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct comp_data *cd = module_get_private_data(mod); struct module_data *md = &mod->priv; struct comp_dev *dev = mod->dev; struct comp_buffer *sinkb, *sourceb; - struct comp_buffer __sparse_cache *sink_c, *source_c; size_t sink_size; int ret; @@ -886,36 +843,30 @@ static int selector_prepare(struct processing_module *mod, sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - - audio_stream_init_alignment_constants(4, 1, &source_c->stream); - audio_stream_init_alignment_constants(4, 1, &sink_c->stream); + audio_stream_init_alignment_constants(4, 1, &sourceb->stream); + audio_stream_init_alignment_constants(4, 1, &sinkb->stream); /* get source data format and period bytes */ - cd->source_format = audio_stream_get_frm_fmt(&source_c->stream); - cd->source_period_bytes = audio_stream_period_bytes(&source_c->stream, dev->frames); + cd->source_format = audio_stream_get_frm_fmt(&sourceb->stream); + cd->source_period_bytes = audio_stream_period_bytes(&sourceb->stream, dev->frames); /* get sink data format and period bytes */ - cd->sink_format = audio_stream_get_frm_fmt(&sink_c->stream); - cd->sink_period_bytes = audio_stream_period_bytes(&sink_c->stream, dev->frames); + cd->sink_format = audio_stream_get_frm_fmt(&sinkb->stream); + cd->sink_period_bytes = audio_stream_period_bytes(&sinkb->stream, dev->frames); /* There is an assumption that sink component will report out * proper number of channels [1] for selector to actually * reduce channel count between source and sink */ comp_info(dev, "selector_prepare(): source sink channel = %u %u", - audio_stream_get_channels(&source_c->stream), - audio_stream_get_channels(&sink_c->stream)); + audio_stream_get_channels(&sourceb->stream), + audio_stream_get_channels(&sinkb->stream)); - sink_size = audio_stream_get_size(&sink_c->stream); + sink_size = audio_stream_get_size(&sinkb->stream); md->mpd.in_buff_size = cd->source_period_bytes; md->mpd.out_buff_size = cd->sink_period_bytes; - buffer_release(sink_c); - buffer_release(source_c); - if (sink_size < cd->sink_period_bytes) { comp_err(dev, "selector_prepare(): sink buffer size %d is insufficient < %d", sink_size, cd->sink_period_bytes); @@ -965,7 +916,7 @@ static int selector_reset(struct processing_module *mod) } /** \brief Selector component definition. */ -static struct module_interface selector_interface = { +static const struct module_interface selector_interface = { .init = selector_init, .prepare = selector_prepare, .process_audio_stream = selector_process, diff --git a/src/audio/selector/selector_generic.c b/src/audio/selector/selector_generic.c index ca9e72f656d5..923277ec3f46 100644 --- a/src/audio/selector/selector_generic.c +++ b/src/audio/selector/selector_generic.c @@ -32,8 +32,8 @@ LOG_MODULE_DECLARE(selector, CONFIG_SOF_LOG_LEVEL); * \param[in,out] source Source buffer. * \param[in] frames Number of frames to process. */ -static void sel_s16le_1ch(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *source, uint32_t frames) +static void sel_s16le_1ch(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream *source, uint32_t frames) { struct comp_data *cd = comp_get_drvdata(dev); int16_t *src = audio_stream_get_rptr(source); @@ -72,8 +72,8 @@ static void sel_s16le_1ch(struct comp_dev *dev, struct audio_stream __sparse_cac * \param[in,out] source Source buffer. * \param[in] frames Number of frames to process. */ -static void sel_s16le_nch(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *source, uint32_t frames) +static void sel_s16le_nch(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream *source, uint32_t frames) { int8_t *src = audio_stream_get_rptr(source); int8_t *dst = audio_stream_get_wptr(sink); @@ -104,8 +104,8 @@ static void sel_s16le_nch(struct comp_dev *dev, struct audio_stream __sparse_cac * \param[in,out] source Source buffer. * \param[in] frames Number of frames to process. */ -static void sel_s32le_1ch(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *source, uint32_t frames) +static void sel_s32le_1ch(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream *source, uint32_t frames) { struct comp_data *cd = comp_get_drvdata(dev); int32_t *src = audio_stream_get_rptr(source); @@ -144,8 +144,8 @@ static void sel_s32le_1ch(struct comp_dev *dev, struct audio_stream __sparse_cac * \param[in,out] source Source buffer. * \param[in] frames Number of frames to process. */ -static void sel_s32le_nch(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *source, uint32_t frames) +static void sel_s32le_nch(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream *source, uint32_t frames) { int8_t *src = audio_stream_get_rptr(source); int8_t *dst = audio_stream_get_wptr(sink); @@ -206,8 +206,8 @@ static void sel_s16le(struct processing_module *mod, struct input_stream_buffer struct output_stream_buffer *bsink, uint32_t frames) { struct comp_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int16_t *src = audio_stream_get_rptr(source); int16_t *dest = audio_stream_get_wptr(sink); int nmax; @@ -277,8 +277,8 @@ static void sel_s32le(struct processing_module *mod, struct input_stream_buffer struct output_stream_buffer *bsink, uint32_t frames) { struct comp_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t *src = audio_stream_get_rptr(source); int32_t *dest = audio_stream_get_wptr(sink); int nmax; diff --git a/src/audio/sink_api_helper.c b/src/audio/sink_api_helper.c index 4655fdbde347..46ffbfd6b860 100644 --- a/src/audio/sink_api_helper.c +++ b/src/audio/sink_api_helper.c @@ -7,19 +7,19 @@ #include #include -void sink_init(struct sof_sink __sparse_cache *sink, const struct sink_ops *ops, +void sink_init(struct sof_sink *sink, const struct sink_ops *ops, struct sof_audio_stream_params *audio_stream_params) { sink->ops = ops; sink->audio_stream_params = audio_stream_params; } -size_t sink_get_free_size(struct sof_sink __sparse_cache *sink) +size_t sink_get_free_size(struct sof_sink *sink) { return sink->ops->get_free_size(sink); } -int sink_get_buffer(struct sof_sink __sparse_cache *sink, size_t req_size, +int sink_get_buffer(struct sof_sink *sink, size_t req_size, void **data_ptr, void **buffer_start, size_t *buffer_size) { int ret; @@ -35,7 +35,7 @@ int sink_get_buffer(struct sof_sink __sparse_cache *sink, size_t req_size, return ret; } -int sink_commit_buffer(struct sof_sink __sparse_cache *sink, size_t commit_size) +int sink_commit_buffer(struct sof_sink *sink, size_t commit_size) { int ret; @@ -56,47 +56,47 @@ int sink_commit_buffer(struct sof_sink __sparse_cache *sink, size_t commit_size) return ret; } -size_t sink_get_num_of_processed_bytes(struct sof_sink __sparse_cache *sink) +size_t sink_get_num_of_processed_bytes(struct sof_sink *sink) { return sink->num_of_bytes_processed; } -void sink_reset_num_of_processed_bytes(struct sof_sink __sparse_cache *sink) +void sink_reset_num_of_processed_bytes(struct sof_sink *sink) { sink->num_of_bytes_processed = 0; } -enum sof_ipc_frame sink_get_frm_fmt(struct sof_sink __sparse_cache *sink) +enum sof_ipc_frame sink_get_frm_fmt(struct sof_sink *sink) { return sink->audio_stream_params->frame_fmt; } -enum sof_ipc_frame sink_get_valid_fmt(struct sof_sink __sparse_cache *sink) +enum sof_ipc_frame sink_get_valid_fmt(struct sof_sink *sink) { return sink->audio_stream_params->valid_sample_fmt; } -uint32_t sink_get_rate(struct sof_sink __sparse_cache *sink) +uint32_t sink_get_rate(struct sof_sink *sink) { return sink->audio_stream_params->rate; } -uint32_t sink_get_channels(struct sof_sink __sparse_cache *sink) +uint32_t sink_get_channels(struct sof_sink *sink) { return sink->audio_stream_params->channels; } -uint32_t sink_get_buffer_fmt(struct sof_sink __sparse_cache *sink) +uint32_t sink_get_buffer_fmt(struct sof_sink *sink) { return sink->audio_stream_params->buffer_fmt; } -bool sink_get_overrun(struct sof_sink __sparse_cache *sink) +bool sink_get_overrun(struct sof_sink *sink) { return sink->audio_stream_params->overrun_permitted; } -int sink_set_frm_fmt(struct sof_sink __sparse_cache *sink, enum sof_ipc_frame frame_fmt) +int sink_set_frm_fmt(struct sof_sink *sink, enum sof_ipc_frame frame_fmt) { sink->audio_stream_params->frame_fmt = frame_fmt; @@ -106,7 +106,7 @@ int sink_set_frm_fmt(struct sof_sink __sparse_cache *sink, enum sof_ipc_frame fr return 0; } -int sink_set_valid_fmt(struct sof_sink __sparse_cache *sink, +int sink_set_valid_fmt(struct sof_sink *sink, enum sof_ipc_frame valid_sample_fmt) { sink->audio_stream_params->valid_sample_fmt = valid_sample_fmt; @@ -115,7 +115,7 @@ int sink_set_valid_fmt(struct sof_sink __sparse_cache *sink, return 0; } -int sink_set_rate(struct sof_sink __sparse_cache *sink, unsigned int rate) +int sink_set_rate(struct sof_sink *sink, unsigned int rate) { sink->audio_stream_params->rate = rate; if (sink->ops->on_audio_format_set) @@ -123,7 +123,7 @@ int sink_set_rate(struct sof_sink __sparse_cache *sink, unsigned int rate) return 0; } -int sink_set_channels(struct sof_sink __sparse_cache *sink, unsigned int channels) +int sink_set_channels(struct sof_sink *sink, unsigned int channels) { sink->audio_stream_params->channels = channels; if (sink->ops->on_audio_format_set) @@ -131,7 +131,7 @@ int sink_set_channels(struct sof_sink __sparse_cache *sink, unsigned int channel return 0; } -int sink_set_buffer_fmt(struct sof_sink __sparse_cache *sink, uint32_t buffer_fmt) +int sink_set_buffer_fmt(struct sof_sink *sink, uint32_t buffer_fmt) { sink->audio_stream_params->buffer_fmt = buffer_fmt; if (sink->ops->on_audio_format_set) @@ -139,7 +139,7 @@ int sink_set_buffer_fmt(struct sof_sink __sparse_cache *sink, uint32_t buffer_fm return 0; } -int sink_set_overrun(struct sof_sink __sparse_cache *sink, bool overrun_permitted) +int sink_set_overrun(struct sof_sink *sink, bool overrun_permitted) { sink->audio_stream_params->overrun_permitted = overrun_permitted; if (sink->ops->on_audio_format_set) @@ -147,19 +147,19 @@ int sink_set_overrun(struct sof_sink __sparse_cache *sink, bool overrun_permitte return 0; } -size_t sink_get_frame_bytes(struct sof_sink __sparse_cache *sink) +size_t sink_get_frame_bytes(struct sof_sink *sink) { return get_frame_bytes(sink_get_frm_fmt(sink), sink_get_channels(sink)); } -size_t sink_get_free_frames(struct sof_sink __sparse_cache *sink) +size_t sink_get_free_frames(struct sof_sink *sink) { return sink_get_free_size(sink) / sink_get_frame_bytes(sink); } -int sink_set_params(struct sof_sink __sparse_cache *sink, +int sink_set_params(struct sof_sink *sink, struct sof_ipc_stream_params *params, bool force_update) { if (sink->ops->audio_set_ipc_params) @@ -167,7 +167,7 @@ int sink_set_params(struct sof_sink __sparse_cache *sink, return 0; } -int sink_set_alignment_constants(struct sof_sink __sparse_cache *sink, +int sink_set_alignment_constants(struct sof_sink *sink, const uint32_t byte_align, const uint32_t frame_align_req) { @@ -176,12 +176,12 @@ int sink_set_alignment_constants(struct sof_sink __sparse_cache *sink, return 0; } -void sink_set_obs(struct sof_sink __sparse_cache *sink, size_t obs) +void sink_set_min_free_space(struct sof_sink *sink, size_t min_free_space) { - sink->obs = obs; + sink->min_free_space = min_free_space; } -size_t sink_get_obs(struct sof_sink __sparse_cache *sink) +size_t sink_get_min_free_space(struct sof_sink *sink) { - return sink->obs; + return sink->min_free_space; } diff --git a/src/audio/sink_source_utils.c b/src/audio/sink_source_utils.c index 671c1752d544..3b79c8c2d5e1 100644 --- a/src/audio/sink_source_utils.c +++ b/src/audio/sink_source_utils.c @@ -12,12 +12,12 @@ #include #include -int source_to_sink_copy(struct sof_source __sparse_cache *source, - struct sof_sink __sparse_cache *sink, bool free, size_t size) +int source_to_sink_copy(struct sof_source *source, + struct sof_sink *sink, bool free, size_t size) { - uint8_t *src_ptr; - uint8_t *src_begin; - uint8_t *src_end; + uint8_t const *src_ptr; + uint8_t const *src_begin; + uint8_t const *src_end; uint8_t *dst_ptr; uint8_t *dst_begin; uint8_t *dst_end; @@ -32,8 +32,8 @@ int source_to_sink_copy(struct sof_source __sparse_cache *source, return -ENOSPC; ret = source_get_data(source, size, - (void **)&src_ptr, - (void **)&src_begin, + (void const **)&src_ptr, + (void const **)&src_begin, &src_size); if (ret) return ret; diff --git a/src/audio/smart_amp/CMakeLists.txt b/src/audio/smart_amp/CMakeLists.txt index 89048004f16b..387381057804 100644 --- a/src/audio/smart_amp/CMakeLists.txt +++ b/src/audio/smart_amp/CMakeLists.txt @@ -10,4 +10,6 @@ else() sof_add_static_library(dsm ${CMAKE_CURRENT_LIST_DIR}/lib/release/dsm_lib/libdsm.a) endif() target_include_directories(sof PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include/dsm_api/inc) +else() +add_local_sources(sof smart_amp_passthru.c) endif() diff --git a/src/audio/smart_amp/Kconfig b/src/audio/smart_amp/Kconfig index 4cbbffbc51d2..02cc6fadc0c5 100644 --- a/src/audio/smart_amp/Kconfig +++ b/src/audio/smart_amp/Kconfig @@ -1,12 +1,30 @@ # SPDX-License-Identifier: BSD-3-Clause -menu "Smart amplifier solutions" - visible if COMP_SMART_AMP +if COMP_SMART_AMP + +choice + prompt "Smart Amplifier solution applied" + default PASSTHRU_AMP + help + The selection for Smart Amplifier component implementation + will depend on the Amplifier solution supplier. It is fair + to treat the supported solutions as mutually exclusive ones. + There should be no more than one solution selected per build + config. When Smart Amplifier is present but no solution is + supported, the passthrough mode will be applied as default. + + config PASSTHRU_AMP + bool "Stream Passthrough" + help + The default option as the passthrough mode while no other + solution is applied. While selected, the feed-forward input + frames will be passed to output after channel remapping. No + gain or latency will be produced. In the meanwhile, the + feedback input frames will be consumed but dropped directly. config MAXIM_DSM bool "Maxim DSM solution" select MAXIM_DSM_STUB if COMP_STUBS - default n help Select to apply Maxim DSM(Dynamic Speaker Management) solution for Smart Amplifier. As the third-party supply, the @@ -14,6 +32,8 @@ menu "Smart amplifier solutions" building the FW binary with this option enabled. The library itself should be statically linked with the SoF FW binary image. +endchoice + config MAXIM_DSM_STUB bool "Maxim DSM solution" depends on MAXIM_DSM @@ -22,5 +42,4 @@ menu "Smart amplifier solutions" Select to build the Maxim DSM adapter with a stub library. This should only be used for CI and testing. -endmenu - +endif diff --git a/src/audio/smart_amp/smart_amp.c b/src/audio/smart_amp/smart_amp.c index d0108aa346c7..ecf0e3a5d7ce 100644 --- a/src/audio/smart_amp/smart_amp.c +++ b/src/audio/smart_amp/smart_amp.c @@ -3,6 +3,12 @@ // Copyright(c) 2020 Maxim Integrated All rights reserved. // // Author: Ryan Lee +// +// Copyright(c) 2023 Google LLC. +// +// Author: Pin-chih Lin + +#include #include #include @@ -14,201 +20,151 @@ static const struct comp_driver comp_smart_amp; +#if CONFIG_MAXIM_DSM /* 0cd84e80-ebd3-11ea-adc1-0242ac120002 */ -DECLARE_SOF_RT_UUID("Maxim DSM", maxim_dsm_comp_uuid, 0x0cd84e80, 0xebd3, +DECLARE_SOF_RT_UUID("Maxim DSM", smart_amp_comp_uuid, 0x0cd84e80, 0xebd3, 0x11ea, 0xad, 0xc1, 0x02, 0x42, 0xac, 0x12, 0x00, 0x02); -DECLARE_TR_CTX(maxim_dsm_comp_tr, SOF_UUID(maxim_dsm_comp_uuid), +#else /* Passthrough */ +/* 64a794f0-55d3-4bca-9d5b-7b588badd037 */ +DECLARE_SOF_RT_UUID("Passthru Amp", smart_amp_comp_uuid, 0x64a794f0, 0x55d3, + 0x4bca, 0x9d, 0x5b, 0x7b, 0x58, 0x8b, 0xad, 0xd0, 0x37); + +#endif +DECLARE_TR_CTX(smart_amp_comp_tr, SOF_UUID(smart_amp_comp_uuid), LOG_LEVEL_INFO); /* Amp configuration & model calibration data for tuning/debug */ #define SOF_SMART_AMP_CONFIG 0 #define SOF_SMART_AMP_MODEL 1 -typedef int(*smart_amp_proc)(struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, uint32_t frames, - int8_t *chan_map, bool is_feedback); - struct smart_amp_data { struct sof_smart_amp_config config; struct comp_data_blob_handler *model_handler; struct comp_buffer *source_buf; /**< stream source buffer */ struct comp_buffer *feedback_buf; /**< feedback source buffer */ struct comp_buffer *sink_buf; /**< sink buffer */ - smart_amp_proc process; - uint32_t in_channels; - uint32_t out_channels; - /* module handle for speaker protection algorithm */ - struct smart_amp_mod_struct_t *mod_handle; + struct ipc_config_process ipc_config; + + smart_amp_src_func ff_get_frame; /**< function to get stream source */ + smart_amp_src_func fb_get_frame; /**< function to get feedback source */ + smart_amp_sink_func ff_set_frame; /**< function to set sink */ + struct smart_amp_mod_stream ff_mod; /**< feed-forward buffer for mod */ + struct smart_amp_mod_stream fb_mod; /**< feedback buffer for mod */ + struct smart_amp_mod_stream out_mod; /**< output buffer for mod */ + + struct smart_amp_buf mod_mems[MOD_MEMBLK_MAX]; /**< memory blocks for mod */ + + struct smart_amp_mod_data_base *mod_data; /**< inner model data */ }; -static inline void smart_amp_free_memory(struct smart_amp_data *sad, - struct comp_dev *dev) +/* smart_amp_free_mod_memories will be called promptly once getting error on + * internal functions. That is, it may be called multiple times by the hierarchical + * model when an error occurs in the lower function and propagates level-wise to + * the function on top. Always set the pointer to NULL after freed to avoid the + * double-freeing error. + */ +static inline void smart_amp_free_mod_memories(struct smart_amp_data *sad) { - struct smart_amp_mod_struct_t *hspk = sad->mod_handle; - - /* buffer : sof -> spk protection feed forward process */ - rfree(hspk->buf.frame_in); - /* buffer : sof <- spk protection feed forward process */ - rfree(hspk->buf.frame_out); - /* buffer : sof -> spk protection feedback process */ - rfree(hspk->buf.frame_iv); - /* buffer : feed forward process input */ - rfree(hspk->buf.input); - /* buffer : feed forward process output */ - rfree(hspk->buf.output); - /* buffer : feedback voltage */ - rfree(hspk->buf.voltage); - /* buffer : feedback current */ - rfree(hspk->buf.current); - /* buffer : feed forward variable length -> fixed length */ - rfree(hspk->buf.ff.buf); - /* buffer : feed forward variable length <- fixed length */ - rfree(hspk->buf.ff_out.buf); - /* buffer : feedback variable length -> fixed length */ - rfree(hspk->buf.fb.buf); - /* Module handle release */ - rfree(hspk); + /* sof -> mod feed-forward data re-mapping and format conversion */ + rfree(sad->ff_mod.buf.data); + sad->ff_mod.buf.data = NULL; + /* sof -> mod feedback data re-mapping and format conversion */ + rfree(sad->fb_mod.buf.data); + sad->fb_mod.buf.data = NULL; + /* mod -> sof processed data format conversion */ + rfree(sad->out_mod.buf.data); + sad->out_mod.buf.data = NULL; + + /* mem block for mod private data usage */ + rfree(sad->mod_mems[MOD_MEMBLK_PRIVATE].data); + sad->mod_mems[MOD_MEMBLK_PRIVATE].data = NULL; + /* mem block for mod audio frame data usage */ + rfree(sad->mod_mems[MOD_MEMBLK_FRAME].data); + sad->mod_mems[MOD_MEMBLK_FRAME].data = NULL; + /* mem block for mod parameter blob usage */ + rfree(sad->mod_mems[MOD_MEMBLK_PARAM].data); + sad->mod_mems[MOD_MEMBLK_PARAM].data = NULL; + + /* inner model data struct */ + rfree(sad->mod_data); + sad->mod_data = NULL; } -static inline int smart_amp_alloc_memory(struct smart_amp_data *sad, - struct comp_dev *dev) +static inline int smart_amp_buf_alloc(struct smart_amp_buf *buf, size_t size) { - struct smart_amp_mod_struct_t *hspk; - int mem_sz; - int size; - - /* memory allocation for module handle */ - mem_sz = sizeof(struct smart_amp_mod_struct_t); - sad->mod_handle = rballoc(0, SOF_MEM_CAPS_RAM, mem_sz); - if (!sad->mod_handle) - goto err; - memset(sad->mod_handle, 0, mem_sz); - - hspk = sad->mod_handle; + buf->data = rballoc(0, SOF_MEM_CAPS_RAM, size); + if (!buf->data) + return -ENOMEM; + buf->size = size; + return 0; +} - /* buffer : sof -> spk protection feed forward process */ - size = SMART_AMP_FF_BUF_DB_SZ * sizeof(int32_t); - hspk->buf.frame_in = rballoc(0, SOF_MEM_CAPS_RAM, size); - if (!hspk->buf.frame_in) - goto err; - mem_sz += size; +static ssize_t smart_amp_alloc_mod_memblk(struct smart_amp_data *sad, + enum smart_amp_mod_memblk blk) +{ + struct smart_amp_mod_data_base *mod = sad->mod_data; + int ret; + size_t size; - /* buffer : sof <- spk protection feed forward process */ - size = SMART_AMP_FF_BUF_DB_SZ * sizeof(int32_t); - hspk->buf.frame_out = rballoc(0, SOF_MEM_CAPS_RAM, size); - if (!hspk->buf.frame_out) - goto err; - mem_sz += size; + /* query the required size from inner model. */ + ret = mod->mod_ops->query_memblk_size(mod, blk); + if (ret <= 0) + goto error; - /* buffer : sof -> spk protection feedback process */ - size = SMART_AMP_FB_BUF_DB_SZ * sizeof(int32_t); - hspk->buf.frame_iv = rballoc(0, SOF_MEM_CAPS_RAM, size); - if (!hspk->buf.frame_iv) - goto err; - mem_sz += size; - - /* buffer : feed forward process input */ - size = DSM_FF_BUF_SZ * sizeof(int32_t); - hspk->buf.input = rballoc(0, SOF_MEM_CAPS_RAM, size); - if (!hspk->buf.input) - goto err; - mem_sz += size; - - /* buffer : feed forward process output */ - size = DSM_FF_BUF_SZ * sizeof(int32_t); - hspk->buf.output = rballoc(0, SOF_MEM_CAPS_RAM, size); - if (!hspk->buf.output) - goto err; - mem_sz += size; - - /* buffer : feedback voltage */ - size = DSM_FF_BUF_SZ * sizeof(int32_t); - hspk->buf.voltage = rballoc(0, SOF_MEM_CAPS_RAM, size); - if (!hspk->buf.voltage) - goto err; - mem_sz += size; - - /* buffer : feedback current */ - size = DSM_FF_BUF_SZ * sizeof(int32_t); - hspk->buf.current = rballoc(0, SOF_MEM_CAPS_RAM, size); - if (!hspk->buf.current) - goto err; - mem_sz += size; - - /* buffer : feed forward variable length -> fixed length */ - size = DSM_FF_BUF_DB_SZ * sizeof(int32_t); - hspk->buf.ff.buf = rballoc(0, SOF_MEM_CAPS_RAM, size); - if (!hspk->buf.ff.buf) - goto err; - mem_sz += size; - - /* buffer : feed forward variable length <- fixed length */ - size = DSM_FF_BUF_DB_SZ * sizeof(int32_t); - hspk->buf.ff_out.buf = rballoc(0, SOF_MEM_CAPS_RAM, size); - if (!hspk->buf.ff_out.buf) - goto err; - mem_sz += size; - - /* buffer : feedback variable length -> fixed length */ - size = DSM_FB_BUF_DB_SZ * sizeof(int32_t); - hspk->buf.fb.buf = rballoc(0, SOF_MEM_CAPS_RAM, size); - if (!hspk->buf.fb.buf) - goto err; - mem_sz += size; - - /* memory allocation of DSM handle */ - size = smart_amp_get_memory_size(hspk, dev); - hspk->dsmhandle = rballoc(0, SOF_MEM_CAPS_RAM, size); - if (!hspk->dsmhandle) - goto err; - memset(hspk->dsmhandle, 0, size); - mem_sz += size; - - comp_dbg(dev, "[DSM] module:%p (%d bytes used)", - hspk, mem_sz); + /* allocate the memory block when returned size > 0. */ + size = ret; + ret = smart_amp_buf_alloc(&sad->mod_mems[blk], size); + if (ret < 0) + goto error; - return 0; -err: - smart_amp_free_memory(sad, dev); - return -ENOMEM; -} + /* provide the memory block information to inner model. */ + ret = mod->mod_ops->set_memblk(mod, blk, &sad->mod_mems[blk]); + if (ret < 0) + goto error; -static void smart_amp_free_caldata(struct comp_dev *dev, - struct smart_amp_caldata *caldata) -{ - if (!caldata->data) - return; + return size; - rfree(caldata->data); - caldata->data = NULL; - caldata->data_size = 0; - caldata->data_pos = 0; +error: + smart_amp_free_mod_memories(sad); + return ret; } -static inline int smart_amp_alloc_caldata(struct comp_dev *dev, - struct smart_amp_caldata *caldata, - uint32_t size) +static int smart_amp_alloc_data_buffers(struct comp_dev *dev, + struct smart_amp_data *sad) { - smart_amp_free_caldata(dev, caldata); - - if (!size) - return 0; + size_t total_size; + int ret; + size_t size; - caldata->data = rballoc(0, SOF_MEM_CAPS_RAM, size); + /* sof -> mod feed-forward data re-mapping and format conversion */ + size = SMART_AMP_FF_BUF_DB_SZ * sizeof(int32_t); + ret = smart_amp_buf_alloc(&sad->ff_mod.buf, size); + if (ret < 0) + goto error; + total_size = size; - if (!caldata->data) { - comp_err(dev, "smart_amp_alloc_caldata(): model->data rballoc failed"); - return -ENOMEM; - } + /* sof -> mod feedback data re-mapping and format conversion */ + size = SMART_AMP_FB_BUF_DB_SZ * sizeof(int32_t); + ret = smart_amp_buf_alloc(&sad->fb_mod.buf, size); + if (ret < 0) + goto error; + total_size += size; - bzero(caldata->data, size); - caldata->data_size = size; - caldata->data_pos = 0; + /* mod -> sof processed data format conversion */ + size = SMART_AMP_FF_BUF_DB_SZ * sizeof(int32_t); + ret = smart_amp_buf_alloc(&sad->out_mod.buf, size); + if (ret < 0) + goto error; + total_size += size; + comp_dbg(dev, "smart_amp_alloc(): used data buffer %zu bytes", total_size); return 0; + +error: + smart_amp_free_mod_memories(sad); + return ret; } static struct comp_dev *smart_amp_new(const struct comp_driver *drv, @@ -220,7 +176,6 @@ static struct comp_dev *smart_amp_new(const struct comp_driver *drv, struct smart_amp_data *sad; struct sof_smart_amp_config *cfg; size_t bs; - int sz_caldata; int ret; dev = comp_alloc(drv, sizeof(*dev)); @@ -248,39 +203,57 @@ static struct comp_dev *smart_amp_new(const struct comp_driver *drv, memcpy_s(&sad->config, sizeof(struct sof_smart_amp_config), cfg, bs); - if (smart_amp_alloc_memory(sad, dev) != 0) + /* allocate inner model data struct */ + sad->mod_data = mod_data_create(dev); + if (!sad->mod_data) { + comp_err(dev, "smart_amp_new(): failed to allocate nner model data"); goto error; + } - /* Bitwidth information is not available. Use 16bit as default. - * Re-initialize in the prepare function if ncessary - */ - sad->mod_handle->bitwidth = 16; - if (smart_amp_init(sad->mod_handle, dev)) + /* allocate stream buffers for mod */ + ret = smart_amp_alloc_data_buffers(dev, sad); + if (ret) { + comp_err(dev, "smart_amp_new(): failed to allocate data buffers, ret:%d", ret); goto error; + } - /* Get the max. number of parameter to allocate memory for model data */ - sad->mod_handle->param.max_param = - smart_amp_get_num_param(sad->mod_handle, dev); - sz_caldata = sad->mod_handle->param.max_param * DSM_SINGLE_PARAM_SZ; + /* (before init) allocate mem block for mod private data usage */ + ret = smart_amp_alloc_mod_memblk(sad, MOD_MEMBLK_PRIVATE); + if (ret < 0) { + comp_err(dev, "smart_amp_new(): failed to allocate mod private, ret:%d", ret); + goto error; + } + comp_dbg(dev, "smart_amp_new(): used mod private buffer %d bytes", ret); - if (sz_caldata > 0) { - ret = smart_amp_alloc_caldata(dev, &sad->mod_handle->param.caldata, - sz_caldata * sizeof(int32_t)); - if (ret < 0) { - comp_err(dev, "smart_amp_new(): caldata initial failed"); - goto error; - } + /* init model */ + ret = sad->mod_data->mod_ops->init(sad->mod_data); + if (ret) { + comp_err(dev, "smart_amp_new(): failed to init inner model, ret:%d", ret); + goto error; } - /* update full parameter values */ - if (smart_amp_get_all_param(sad->mod_handle, dev) < 0) + /* (after init) allocate mem block for mod audio frame data usage */ + ret = smart_amp_alloc_mod_memblk(sad, MOD_MEMBLK_FRAME); + if (ret < 0) { + comp_err(dev, "smart_amp_new(): failed to allocate mod buffer, ret:%d", ret); goto error; + } + comp_dbg(dev, "smart_amp_new(): used mod data buffer %d bytes", ret); + + /* (after init) allocate mem block for mod parameter blob usage */ + ret = smart_amp_alloc_mod_memblk(sad, MOD_MEMBLK_PARAM); + if (ret < 0) { + comp_err(dev, "smart_amp_new(): failed to allocate mod config, ret:%d", ret); + goto error; + } + comp_dbg(dev, "smart_amp_new(): used mod config buffer %d bytes", ret); dev->state = COMP_STATE_READY; return dev; error: + smart_amp_free_mod_memories(sad); rfree(sad); rfree(dev); return NULL; @@ -295,14 +268,14 @@ static int smart_amp_set_config(struct comp_dev *dev, /* Copy new config, find size from header */ cfg = (struct sof_smart_amp_config *) - ASSUME_ALIGNED(&cdata->data->data, sizeof(uint32_t)); + ASSUME_ALIGNED(&cdata->data->data, sizeof(uint32_t)); bs = cfg->size; - comp_dbg(dev, "smart_amp_set_config(), actual blob size = %u, expected blob size = %u", + comp_dbg(dev, "smart_amp_set_config(), actual blob size = %zu, expected blob size = %zu", bs, sizeof(struct sof_smart_amp_config)); if (bs != sizeof(struct sof_smart_amp_config)) { - comp_err(dev, "smart_amp_set_config(): invalid blob size, actual blob size = %u, expected blob size = %u", + comp_err(dev, "smart_amp_set_config(): invalid blob size, actual blob size = %zu, expected blob size = %zu", bs, sizeof(struct sof_smart_amp_config)); return -EINVAL; } @@ -323,7 +296,7 @@ static int smart_amp_get_config(struct comp_dev *dev, /* Copy back to user space */ bs = sad->config.size; - comp_dbg(dev, "smart_amp_get_config(), actual blob size = %u, expected blob size = %u", + comp_dbg(dev, "smart_amp_get_config(), actual blob size = %zu, expected blob size = %zu", bs, sizeof(struct sof_smart_amp_config)); if (bs == 0 || bs > size) @@ -343,18 +316,20 @@ static int smart_amp_ctrl_get_bin_data(struct comp_dev *dev, int size) { struct smart_amp_data *sad = comp_get_drvdata(dev); + struct smart_amp_mod_data_base *mod; int ret = 0; assert(sad); + mod = sad->mod_data; switch (cdata->data->type) { case SOF_SMART_AMP_CONFIG: ret = smart_amp_get_config(dev, cdata, size); break; case SOF_SMART_AMP_MODEL: - ret = maxim_dsm_get_param(sad->mod_handle, dev, cdata, size); + ret = mod->mod_ops->get_config(mod, cdata, size); if (ret < 0) { - comp_err(dev, "smart_amp_ctrl_get_bin_data(): parameter read error!"); + comp_err(dev, "smart_amp_ctrl_get_bin_data(): failed to read inner model!"); return ret; } break; @@ -389,9 +364,11 @@ static int smart_amp_ctrl_set_bin_data(struct comp_dev *dev, struct sof_ipc_ctrl_data *cdata) { struct smart_amp_data *sad = comp_get_drvdata(dev); + struct smart_amp_mod_data_base *mod; int ret = 0; assert(sad); + mod = sad->mod_data; if (dev->state < COMP_STATE_READY) { comp_err(dev, "smart_amp_ctrl_set_bin_data(): driver in init!"); @@ -403,9 +380,9 @@ static int smart_amp_ctrl_set_bin_data(struct comp_dev *dev, ret = smart_amp_set_config(dev, cdata); break; case SOF_SMART_AMP_MODEL: - ret = maxim_dsm_set_param(sad->mod_handle, dev, cdata); + ret = mod->mod_ops->set_config(mod, cdata); if (ret < 0) { - comp_err(dev, "smart_amp_ctrl_set_bin_data(): parameter write error!"); + comp_err(dev, "smart_amp_ctrl_set_bin_data(): failed to write inner model!"); return ret; } break; @@ -466,11 +443,12 @@ static void smart_amp_free(struct comp_dev *dev) comp_dbg(dev, "smart_amp_free()"); - smart_amp_free_caldata(dev, &sad->mod_handle->param.caldata); - smart_amp_free_memory(sad, dev); + smart_amp_free_mod_memories(sad); rfree(sad); + sad = NULL; rfree(dev); + dev = NULL; } static int smart_amp_verify_params(struct comp_dev *dev, @@ -518,9 +496,7 @@ static int smart_amp_trigger(struct comp_dev *dev, int cmd) case COMP_TRIGGER_START: case COMP_TRIGGER_RELEASE: if (sad->feedback_buf) { - struct comp_buffer __sparse_cache *buf = buffer_acquire(sad->feedback_buf); - buffer_zero(buf); - buffer_release(buf); + buffer_zero(sad->feedback_buf); } break; case COMP_TRIGGER_PAUSE: @@ -533,52 +509,79 @@ static int smart_amp_trigger(struct comp_dev *dev, int cmd) return ret; } -static int smart_amp_process(struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, - uint32_t frames, int8_t *chan_map, - bool is_feedback) +static int smart_amp_ff_process(struct comp_dev *dev, + const struct audio_stream *source, + const struct audio_stream *sink, + uint32_t frames, const int8_t *chan_map) { struct smart_amp_data *sad = comp_get_drvdata(dev); + struct smart_amp_mod_data_base *mod = sad->mod_data; int ret; - if (!is_feedback) - ret = smart_amp_ff_copy(dev, frames, - source, sink, - chan_map, sad->mod_handle, - sad->in_channels, sad->out_channels); - else - ret = smart_amp_fb_copy(dev, frames, - source, sink, - chan_map, sad->mod_handle, - audio_stream_get_channels(source)); - return ret; + sad->ff_mod.consumed = 0; + sad->out_mod.produced = 0; + + if (frames == 0) { + comp_warn(dev, "smart_amp_copy(): feed forward frame size zero warning."); + return 0; + } + + if (frames > SMART_AMP_FF_BUF_DB_SZ) { + comp_err(dev, "smart_amp_copy(): feed forward frame size overflow: %u", frames); + sad->ff_mod.consumed = frames; + return -EINVAL; + } + + sad->ff_get_frame(&sad->ff_mod, frames, source, chan_map); + + ret = mod->mod_ops->ff_proc(mod, frames, &sad->ff_mod, &sad->out_mod); + if (ret) { + comp_err(dev, "smart_amp_copy(): feed forward inner model process error"); + return ret; + } + + sad->ff_set_frame(&sad->out_mod, sad->out_mod.produced, sink); + + return 0; } -static smart_amp_proc get_smart_amp_process(struct comp_dev *dev) +static int smart_amp_fb_process(struct comp_dev *dev, + const struct audio_stream *source, + uint32_t frames, const int8_t *chan_map) { struct smart_amp_data *sad = comp_get_drvdata(dev); - struct comp_buffer __sparse_cache *source_buf = buffer_acquire(sad->source_buf); - enum sof_ipc_frame fmt = audio_stream_get_frm_fmt(&source_buf->stream); + struct smart_amp_mod_data_base *mod = sad->mod_data; + int ret; - buffer_release(source_buf); + sad->fb_mod.consumed = 0; - switch (fmt) { - case SOF_IPC_FRAME_S16_LE: - case SOF_IPC_FRAME_S24_4LE: - case SOF_IPC_FRAME_S32_LE: - return smart_amp_process; - default: - comp_err(dev, "smart_amp_process() error: not supported frame format"); - return NULL; + if (frames == 0) { + comp_warn(dev, "smart_amp_copy(): feedback frame size zero warning."); + return 0; } + + if (frames > SMART_AMP_FB_BUF_DB_SZ) { + comp_err(dev, "smart_amp_copy(): feedback frame size overflow: %u", frames); + sad->fb_mod.consumed = frames; + return -EINVAL; + } + + sad->fb_get_frame(&sad->fb_mod, frames, source, chan_map); + + ret = mod->mod_ops->fb_proc(mod, frames, &sad->fb_mod); + if (ret) { + comp_err(dev, "smart_amp_copy(): feedback inner model process error"); + return ret; + } + + return 0; } static int smart_amp_copy(struct comp_dev *dev) { struct smart_amp_data *sad = comp_get_drvdata(dev); - struct comp_buffer __sparse_cache *source_buf = buffer_acquire(sad->source_buf); - struct comp_buffer __sparse_cache *sink_buf = buffer_acquire(sad->sink_buf); + struct comp_buffer *source_buf = sad->source_buf; + struct comp_buffer *sink_buf = sad->sink_buf; uint32_t avail_passthrough_frames; uint32_t avail_feedback_frames; uint32_t avail_frames; @@ -595,7 +598,7 @@ static int smart_amp_copy(struct comp_dev *dev) avail_frames = avail_passthrough_frames; if (sad->feedback_buf) { - struct comp_buffer __sparse_cache *feedback_buf = buffer_acquire(sad->feedback_buf); + struct comp_buffer *feedback_buf = sad->feedback_buf; if (comp_get_state(dev, feedback_buf->source) == dev->state) { /* feedback */ @@ -608,63 +611,124 @@ static int smart_amp_copy(struct comp_dev *dev) feedback_bytes = avail_feedback_frames * audio_stream_frame_bytes(&feedback_buf->stream); - comp_dbg(dev, "smart_amp_copy(): processing %d feedback frames (avail_passthrough_frames: %d)", + comp_dbg(dev, "smart_amp_copy(): processing %u feedback frames (avail_passthrough_frames: %u)", avail_feedback_frames, avail_passthrough_frames); /* perform buffer writeback after source_buf process */ buffer_stream_invalidate(feedback_buf, feedback_bytes); - sad->process(dev, &feedback_buf->stream, - &sink_buf->stream, avail_feedback_frames, - sad->config.feedback_ch_map, true); + smart_amp_fb_process(dev, &feedback_buf->stream, + avail_feedback_frames, + sad->config.feedback_ch_map); + + comp_dbg(dev, "smart_amp_copy(): consumed %u feedback frames", + sad->fb_mod.consumed); + if (sad->fb_mod.consumed < avail_feedback_frames) { + feedback_bytes = sad->fb_mod.consumed * + audio_stream_frame_bytes(&feedback_buf->stream); + } comp_update_buffer_consume(feedback_buf, feedback_bytes); } - - buffer_release(feedback_buf); } - /* bytes calculation */ + /* process data */ source_bytes = avail_frames * audio_stream_frame_bytes(&source_buf->stream); - sink_bytes = avail_frames * audio_stream_frame_bytes(&sink_buf->stream); - /* process data */ buffer_stream_invalidate(source_buf, source_bytes); - sad->process(dev, &source_buf->stream, &sink_buf->stream, - avail_frames, sad->config.source_ch_map, false); + smart_amp_ff_process(dev, &source_buf->stream, &sink_buf->stream, + avail_frames, sad->config.source_ch_map); + + comp_dbg(dev, "smart_amp_copy(): processing %u feed forward frames (consumed: %u, produced: %u)", + avail_frames, sad->ff_mod.consumed, sad->out_mod.produced); + if (sad->ff_mod.consumed < avail_frames) + source_bytes = sad->ff_mod.consumed * audio_stream_frame_bytes(&source_buf->stream); + + sink_bytes = sad->out_mod.produced * audio_stream_frame_bytes(&sink_buf->stream); buffer_stream_writeback(sink_buf, sink_bytes); /* source/sink buffer pointers update */ comp_update_buffer_consume(source_buf, source_bytes); comp_update_buffer_produce(sink_buf, sink_bytes); - buffer_release(sink_buf); - buffer_release(source_buf); - return 0; } static int smart_amp_reset(struct comp_dev *dev) { struct smart_amp_data *sad = comp_get_drvdata(dev); + struct smart_amp_mod_data_base *mod = sad->mod_data; + int ret; comp_dbg(dev, "smart_amp_reset()"); - sad->process = NULL; - sad->in_channels = 0; - sad->out_channels = 0; + sad->ff_get_frame = NULL; + sad->fb_get_frame = NULL; + sad->ff_set_frame = NULL; + + /* reset inner model */ + ret = mod->mod_ops->reset(mod); + if (ret) + return ret; comp_set_state(dev, COMP_TRIGGER_RESET); return 0; } +/* supported formats: {SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE} + * which are enumerated as 0, 1, and 2. Simply check if supported while fmt <= 2. + */ +static inline bool is_supported_fmt(uint16_t fmt) +{ + return fmt <= SOF_IPC_FRAME_S32_LE; +} + +static int smart_amp_resolve_mod_fmt(struct comp_dev *dev, uint32_t least_req_depth) +{ + struct smart_amp_data *sad = comp_get_drvdata(dev); + struct smart_amp_mod_data_base *mod = sad->mod_data; + const uint16_t *mod_fmts; + int num_mod_fmts; + int ret; + int i; + + /* get supported formats from mod */ + ret = mod->mod_ops->get_supported_fmts(mod, &mod_fmts, &num_mod_fmts); + if (ret) { + comp_err(dev, "smart_amp_resolve_mod_fmt(): failed to get supported formats"); + return ret; + } + + for (i = 0; i < num_mod_fmts; i++) { + if (get_sample_bitdepth(mod_fmts[i]) >= least_req_depth && + is_supported_fmt(mod_fmts[i])) { + /* set frame format to inner model */ + comp_dbg(dev, "smart_amp_resolve_mod_fmt(): set mod format to %u", + mod_fmts[i]); + ret = mod->mod_ops->set_fmt(mod, mod_fmts[i]); + if (ret) { + comp_err(dev, + "smart_amp_resolve_mod_fmt(): failed setting format %u", + mod_fmts[i]); + return ret; + } + /* return the resolved format for later settings. */ + return mod_fmts[i]; + } + } + + comp_err(dev, "smart_amp_resolve_mod_fmt(): failed to resolve the frame format for mod"); + return -EINVAL; +} + static int smart_amp_prepare(struct comp_dev *dev) { struct smart_amp_data *sad = comp_get_drvdata(dev); - struct comp_buffer __sparse_cache *source_c, *buf_c; struct list_item *blist; + uint16_t ff_src_fmt, fb_src_fmt, resolved_mod_fmt; + uint32_t least_req_depth; + uint32_t rate; int ret; - int bitwidth; comp_dbg(dev, "smart_amp_prepare()"); @@ -676,91 +740,76 @@ static int smart_amp_prepare(struct comp_dev *dev) list_for_item(blist, &dev->bsource_list) { struct comp_buffer *source_buffer = container_of(blist, struct comp_buffer, sink_list); - source_c = buffer_acquire(source_buffer); - if (source_c->source->ipc_config.type == SOF_COMP_DEMUX) { + if (source_buffer->source->ipc_config.type == SOF_COMP_DEMUX) { sad->feedback_buf = source_buffer; } else { sad->source_buf = source_buffer; - sad->in_channels = audio_stream_get_channels(&source_c->stream); + sad->in_channels = audio_stream_get_channels(&source_buffer->stream); } - - buffer_release(source_c); } + /* sink buffer */ sad->sink_buf = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - buf_c = buffer_acquire(sad->sink_buf); - sad->out_channels = audio_stream_get_channels(&buf_c->stream); - buffer_release(buf_c); - - source_c = buffer_acquire(sad->source_buf); + /* get frame format and channels param of stream and feedback source */ + ff_src_fmt = audio_stream_get_frm_fmt(&sad->source_buf->stream); + sad->ff_mod.channels = MIN(SMART_AMP_FF_MAX_CH_NUM, + audio_stream_get_channels(&sad->source_buf->stream)); + sad->out_mod.channels = sad->ff_mod.channels; + /* the least bitdepth required for inner model, which should not be lower than the bitdepth + * for input samples of feed-forward, and feedback if exists. + */ + least_req_depth = get_sample_bitdepth(ff_src_fmt); if (sad->feedback_buf) { - buf_c = buffer_acquire(sad->feedback_buf); - - audio_stream_set_channels(&buf_c->stream, sad->config.feedback_channels); - audio_stream_set_rate(&buf_c->stream, audio_stream_get_rate(&source_c->stream)); - buffer_release(buf_c); - - ret = smart_amp_check_audio_fmt(audio_stream_get_rate(&source_c->stream), - audio_stream_get_channels(&source_c->stream)); - if (ret) { - comp_err(dev, "[DSM] Format not supported, sample rate: %d, ch: %d", - audio_stream_get_rate(&source_c->stream), - audio_stream_get_channels(&source_c->stream)); - goto error; - } + /* forward set channels and rate param to feedback source */ + audio_stream_set_channels(&sad->feedback_buf->stream, + sad->config.feedback_channels); + audio_stream_set_rate(&sad->feedback_buf->stream, + audio_stream_get_rate(&sad->source_buf->stream)); + fb_src_fmt = audio_stream_get_frm_fmt(&sad->feedback_buf->stream); + sad->fb_mod.channels = MIN(SMART_AMP_FB_MAX_CH_NUM, + audio_stream_get_channels(&sad->feedback_buf->stream)); + + least_req_depth = MAX(least_req_depth, get_sample_bitdepth(fb_src_fmt)); } - switch (audio_stream_get_frm_fmt(&source_c->stream)) { - case SOF_IPC_FRAME_S16_LE: - bitwidth = 16; - break; - case SOF_IPC_FRAME_S24_4LE: - bitwidth = 24; - break; - case SOF_IPC_FRAME_S32_LE: - bitwidth = 32; - break; - default: - comp_err(dev, "[DSM] smart_amp_process() error: not supported frame format %d", - audio_stream_get_frm_fmt(&source_c->stream)); - goto error; - } + /* resolve the frame format for inner model. The return value will be the applied format + * or the negative error code. + */ + ret = smart_amp_resolve_mod_fmt(dev, least_req_depth); + if (ret < 0) + return ret; - sad->mod_handle->bitwidth = bitwidth; - comp_info(dev, "[DSM] Re-initialized for %d bit processing", bitwidth); + resolved_mod_fmt = ret; - ret = smart_amp_init(sad->mod_handle, dev); - if (ret) { - comp_err(dev, "[DSM] Re-initialization error."); - goto error; - } - ret = maxim_dsm_restore_param(sad->mod_handle, dev); - if (ret) { - comp_err(dev, "[DSM] Restoration error."); - goto error; - } + /* set format to mod buffers and get the corresponding src/sink function of channel + * remapping and format conversion. + */ + sad->ff_mod.frame_fmt = resolved_mod_fmt; + sad->out_mod.frame_fmt = resolved_mod_fmt; + sad->ff_get_frame = smart_amp_get_src_func(ff_src_fmt, sad->ff_mod.frame_fmt); + sad->ff_set_frame = smart_amp_get_sink_func(ff_src_fmt, sad->out_mod.frame_fmt); + comp_dbg(dev, "smart_amp_prepare(): ff mod buffer channels:%u fmt_conv:%u -> %u", + sad->ff_mod.channels, ff_src_fmt, sad->ff_mod.frame_fmt); + comp_dbg(dev, "smart_amp_prepare(): output mod buffer channels:%u fmt_conv:%u -> %u", + sad->out_mod.channels, sad->out_mod.frame_fmt, ff_src_fmt); - sad->process = get_smart_amp_process(dev); - if (!sad->process) { - comp_err(dev, "smart_amp_prepare(): get_smart_amp_process failed"); - ret = -EINVAL; + if (sad->feedback_buf) { + sad->fb_mod.frame_fmt = resolved_mod_fmt; + sad->fb_get_frame = smart_amp_get_src_func(fb_src_fmt, sad->fb_mod.frame_fmt); + comp_dbg(dev, "smart_amp_prepare(): fb mod buffer channels:%u fmt_conv:%u -> %u", + sad->fb_mod.channels, fb_src_fmt, sad->fb_mod.frame_fmt); } - -error: - buffer_release(source_c); - - smart_amp_flush(sad->mod_handle, dev); - return ret; + return 0; } static const struct comp_driver comp_smart_amp = { .type = SOF_COMP_SMART_AMP, - .uid = SOF_RT_UUID(maxim_dsm_comp_uuid), - .tctx = &maxim_dsm_comp_tr, + .uid = SOF_RT_UUID(smart_amp_comp_uuid), + .tctx = &smart_amp_comp_tr, .ops = { .create = smart_amp_new, .free = smart_amp_free, diff --git a/src/audio/smart_amp/smart_amp_generic.c b/src/audio/smart_amp/smart_amp_generic.c index 3ad4c1ce28de..5f6a1698d16b 100644 --- a/src/audio/smart_amp/smart_amp_generic.c +++ b/src/audio/smart_amp/smart_amp_generic.c @@ -3,200 +3,357 @@ // Copyright(c) 2020 Maxim Integrated All rights reserved. // // Author: Ryan Lee +// +// Copyright(c) 2023 Google LLC. +// +// Author: Pin-chih Lin #include #include #include #include -#ifdef CONFIG_GENERIC - -static int32_t smart_amp_ff_generic(int32_t x) +static void remap_s32_to_s32(struct smart_amp_mod_stream *src_mod, uint32_t frames, + const struct audio_stream __sparse_cache *src, + const int8_t *chan_map) { - /* Add speaker protection feed forward process here */ - return x; + int num_samples_remaining; + int nmax, n, ch, i; + int n_mod = 0; + int src_ch = audio_stream_get_channels(src); + int32_t *src_ptr_base = audio_stream_get_rptr(src); + int32_t *mod_ptr_base = (int32_t *)src_mod->buf.data; + int32_t *src_ptr; + int32_t *mod_ptr; + + /* clean up dst buffer to make sure all 0s on the unmapped channel */ + bzero(mod_ptr_base, src_mod->buf.size); + + num_samples_remaining = frames * src_ch; + while (num_samples_remaining) { + nmax = audio_stream_samples_without_wrap_s32(src, src_ptr_base); + n = MIN(num_samples_remaining, nmax); + + for (ch = 0; ch < src_mod->channels; ch++) { + if (chan_map[ch] == -1) + continue; + + mod_ptr = mod_ptr_base + ch; + src_ptr = src_ptr_base + chan_map[ch]; + n_mod = 0; + for (i = 0; i < n; i += src_ch) { + *mod_ptr = *src_ptr; + mod_ptr += src_mod->channels; + src_ptr += src_ch; + n_mod += src_mod->channels; + } + } + /* update base pointers by forwarding (n / src_ch) frames */ + mod_ptr_base += n_mod; + src_ptr_base += n; + + num_samples_remaining -= n; + src_ptr_base = audio_stream_wrap(src, src_ptr_base); + } } -static void smart_amp_fb_generic(int32_t x) +static void remap_s24_to_s24(struct smart_amp_mod_stream *src_mod, uint32_t frames, + const struct audio_stream __sparse_cache *src, + const int8_t *chan_map) { - /* Add speaker protection feedback process here */ + remap_s32_to_s32(src_mod, frames, src, chan_map); } -#if CONFIG_FORMAT_S16LE -static void smart_amp_s16_ff_default(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *feedback, - uint32_t frames) -{ - int16_t *x; - int16_t *y; - int32_t tmp; - int idx; - int ch; +static void remap_s24_to_s32(struct smart_amp_mod_stream *src_mod, uint32_t frames, + const struct audio_stream __sparse_cache *src, + const int8_t *chan_map) +{ int i; - int nch = audio_stream_get_channels(source); - - for (ch = 0; ch < nch; ch++) { - idx = ch; - for (i = 0; i < frames; i++) { - x = audio_stream_read_frag_s16(source, idx); - y = audio_stream_read_frag_s16(sink, idx); - tmp = smart_amp_ff_generic(*x << 16); - *y = sat_int16(Q_SHIFT_RND(tmp, 31, 15)); - idx += nch; - } + int n_mod = frames * src_mod->channels; + int32_t *mod_ptr = (int32_t *)src_mod->buf.data; + + remap_s32_to_s32(src_mod, frames, src, chan_map); + + /* one loop for in-place lshift (s24-to-s32) after remapping */ + for (i = 0; i < n_mod; i++) { + *mod_ptr = *mod_ptr << 8; + mod_ptr++; } } -#endif /* CONFIG_FORMAT_S16LE */ -#if CONFIG_FORMAT_S24LE -static void smart_amp_s24_ff_default(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *feedback, - uint32_t frames) -{ - int32_t *x; - int32_t *y; - int32_t tmp; - int idx; - int ch; - int i; - int nch = audio_stream_get_channels(source); - - for (ch = 0; ch < nch; ch++) { - idx = ch; - for (i = 0; i < frames; i++) { - x = audio_stream_read_frag_s32(source, idx); - y = audio_stream_read_frag_s32(sink, idx); - tmp = smart_amp_ff_generic(*x << 8); - *y = sat_int24(Q_SHIFT_RND(tmp, 31, 23)); - idx += nch; +static void remap_s16_to_s16(struct smart_amp_mod_stream *src_mod, uint32_t frames, + const struct audio_stream __sparse_cache *src, + const int8_t *chan_map) +{ + int num_samples_remaining; + int nmax, n, ch, i; + int n_mod = 0; + int src_ch = audio_stream_get_channels(src); + int16_t *src_ptr_base = audio_stream_get_rptr(src); + int16_t *mod_ptr_base = (int16_t *)src_mod->buf.data; + int16_t *src_ptr; + int16_t *mod_ptr; + + /* clean up mod buffer (dst) to keep all-0 data on the unmapped channel */ + bzero(mod_ptr_base, src_mod->buf.size); + + num_samples_remaining = frames * src_ch; + while (num_samples_remaining) { + nmax = audio_stream_samples_without_wrap_s16(src, src_ptr_base); + n = MIN(num_samples_remaining, nmax); + + for (ch = 0; ch < src_mod->channels; ch++) { + if (chan_map[ch] == -1) + continue; + + mod_ptr = mod_ptr_base + ch; + src_ptr = src_ptr_base + chan_map[ch]; + n_mod = 0; + for (i = 0; i < n; i += src_ch) { + *mod_ptr = *src_ptr; + mod_ptr += src_mod->channels; + src_ptr += src_ch; + n_mod += src_mod->channels; + } } + /* update base pointers by forwarding (n / src_ch) frames */ + mod_ptr_base += n_mod; + src_ptr_base += n; + + num_samples_remaining -= n; + src_ptr_base = audio_stream_wrap(src, src_ptr_base); } } -#endif /* CONFIG_FORMAT_S24LE */ -#if CONFIG_FORMAT_S32LE -static void smart_amp_s32_ff_default(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *feedback, - uint32_t frames) -{ - int32_t *x; - int32_t *y; - int idx; - int ch; - int i; - int nch = audio_stream_get_channels(source); - - for (ch = 0; ch < nch; ch++) { - idx = ch; - for (i = 0; i < frames; i++) { - x = audio_stream_read_frag_s32(source, idx); - y = audio_stream_read_frag_s32(sink, idx); - *y = smart_amp_ff_generic(*x); - idx += nch; +static void remap_s16_to_b32(struct smart_amp_mod_stream *src_mod, uint32_t frames, + const struct audio_stream __sparse_cache *src, + const int8_t *chan_map, int lshift) +{ + int num_samples_remaining; + int nmax, n, ch, i; + int n_mod = 0; + int src_ch = audio_stream_get_channels(src); + int16_t *src_ptr_base = audio_stream_get_rptr(src); + int32_t *mod_ptr_base = (int32_t *)src_mod->buf.data; + int16_t *src_ptr; + int32_t *mod_ptr; + + /* clean up dst buffer to make sure all 0s on the unmapped channel */ + bzero(mod_ptr_base, src_mod->buf.size); + + num_samples_remaining = frames * src_ch; + while (num_samples_remaining) { + nmax = audio_stream_samples_without_wrap_s16(src, src_ptr_base); + n = MIN(num_samples_remaining, nmax); + + for (ch = 0; ch < src_mod->channels; ch++) { + if (chan_map[ch] == -1) + continue; + + mod_ptr = mod_ptr_base + ch; + src_ptr = src_ptr_base + chan_map[ch]; + n_mod = 0; + for (i = 0; i < n; i += src_ch) { + *mod_ptr = (int32_t)*src_ptr << lshift; + mod_ptr += src_mod->channels; + src_ptr += src_ch; + n_mod += src_mod->channels; + } } + /* update base pointers by forwarding (n / src_ch) frames */ + mod_ptr_base += n_mod; + src_ptr_base += n; + + num_samples_remaining -= n; + src_ptr_base = audio_stream_wrap(src, src_ptr_base); } } -#endif /* CONFIG_FORMAT_S32LE */ -#if CONFIG_FORMAT_S16LE -static void smart_amp_s16_fb_default(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *feedback, - uint32_t frames) -{ - int16_t *x; - int idx; - int ch; - int i; - int nch = audio_stream_get_channels(source); - - for (ch = 0; ch < nch; ch++) { - idx = ch; - for (i = 0; i < frames; i++) { - x = audio_stream_read_frag_s16(feedback, idx); - smart_amp_fb_generic(*x << 16); - idx += nch; +static void remap_s16_to_s24(struct smart_amp_mod_stream *src_mod, uint32_t frames, + const struct audio_stream __sparse_cache *src, + const int8_t *chan_map) +{ + remap_s16_to_b32(src_mod, frames, src, chan_map, 8 /* lshift */); +} + +static void remap_s16_to_s32(struct smart_amp_mod_stream *src_mod, uint32_t frames, + const struct audio_stream __sparse_cache *src, + const int8_t *chan_map) +{ + remap_s16_to_b32(src_mod, frames, src, chan_map, 16 /* lshift */); +} + +static void feed_s32_to_s32(const struct smart_amp_mod_stream *sink_mod, uint32_t frames, + const struct audio_stream __sparse_cache *sink) +{ + int num_samples_remaining; + int nmax, n, ch, i; + int sink_ch = audio_stream_get_channels(sink); + int feed_channels = MIN(sink_ch, sink_mod->channels); + int32_t *sink_ptr = audio_stream_get_wptr(sink); + int32_t *mod_ptr = (int32_t *)sink_mod->buf.data; + + num_samples_remaining = frames * sink_ch; + while (num_samples_remaining) { + nmax = audio_stream_samples_without_wrap_s32(sink, sink_ptr); + n = MIN(num_samples_remaining, nmax); + + for (i = 0; i < n; i += sink_ch) { + for (ch = 0; ch < feed_channels; ch++) + *(sink_ptr + ch) = *(mod_ptr + ch); + + sink_ptr += sink_ch; + mod_ptr += sink_mod->channels; } + + num_samples_remaining -= n; + sink_ptr = audio_stream_wrap(sink, sink_ptr); } } -#endif /* CONFIG_FORMAT_S16LE */ -#if CONFIG_FORMAT_S24LE -static void smart_amp_s24_fb_default(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *feedback, - uint32_t frames) -{ - int32_t *x; - int idx; - int ch; +static void feed_s24_to_s24(const struct smart_amp_mod_stream *sink_mod, uint32_t frames, + const struct audio_stream __sparse_cache *sink) +{ + feed_s32_to_s32(sink_mod, frames, sink); +} + +static void feed_s32_to_s24(const struct smart_amp_mod_stream *sink_mod, uint32_t frames, + const struct audio_stream __sparse_cache *sink) +{ int i; - int nch = audio_stream_get_channels(source); - - for (ch = 0; ch < nch; ch++) { - idx = ch; - for (i = 0; i < frames; i++) { - x = audio_stream_read_frag_s32(feedback, idx); - smart_amp_fb_generic(*x << 8); - idx += nch; + int sink_ch = audio_stream_get_channels(sink); + int n_mod = frames * sink_mod->channels; + int32_t *mod_ptr = (int32_t *)sink_mod->buf.data; + + /* one loop for in-place rshift (s32-to-s24) before feeding */ + for (i = 0; i < n_mod; i++) { + *mod_ptr = sat_int24(Q_SHIFT_RND(*mod_ptr, 31, 23)); + mod_ptr++; + } + + feed_s32_to_s32(sink_mod, frames, sink); +} + +static void feed_s16_to_s16(const struct smart_amp_mod_stream *sink_mod, uint32_t frames, + const struct audio_stream __sparse_cache *sink) +{ + int num_samples_remaining; + int nmax, n, ch, i; + int sink_ch = audio_stream_get_channels(sink); + int feed_channels = MIN(sink_ch, sink_mod->channels); + int16_t *sink_ptr = audio_stream_get_wptr(sink); + int16_t *mod_ptr = (int16_t *)sink_mod->buf.data; + + num_samples_remaining = frames * sink_ch; + while (num_samples_remaining) { + nmax = audio_stream_samples_without_wrap_s16(sink, sink_ptr); + n = MIN(num_samples_remaining, nmax); + + for (i = 0; i < n; i += sink_ch) { + for (ch = 0; ch < feed_channels; ch++) + *(sink_ptr + ch) = *(mod_ptr + ch); + + sink_ptr += sink_ch; + mod_ptr += sink_mod->channels; } + + num_samples_remaining -= n; + sink_ptr = audio_stream_wrap(sink, sink_ptr); } } -#endif /* CONFIG_FORMAT_S24LE */ -#if CONFIG_FORMAT_S32LE -static void smart_amp_s32_fb_default(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *feedback, - uint32_t frames) -{ - int32_t *x; - int idx; - int ch; - int i; - int nch = audio_stream_get_channels(source); - - for (ch = 0; ch < nch; ch++) { - idx = ch; - for (i = 0; i < frames; i++) { - x = audio_stream_read_frag_s32(feedback, idx); - smart_amp_ff_generic(*x); - idx += nch; +static void feed_b32_to_s16(const struct smart_amp_mod_stream *sink_mod, uint32_t frames, + const struct audio_stream __sparse_cache *sink, int mod_fbits) +{ + int num_samples_remaining; + int nmax, n, ch, i; + int sink_ch = audio_stream_get_channels(sink); + int feed_channels = MIN(sink_ch, sink_mod->channels); + int16_t *sink_ptr = audio_stream_get_wptr(sink); + int32_t *mod_ptr = (int32_t *)sink_mod->buf.data; + + num_samples_remaining = frames * sink_ch; + while (num_samples_remaining) { + nmax = audio_stream_samples_without_wrap_s16(sink, sink_ptr); + n = MIN(num_samples_remaining, nmax); + + for (i = 0; i < n; i += sink_ch) { + for (ch = 0; ch < feed_channels; ch++) { + *(sink_ptr + ch) = sat_int16(Q_SHIFT_RND(*(mod_ptr + ch), + mod_fbits, 15)); + } + sink_ptr += sink_ch; + mod_ptr += sink_mod->channels; } + + num_samples_remaining -= n; + sink_ptr = audio_stream_wrap(sink, sink_ptr); } } -#endif /* CONFIG_FORMAT_S32LE */ -const struct smart_amp_func_map smart_amp_function_map[] = { -/* { SOURCE_FORMAT , PROCESSING FUNCTION } */ +static void feed_s24_to_s16(const struct smart_amp_mod_stream *sink_mod, uint32_t frames, + const struct audio_stream __sparse_cache *sink) +{ + feed_b32_to_s16(sink_mod, frames, sink, 23 /* mod_fbits */); +} + +static void feed_s32_to_s16(const struct smart_amp_mod_stream *sink_mod, uint32_t frames, + const struct audio_stream __sparse_cache *sink) +{ + feed_b32_to_s16(sink_mod, frames, sink, 31 /* mod_fbits */); +} + +const struct smart_amp_func_map src_sink_func_map[] = { + /* { comp_fmt, mod_fmt, src_func, sink_func } + * cases are valid only if comp_fmt <= mod_fmt + */ #if CONFIG_FORMAT_S16LE - { SOF_IPC_FRAME_S16_LE, smart_amp_s16_ff_default }, -#endif /* CONFIG_FORMAT_S16LE */ + { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, &remap_s16_to_s16, &feed_s16_to_s16 }, + #if CONFIG_FORMAT_S24LE - { SOF_IPC_FRAME_S24_4LE, smart_amp_s24_ff_default }, -#endif /* CONFIG_FORMAT_S24LE */ + { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S24_4LE, &remap_s16_to_s24, &feed_s24_to_s16 }, +#endif /* CONFIG_FORMAT_S24LE */ + #if CONFIG_FORMAT_S32LE - { SOF_IPC_FRAME_S32_LE, smart_amp_s32_ff_default }, -#endif /* CONFIG_FORMAT_S32LE */ -#if CONFIG_FORMAT_S16LE - { SOF_IPC_FRAME_S16_LE, smart_amp_s16_fb_default }, -#endif /* CONFIG_FORMAT_S16LE */ + { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, &remap_s16_to_s32, &feed_s32_to_s16 }, +#endif /* CONFIG_FORMAT_S32LE */ +#endif /* CONFIG_FORMAT_S16LE */ + #if CONFIG_FORMAT_S24LE - { SOF_IPC_FRAME_S24_4LE, smart_amp_s24_fb_default }, -#endif /* CONFIG_FORMAT_S24LE */ + { SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_4LE, &remap_s24_to_s24, &feed_s24_to_s24 }, + +#if CONFIG_FORMAT_S32LE + { SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, &remap_s24_to_s32, &feed_s32_to_s24 }, +#endif /* CONFIG_FORMAT_S32LE */ +#endif /* CONFIG_FORMAT_S24LE */ + #if CONFIG_FORMAT_S32LE - { SOF_IPC_FRAME_S32_LE, smart_amp_s32_fb_default }, -#endif /* CONFIG_FORMAT_S32LE */ + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, &remap_s32_to_s32, &feed_s32_to_s32 }, +#endif /* CONFIG_FORMAT_S32LE */ }; -const size_t smart_amp_func_count = ARRAY_SIZE(smart_amp_function_map); -#endif +smart_amp_src_func smart_amp_get_src_func(uint16_t comp_fmt, uint16_t mod_fmt) +{ + uint32_t i; + + for (i = 0; i < ARRAY_SIZE(src_sink_func_map); i++) { + if (comp_fmt == src_sink_func_map[i].comp_fmt && + mod_fmt == src_sink_func_map[i].mod_fmt) + return src_sink_func_map[i].src_func; + } + + return NULL; +} + +smart_amp_sink_func smart_amp_get_sink_func(uint16_t comp_fmt, uint16_t mod_fmt) +{ + uint32_t i; + + for (i = 0; i < ARRAY_SIZE(src_sink_func_map); i++) { + if (comp_fmt == src_sink_func_map[i].comp_fmt && + mod_fmt == src_sink_func_map[i].mod_fmt) + return src_sink_func_map[i].sink_func; + } + + return NULL; +} diff --git a/src/audio/smart_amp/smart_amp_maxim_dsm.c b/src/audio/smart_amp/smart_amp_maxim_dsm.c index ed6b5a218511..e45620248dd4 100644 --- a/src/audio/smart_amp/smart_amp_maxim_dsm.c +++ b/src/audio/smart_amp/smart_amp_maxim_dsm.c @@ -20,8 +20,119 @@ #include #include "dsm_api_public.h" -static int maxim_dsm_init(struct smart_amp_mod_struct_t *hspk, struct comp_dev *dev) +/* Maxim DSM(Dynamic Speaker Management) process buffer size */ +#define DSM_FRM_SZ 48 +#define DSM_FF_BUF_SZ (DSM_FRM_SZ * SMART_AMP_FF_MAX_CH_NUM) +#define DSM_FB_BUF_SZ (DSM_FRM_SZ * SMART_AMP_FB_MAX_CH_NUM) + +#define DSM_FF_BUF_DB_SZ (DSM_FF_BUF_SZ * SMART_AMP_FF_MAX_CH_NUM) +#define DSM_FB_BUF_DB_SZ (DSM_FB_BUF_SZ * SMART_AMP_FB_MAX_CH_NUM) + +/* DSM parameter table structure + * +--------------+-----------------+---------------------------------+ + * | ID (4 bytes) | VALUE (4 bytes) | 1st channel : | + * | | | 8 bytes per single parameter | + * +--------------+-----------------+---------------------------------+ + * | ... | ... | Repeat N times for N parameters | + * +--------------+-----------------+---------------------------------+ + * | ID (4 bytes) | VALUE (4 bytes) | 2nd channel : | + * | | | 8 bytes per single parameter | + * +--------------+-----------------+---------------------------------+ + * | ... | ... | Repeat N times for N parameters | + * +--------------+-----------------+---------------------------------+ + */ +enum dsm_param { + DSM_PARAM_ID = 0, + DSM_PARAM_VALUE, + DSM_PARAM_MAX +}; + +#define DSM_SINGLE_PARAM_SZ (DSM_PARAM_MAX * SMART_AMP_FF_MAX_CH_NUM) + +static const int supported_fmt_count = 3; +static const uint16_t supported_fmts[] = { + SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE +}; + +union maxim_dsm_buf { + int16_t *buf16; + int32_t *buf32; +}; + +struct maxim_dsm_ff_buf_struct_t { + int32_t *buf; + int avail; +}; + +struct maxim_dsm_fb_buf_struct_t { + int32_t *buf; + int avail; + int rdy; +}; + +struct smart_amp_buf_struct_t { + /* buffer : feed forward process input */ + int32_t *input; + /* buffer : feed forward process output */ + int32_t *output; + /* buffer : feedback voltage */ + int32_t *voltage; + /* buffer : feedback current */ + int32_t *current; + /* buffer : feed forward variable length -> fixed length */ + struct maxim_dsm_ff_buf_struct_t ff; + /* buffer : feed forward variable length <- fixed length */ + struct maxim_dsm_ff_buf_struct_t ff_out; + /* buffer : feedback variable length -> fixed length */ + struct maxim_dsm_fb_buf_struct_t fb; +}; + +struct param_buf_struct_t { + int id; + int value; +}; + +struct smart_amp_caldata { + uint32_t data_size; /* size of component's model data */ + void *data; /* model data pointer */ + uint32_t data_pos; /* data position for read/write */ +}; + +struct smart_amp_param_struct_t { + struct param_buf_struct_t param; /* variable to keep last parameter ID/value */ + struct smart_amp_caldata caldata; /* model data buffer */ + int pos; /* data position for read/write */ + int max_param; /* keep max number of DSM parameters */ +}; + +/* self-declared inner model data struct */ +struct smart_amp_mod_struct_t { + struct smart_amp_mod_data_base base; + struct smart_amp_buf_struct_t buf; + void *dsmhandle; + /* DSM variables for the initialization */ + int delayedsamples[SMART_AMP_FF_MAX_CH_NUM << 2]; + int circularbuffersize[SMART_AMP_FF_MAX_CH_NUM << 2]; + /* Number of samples of feed forward and feedback frame */ + int ff_fr_sz_samples; + int fb_fr_sz_samples; + int channelmask; + /* Number of channels of DSM */ + int nchannels; + /* Number of samples of feed forward channel */ + int ifsamples; + /* Number of samples of feedback channel */ + int ibsamples; + /* Number of processed samples */ + int ofsamples; + /* Channel bit dempth */ + int bitwidth; + struct smart_amp_param_struct_t param; +}; + +static int maxim_dsm_init(struct smart_amp_mod_struct_t *hspk) { + const struct comp_dev *dev = hspk->base.dev; int *circularbuffersize = hspk->circularbuffersize; int *delayedsamples = hspk->delayedsamples; struct dsm_api_init_ext_t initparam; @@ -33,11 +144,16 @@ static int maxim_dsm_init(struct smart_amp_mod_struct_t *hspk, struct comp_dev * initparam.ipdelayedsamples = delayedsamples; initparam.isamplingrate = DSM_DEFAULT_SAMPLE_RATE; + if (!hspk->dsmhandle) { + comp_err(dev, "[DSM] Initialization failed: dsmhandle not allocated"); + return -EINVAL; + } + retcode = dsm_api_init(hspk->dsmhandle, &initparam, sizeof(struct dsm_api_init_ext_t)); if (retcode != DSM_API_OK) { goto exit; - } else { + } else { hspk->ff_fr_sz_samples = initparam.off_framesizesamples; hspk->fb_fr_sz_samples = @@ -60,8 +176,62 @@ static int maxim_dsm_init(struct smart_amp_mod_struct_t *hspk, struct comp_dev * return (int)retcode; } -static int maxim_dsm_get_all_param(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev) +static int maxim_dsm_get_num_param(struct smart_amp_mod_struct_t *hspk) +{ + enum DSM_API_MESSAGE retcode; + int cmdblock[DSM_GET_PARAM_SZ_PAYLOAD]; + + /* Get number of parameters */ + cmdblock[DSM_GET_ID_IDX] = DSM_SET_CMD_ID(DSM_API_GET_MAXIMUM_CMD_ID); + retcode = dsm_api_get_params(hspk->dsmhandle, 1, (void *)cmdblock); + if (retcode != DSM_API_OK) + return 0; + + return MIN(DSM_DEFAULT_MAX_NUM_PARAM, cmdblock[DSM_GET_CH1_IDX]); +} + +static int maxim_dsm_get_handle_size(struct smart_amp_mod_struct_t *hspk) +{ + enum DSM_API_MESSAGE retcode; + struct dsm_api_memory_size_ext_t memsize; + int *circularbuffersize = hspk->circularbuffersize; + + memsize.ichannels = DSM_DEFAULT_NUM_CHANNEL; + memsize.ipcircbuffersizebytes = circularbuffersize; + memsize.isamplingrate = DSM_DEFAULT_SAMPLE_RATE; + memsize.omemsizerequestedbytes = 0; + memsize.numeqfilters = DSM_DEFAULT_NUM_EQ; + retcode = dsm_api_get_mem(&memsize, + sizeof(struct dsm_api_memory_size_ext_t)); + if (retcode != DSM_API_OK) + return 0; + + return memsize.omemsizerequestedbytes; +} + +static int maxim_dsm_flush(struct smart_amp_mod_struct_t *hspk) +{ + const struct comp_dev *dev = hspk->base.dev; + + memset(hspk->buf.input, 0, DSM_FF_BUF_SZ * sizeof(int32_t)); + memset(hspk->buf.output, 0, DSM_FF_BUF_SZ * sizeof(int32_t)); + memset(hspk->buf.voltage, 0, DSM_FF_BUF_SZ * sizeof(int32_t)); + memset(hspk->buf.current, 0, DSM_FF_BUF_SZ * sizeof(int32_t)); + + memset(hspk->buf.ff.buf, 0, DSM_FF_BUF_DB_SZ * sizeof(int32_t)); + memset(hspk->buf.ff_out.buf, 0, DSM_FF_BUF_DB_SZ * sizeof(int32_t)); + memset(hspk->buf.fb.buf, 0, DSM_FB_BUF_DB_SZ * sizeof(int32_t)); + + hspk->buf.ff.avail = DSM_FF_BUF_SZ; + hspk->buf.ff_out.avail = 0; + hspk->buf.fb.avail = 0; + + comp_dbg(dev, "[DSM] Reset (handle:%p)", hspk); + + return 0; +} + +static int maxim_dsm_get_all_param(struct smart_amp_mod_struct_t *hspk) { struct smart_amp_caldata *caldata = &hspk->param.caldata; int32_t *db = (int32_t *)caldata->data; @@ -96,7 +266,7 @@ static int maxim_dsm_get_all_param(struct smart_amp_mod_struct_t *hspk, } static int maxim_dsm_get_volatile_param(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev) + const struct comp_dev *dev) { struct smart_amp_caldata *caldata = &hspk->param.caldata; int32_t *db = (int32_t *)caldata->data; @@ -125,42 +295,10 @@ static int maxim_dsm_get_volatile_param(struct smart_amp_mod_struct_t *hspk, return 0; } -int maxim_dsm_get_param_forced(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev) -{ - struct smart_amp_caldata *caldata = &hspk->param.caldata; - int32_t *db = (int32_t *)caldata->data; - enum DSM_API_MESSAGE retcode; - int cmdblock[DSM_GET_PARAM_SZ_PAYLOAD]; - int num_param = hspk->param.max_param; - int idx; - - /* Update all parameter values from the DSM component */ - for (idx = 0 ; idx <= num_param ; idx++) { - cmdblock[0] = DSM_SET_CMD_ID(idx); - retcode = dsm_api_get_params(hspk->dsmhandle, 1, (void *)cmdblock); - if (retcode != DSM_API_OK) { - /* set zero if the parameter is not readable */ - cmdblock[DSM_GET_CH1_IDX] = 0; - cmdblock[DSM_GET_CH2_IDX] = 0; - } - /* fill the data for the 1st channel 4 byte ID + 4 byte value */ - db[idx * DSM_PARAM_MAX + DSM_PARAM_ID] = DSM_CH1_BITMASK | idx; - db[idx * DSM_PARAM_MAX + DSM_PARAM_VALUE] = cmdblock[DSM_GET_CH1_IDX]; - /* fill the data for the 2nd channel 4 byte ID + 4 byte value - * 2nd channel data have offset for num_param * DSM_PARAM_MAX - */ - db[(idx + num_param) * DSM_PARAM_MAX + DSM_PARAM_ID] = DSM_CH2_BITMASK | idx; - db[(idx + num_param) * DSM_PARAM_MAX + DSM_PARAM_VALUE] = cmdblock[DSM_GET_CH2_IDX]; - } - - return 0; -} - -int maxim_dsm_get_param(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev, - struct sof_ipc_ctrl_data *cdata, int size) +static int maxim_dsm_get_param(struct smart_amp_mod_struct_t *hspk, + struct sof_ipc_ctrl_data *cdata, int size) { + const struct comp_dev *dev = hspk->base.dev; struct smart_amp_caldata *caldata = &hspk->param.caldata; size_t bs; int ret; @@ -203,10 +341,10 @@ int maxim_dsm_get_param(struct smart_amp_mod_struct_t *hspk, return 0; } -int maxim_dsm_set_param(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev, - struct sof_ipc_ctrl_data *cdata) +static int maxim_dsm_set_param(struct smart_amp_mod_struct_t *hspk, + struct sof_ipc_ctrl_data *cdata) { + const struct comp_dev *dev = hspk->base.dev; struct smart_amp_param_struct_t *param = &hspk->param; struct smart_amp_caldata *caldata = &hspk->param.caldata; /* Model database */ @@ -265,9 +403,9 @@ int maxim_dsm_set_param(struct smart_amp_mod_struct_t *hspk, return 0; } -int maxim_dsm_restore_param(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev) +static int maxim_dsm_restore_param(struct smart_amp_mod_struct_t *hspk) { + const struct comp_dev *dev = hspk->base.dev; struct smart_amp_caldata *caldata = &hspk->param.caldata; int32_t *db = (int32_t *)caldata->data; int num_param = hspk->param.max_param; @@ -290,42 +428,74 @@ int maxim_dsm_restore_param(struct smart_amp_mod_struct_t *hspk, return 0; } -static void maxim_dsm_ff_proc(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev, void *in, void *out, - int nsamples, int szsample) +/** + * mod_ops implementation. + */ + +static int maxim_dsm_get_config(struct smart_amp_mod_data_base *mod, + struct sof_ipc_ctrl_data *cdata, uint32_t size) { - union smart_amp_buf buf, buf_out; + struct smart_amp_mod_struct_t *hspk = (struct smart_amp_mod_struct_t *)mod; + + return maxim_dsm_get_param(hspk, cdata, size); +} + +static int maxim_dsm_set_config(struct smart_amp_mod_data_base *mod, + struct sof_ipc_ctrl_data *cdata) +{ + struct smart_amp_mod_struct_t *hspk = (struct smart_amp_mod_struct_t *)mod; + + return maxim_dsm_set_param(hspk, cdata); +} + +static int maxim_dsm_ff_proc(struct smart_amp_mod_data_base *mod, + uint32_t frames, + struct smart_amp_mod_stream *in, + struct smart_amp_mod_stream *out) +{ + struct smart_amp_mod_struct_t *hspk = (struct smart_amp_mod_struct_t *)mod; + union maxim_dsm_buf buf, buf_out; int16_t *input = (int16_t *)hspk->buf.input; int16_t *output = (int16_t *)hspk->buf.output; int32_t *input32 = hspk->buf.input; int32_t *output32 = hspk->buf.output; int *w_ptr = &hspk->buf.ff.avail; int *r_ptr = &hspk->buf.ff_out.avail; - bool is_16bit = szsample == 2 ? true : false; + bool is_16bit = (in->frame_fmt == SOF_IPC_FRAME_S16_LE); + int szsample = (is_16bit ? 2 : 4); + int nsamples = frames * in->channels; int remain; int idx; + int ret = 0; buf.buf16 = (int16_t *)hspk->buf.ff.buf; buf.buf32 = (int32_t *)hspk->buf.ff.buf; buf_out.buf16 = (int16_t *)hspk->buf.ff_out.buf; buf_out.buf32 = (int32_t *)hspk->buf.ff_out.buf; + /* Report all frames consumed even if buffer overflow to prevent source + * congestion. Same for frames produced to keep the stream rolling. + */ + in->consumed = frames; + out->produced = frames; + /* Current pointer(w_ptr) + number of input frames(nsamples) * must be smaller than buffer size limit */ if (*w_ptr + nsamples <= DSM_FF_BUF_DB_SZ) { if (is_16bit) memcpy_s(&buf.buf16[*w_ptr], nsamples * szsample, - in, nsamples * szsample); + in->buf.data, nsamples * szsample); else memcpy_s(&buf.buf32[*w_ptr], nsamples * szsample, - in, nsamples * szsample); + in->buf.data, nsamples * szsample); *w_ptr += nsamples; } else { - comp_warn(dev, + comp_warn(mod->dev, "[DSM] Feed Forward buffer overflow. (w_ptr : %d + %d > %d)", *w_ptr, nsamples, DSM_FF_BUF_DB_SZ); - return; + ret = -EOVERFLOW; + goto error; } /* Run DSM Feedforward process if the buffer is ready */ @@ -387,10 +557,10 @@ static void maxim_dsm_ff_proc(struct smart_amp_mod_struct_t *hspk, /* Output buffer preparation */ if (*r_ptr >= nsamples) { if (is_16bit) - memcpy_s(out, nsamples * szsample, + memcpy_s(out->buf.data, nsamples * szsample, buf_out.buf16, nsamples * szsample); else - memcpy_s(out, nsamples * szsample, + memcpy_s(out->buf.data, nsamples * szsample, buf_out.buf32, nsamples * szsample); remain = (*r_ptr - nsamples); @@ -405,47 +575,65 @@ static void maxim_dsm_ff_proc(struct smart_amp_mod_struct_t *hspk, remain * szsample); } *r_ptr -= nsamples; - } else { - memset(out, 0, nsamples * szsample); - comp_err(dev, - "[DSM] DSM FF process underrun. r_ptr : %d", - *r_ptr); + return ret; } + /* else { */ + comp_err(mod->dev, "[DSM] DSM FF process underrun. r_ptr : %d", *r_ptr); + ret = -ENODATA; + +error: + /* TODO(Maxim): undefined behavior when buffer overflow in previous code. + * It leads to early return and no sample written to output + * buffer. However the sink buffer will still writeback + * avail_frames data copied from output buffer. + */ + /* set all-zero output when buffer overflow or process underrun. */ + memset_s(out->buf.data, out->buf.size, 0, nsamples * szsample); + return ret; } -static void maxim_dsm_fb_proc(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev, void *in, - int nsamples, int szsample) +static int maxim_dsm_fb_proc(struct smart_amp_mod_data_base *mod, + uint32_t frames, + struct smart_amp_mod_stream *in) { - union smart_amp_buf buf; + struct smart_amp_mod_struct_t *hspk = (struct smart_amp_mod_struct_t *)mod; + union maxim_dsm_buf buf; int *w_ptr = &hspk->buf.fb.avail; int16_t *v = (int16_t *)hspk->buf.voltage; int16_t *i = (int16_t *)hspk->buf.current; int32_t *v32 = hspk->buf.voltage; int32_t *i32 = hspk->buf.current; - bool is_16bit = szsample == 2 ? true : false; + bool is_16bit = (in->frame_fmt == SOF_IPC_FRAME_S16_LE); + int szsample = (is_16bit ? 2 : 4); + int nsamples = frames * in->channels; int remain; int idx; buf.buf16 = (int16_t *)hspk->buf.fb.buf; buf.buf32 = hspk->buf.fb.buf; + /* Set all frames consumed even if buffer overflow to prevent source + * congestion. + */ + in->consumed = frames; + /* Current pointer(w_ptr) + number of input frames(nsamples) * must be smaller than buffer size limit */ if (*w_ptr + nsamples <= DSM_FB_BUF_DB_SZ) { if (is_16bit) memcpy_s(&buf.buf16[*w_ptr], nsamples * szsample, - in, nsamples * szsample); + in->buf.data, nsamples * szsample); else memcpy_s(&buf.buf32[*w_ptr], nsamples * szsample, - in, nsamples * szsample); + in->buf.data, nsamples * szsample); *w_ptr += nsamples; } else { - comp_warn(dev, "[DSM] Feedback buffer overflow. w_ptr : %d", + comp_warn(mod->dev, "[DSM] Feedback buffer overflow. w_ptr : %d", *w_ptr); - return; + return -EOVERFLOW; } + /* Run DSM Feedback process if the buffer is ready */ if (*w_ptr >= DSM_FB_BUF_SZ) { if (is_16bit) { @@ -490,189 +678,99 @@ static void maxim_dsm_fb_proc(struct smart_amp_mod_struct_t *hspk, hspk->channelmask, (short *)i32, (short *)v32, &hspk->ibsamples); } -} - -int smart_amp_flush(struct smart_amp_mod_struct_t *hspk, struct comp_dev *dev) -{ - memset(hspk->buf.frame_in, 0, - SMART_AMP_FF_BUF_DB_SZ * sizeof(int32_t)); - memset(hspk->buf.frame_out, 0, - SMART_AMP_FF_BUF_DB_SZ * sizeof(int32_t)); - memset(hspk->buf.frame_iv, 0, - SMART_AMP_FB_BUF_DB_SZ * sizeof(int32_t)); - - memset(hspk->buf.input, 0, DSM_FF_BUF_SZ * sizeof(int16_t)); - memset(hspk->buf.output, 0, DSM_FF_BUF_SZ * sizeof(int16_t)); - memset(hspk->buf.voltage, 0, DSM_FF_BUF_SZ * sizeof(int16_t)); - memset(hspk->buf.current, 0, DSM_FF_BUF_SZ * sizeof(int16_t)); - - memset(hspk->buf.ff.buf, 0, DSM_FF_BUF_DB_SZ * sizeof(int32_t)); - memset(hspk->buf.ff_out.buf, 0, DSM_FF_BUF_DB_SZ * sizeof(int32_t)); - memset(hspk->buf.fb.buf, 0, DSM_FB_BUF_DB_SZ * sizeof(int32_t)); - - hspk->buf.ff.avail = DSM_FF_BUF_SZ; - hspk->buf.ff_out.avail = 0; - hspk->buf.fb.avail = 0; - - comp_dbg(dev, "[DSM] Reset (handle:%p)", hspk); - - return 0; -} - -int smart_amp_init(struct smart_amp_mod_struct_t *hspk, struct comp_dev *dev) -{ - return maxim_dsm_init(hspk, dev); -} - -int smart_amp_get_all_param(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev) -{ - if (maxim_dsm_get_all_param(hspk, dev) < 0) - return -EINVAL; return 0; } -int smart_amp_get_num_param(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev) +static int maxim_dsm_preinit(struct smart_amp_mod_data_base *mod) { - enum DSM_API_MESSAGE retcode; - int cmdblock[DSM_GET_PARAM_SZ_PAYLOAD]; + struct smart_amp_mod_struct_t *hspk = (struct smart_amp_mod_struct_t *)mod; - /* Get number of parameters */ - cmdblock[DSM_GET_ID_IDX] = DSM_SET_CMD_ID(DSM_API_GET_MAXIMUM_CMD_ID); - retcode = dsm_api_get_params(hspk->dsmhandle, 1, (void *)cmdblock); - if (retcode != DSM_API_OK) - return 0; - - return MIN(DSM_DEFAULT_MAX_NUM_PARAM, cmdblock[DSM_GET_CH1_IDX]); -} - -int smart_amp_get_memory_size(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev) -{ - enum DSM_API_MESSAGE retcode; - struct dsm_api_memory_size_ext_t memsize; - int *circularbuffersize = hspk->circularbuffersize; - - memsize.ichannels = DSM_DEFAULT_NUM_CHANNEL; - memsize.ipcircbuffersizebytes = circularbuffersize; - memsize.isamplingrate = DSM_DEFAULT_SAMPLE_RATE; - memsize.omemsizerequestedbytes = 0; - memsize.numeqfilters = DSM_DEFAULT_NUM_EQ; - retcode = dsm_api_get_mem(&memsize, - sizeof(struct dsm_api_memory_size_ext_t)); - if (retcode != DSM_API_OK) - return 0; - - return memsize.omemsizerequestedbytes; + /* Bitwidth information is not available. Use 16bit as default. + * Re-initialize in the prepare function if ncessary + */ + hspk->bitwidth = 16; + return maxim_dsm_init(hspk); } -int smart_amp_check_audio_fmt(int sample_rate, int ch_num) +static int maxim_dsm_query_memblk_size(struct smart_amp_mod_data_base *mod, + enum smart_amp_mod_memblk blk) { - /* Return error if the format is not supported by DSM component */ - if (sample_rate != DSM_DEFAULT_SAMPLE_RATE) - return -EINVAL; - if (ch_num > DSM_DEFAULT_NUM_CHANNEL) - return -EINVAL; - - return 0; -} + struct smart_amp_mod_struct_t *hspk = (struct smart_amp_mod_struct_t *)mod; + int ret; -static int smart_amp_get_buffer(int32_t *buf, uint32_t frames, - const struct audio_stream __sparse_cache *stream, - int8_t *chan_map, uint32_t num_ch) -{ - int idx, ch; - uint32_t in_frag = 0; - union smart_amp_buf input, output; - int index; - - input.buf16 = audio_stream_get_rptr(stream); - input.buf32 = audio_stream_get_rptr(stream); - output.buf16 = (int16_t *)buf; - output.buf32 = (int32_t *)buf; - - switch (audio_stream_get_frm_fmt(stream)) { - case SOF_IPC_FRAME_S16_LE: - for (idx = 0 ; idx < frames ; idx++) { - for (ch = 0 ; ch < num_ch; ch++) { - if (chan_map[ch] == -1) - continue; - index = in_frag + chan_map[ch]; - input.buf16 = - audio_stream_read_frag_s16(stream, - index); - output.buf16[num_ch * idx + ch] = *input.buf16; - } - in_frag += audio_stream_get_channels(stream); - } + switch (blk) { + case MOD_MEMBLK_PRIVATE: + /* Memory size for private data block - dsmhandle */ + ret = maxim_dsm_get_handle_size(hspk); + if (ret <= 0) + comp_err(mod->dev, "[DSM] Get handle size error"); break; - case SOF_IPC_FRAME_S24_4LE: - case SOF_IPC_FRAME_S32_LE: - for (idx = 0 ; idx < frames ; idx++) { - for (ch = 0 ; ch < num_ch ; ch++) { - if (chan_map[ch] == -1) - continue; - index = in_frag + chan_map[ch]; - input.buf32 = - audio_stream_read_frag_s32(stream, - index); - output.buf32[num_ch * idx + ch] = *input.buf32; - } - in_frag += audio_stream_get_channels(stream); + case MOD_MEMBLK_FRAME: + /* Memory size for frame buffer block - smart_amp_buf_struct_t */ + /* smart_amp_buf_struct_t -> input, output, voltage, current */ + ret = 4 * DSM_FF_BUF_SZ * sizeof(int32_t); + /* smart_amp_buf_struct_t -> ff, ff_out, fb */ + ret += 2 * DSM_FF_BUF_DB_SZ * sizeof(int32_t) + DSM_FB_BUF_DB_SZ * sizeof(int32_t); + break; + case MOD_MEMBLK_PARAM: + /* Memory size for param blob block - caldata */ + /* Get the max. number of parameter to allocate memory for model data */ + ret = maxim_dsm_get_num_param(hspk); + if (ret < 0) { + comp_err(mod->dev, "[DSM] Get parameter size error"); + return -EINVAL; } + hspk->param.max_param = ret; + ret = hspk->param.max_param * DSM_SINGLE_PARAM_SZ * sizeof(int32_t); break; default: - return -EINVAL; + ret = -EINVAL; + break; } - return 0; + + return ret; } -static int smart_amp_put_buffer(int32_t *buf, uint32_t frames, - const struct audio_stream __sparse_cache *stream, - int8_t *chan_map, uint32_t num_ch_in, - uint32_t num_ch_out) +static int maxim_dsm_set_memblk(struct smart_amp_mod_data_base *mod, + enum smart_amp_mod_memblk blk, + struct smart_amp_buf *buf) { - union smart_amp_buf input, output; - uint32_t out_frag = 0; - int idx, ch; - - input.buf16 = (int16_t *)buf; - input.buf32 = (int32_t *)buf; - output.buf16 = audio_stream_get_wptr(stream); - output.buf32 = audio_stream_get_wptr(stream); - - switch (audio_stream_get_frm_fmt(stream)) { - case SOF_IPC_FRAME_S16_LE: - for (idx = 0 ; idx < frames ; idx++) { - for (ch = 0 ; ch < num_ch_out; ch++) { - if (chan_map[ch] == -1) { - out_frag++; - continue; - } - output.buf16 = - audio_stream_write_frag_s16(stream, - out_frag); - *output.buf16 = input.buf16[num_ch_in * idx + ch]; - out_frag++; - } - } + struct smart_amp_mod_struct_t *hspk = (struct smart_amp_mod_struct_t *)mod; + int32_t *mem_ptr; + + switch (blk) { + case MOD_MEMBLK_PRIVATE: + /* Assign memory to private data */ + hspk->dsmhandle = buf->data; + bzero(hspk->dsmhandle, buf->size); break; - case SOF_IPC_FRAME_S24_4LE: - case SOF_IPC_FRAME_S32_LE: - for (idx = 0 ; idx < frames ; idx++) { - for (ch = 0 ; ch < num_ch_out; ch++) { - if (chan_map[ch] == -1) { - out_frag++; - continue; - } - output.buf32 = - audio_stream_write_frag_s32(stream, - out_frag); - *output.buf32 = input.buf32[num_ch_in * idx + ch]; - out_frag++; - } - } + case MOD_MEMBLK_FRAME: + /* Assign memory to frame buffers */ + mem_ptr = (int32_t *)buf->data; + hspk->buf.input = mem_ptr; + mem_ptr += DSM_FF_BUF_SZ; + hspk->buf.output = mem_ptr; + mem_ptr += DSM_FF_BUF_SZ; + hspk->buf.voltage = mem_ptr; + mem_ptr += DSM_FF_BUF_SZ; + hspk->buf.current = mem_ptr; + mem_ptr += DSM_FF_BUF_SZ; + hspk->buf.ff.buf = mem_ptr; + mem_ptr += DSM_FF_BUF_DB_SZ; + hspk->buf.ff_out.buf = mem_ptr; + mem_ptr += DSM_FF_BUF_DB_SZ; + hspk->buf.fb.buf = mem_ptr; + break; + case MOD_MEMBLK_PARAM: + /* Assign memory to config caldata */ + hspk->param.caldata.data = buf->data; + hspk->param.caldata.data_size = buf->size; + bzero(hspk->param.caldata.data, hspk->param.caldata.data_size); + hspk->param.caldata.data_pos = 0; + + /* update full parameter values */ + if (maxim_dsm_get_all_param(hspk) < 0) + return -EINVAL; break; default: return -EINVAL; @@ -680,110 +778,71 @@ static int smart_amp_put_buffer(int32_t *buf, uint32_t frames, return 0; } -int smart_amp_ff_copy(struct comp_dev *dev, uint32_t frames, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, int8_t *chan_map, - struct smart_amp_mod_struct_t *hspk, - uint32_t num_ch_in, uint32_t num_ch_out) +static int maxim_dsm_get_supported_fmts(struct smart_amp_mod_data_base *mod, + const uint16_t **mod_fmts, int *num_mod_fmts) +{ + *num_mod_fmts = supported_fmt_count; + *mod_fmts = supported_fmts; + return 0; +} + +static int maxim_dsm_set_fmt(struct smart_amp_mod_data_base *mod, uint16_t mod_fmt) { + struct smart_amp_mod_struct_t *hspk = (struct smart_amp_mod_struct_t *)mod; int ret; - if (frames == 0) { - comp_warn(dev, "[DSM] feed forward frame size zero warning."); - return 0; - } + comp_dbg(mod->dev, "[DSM] smart_amp_mod_set_fmt(): %u", mod_fmt); - if (frames > SMART_AMP_FF_BUF_DB_SZ) { - comp_err(dev, "[DSM] feed forward frame size overflow : %d", - frames); - return -EINVAL; - } + hspk->bitwidth = get_sample_bitdepth(mod_fmt); - num_ch_in = MIN(num_ch_in, SMART_AMP_FF_MAX_CH_NUM); - num_ch_out = MIN(num_ch_out, SMART_AMP_FF_OUT_MAX_CH_NUM); - - ret = smart_amp_get_buffer(hspk->buf.frame_in, - frames, source, chan_map, - num_ch_in); - if (ret) - goto err; - - switch (audio_stream_get_frm_fmt(source)) { - case SOF_IPC_FRAME_S16_LE: - maxim_dsm_ff_proc(hspk, dev, - hspk->buf.frame_in, - hspk->buf.frame_out, - frames * num_ch_in, sizeof(int16_t)); - break; - case SOF_IPC_FRAME_S24_4LE: - case SOF_IPC_FRAME_S32_LE: - maxim_dsm_ff_proc(hspk, dev, - hspk->buf.frame_in, - hspk->buf.frame_out, - frames * num_ch_in, sizeof(int32_t)); - break; - default: - ret = -EINVAL; - goto err; + ret = maxim_dsm_init(hspk); + if (ret) { + comp_err(mod->dev, "[DSM] Re-initialization error."); + goto error; + } + ret = maxim_dsm_restore_param(hspk); + if (ret) { + comp_err(mod->dev, "[DSM] Restoration error."); + goto error; } - ret = smart_amp_put_buffer(hspk->buf.frame_out, - frames, sink, chan_map, - MIN(num_ch_in, SMART_AMP_FF_MAX_CH_NUM), - MIN(num_ch_out, SMART_AMP_FF_OUT_MAX_CH_NUM)); - if (ret) - goto err; - - return 0; -err: - comp_err(dev, "[DSM] Not supported frame format"); +error: + maxim_dsm_flush(hspk); return ret; } -int smart_amp_fb_copy(struct comp_dev *dev, uint32_t frames, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, int8_t *chan_map, - struct smart_amp_mod_struct_t *hspk, - uint32_t num_ch) +static int maxim_dsm_reset(struct smart_amp_mod_data_base *mod) { - int ret; - - if (frames == 0) { - comp_warn(dev, "[DSM] feedback frame size zero warning."); - return 0; - } - - if (frames > SMART_AMP_FB_BUF_DB_SZ) { - comp_err(dev, "[DSM] feedback frame size overflow : %d", - frames); - return -EINVAL; - } + /* no-op for reset */ + return 0; +} - num_ch = MIN(num_ch, SMART_AMP_FB_MAX_CH_NUM); +static const struct inner_model_ops maxim_dsm_ops = { + .init = maxim_dsm_preinit, + .query_memblk_size = maxim_dsm_query_memblk_size, + .set_memblk = maxim_dsm_set_memblk, + .get_supported_fmts = maxim_dsm_get_supported_fmts, + .set_fmt = maxim_dsm_set_fmt, + .ff_proc = maxim_dsm_ff_proc, + .fb_proc = maxim_dsm_fb_proc, + .set_config = maxim_dsm_set_config, + .get_config = maxim_dsm_get_config, + .reset = maxim_dsm_reset +}; + +/** + * mod_data_create() implementation. + */ + +struct smart_amp_mod_data_base *mod_data_create(const struct comp_dev *dev) +{ + struct smart_amp_mod_struct_t *hspk; - ret = smart_amp_get_buffer(hspk->buf.frame_iv, - frames, source, - chan_map, num_ch); - if (ret) - goto err; + hspk = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*hspk)); + if (!hspk) + return NULL; - switch (audio_stream_get_frm_fmt(source)) { - case SOF_IPC_FRAME_S16_LE: - maxim_dsm_fb_proc(hspk, dev, hspk->buf.frame_iv, - frames * num_ch, sizeof(int16_t)); - break; - case SOF_IPC_FRAME_S24_4LE: - case SOF_IPC_FRAME_S32_LE: - maxim_dsm_fb_proc(hspk, dev, hspk->buf.frame_iv, - frames * num_ch, sizeof(int32_t)); - break; - default: - ret = -EINVAL; - goto err; - } - return 0; -err: - comp_err(dev, "[DSM] Not supported frame format : %d", - audio_stream_get_frm_fmt(source)); - return ret; + hspk->base.dev = dev; + hspk->base.mod_ops = &maxim_dsm_ops; + return &hspk->base; } diff --git a/src/audio/smart_amp/smart_amp_passthru.c b/src/audio/smart_amp/smart_amp_passthru.c new file mode 100644 index 000000000000..dd5c2fe3d789 --- /dev/null +++ b/src/audio/smart_amp/smart_amp_passthru.c @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2023 Google LLC. +// +// Author: Pin-chih Lin + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* self-declared inner model data struct */ +struct passthru_mod_data { + struct smart_amp_mod_data_base base; + uint16_t ff_fmt; + uint16_t fb_fmt; +}; + +static const int supported_fmt_count = 3; +static const uint16_t supported_fmts[] = { + SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE +}; + +/** + * mod ops implementation. + */ + +static int passthru_mod_init(struct smart_amp_mod_data_base *mod) +{ + comp_info(mod->dev, "[PassThru Amp] init"); + return 0; +} + +static int passthru_mod_query_memblk_size(struct smart_amp_mod_data_base *mod, + enum smart_amp_mod_memblk blk) +{ + return 0; +} + +static int passthru_mod_set_memblk(struct smart_amp_mod_data_base *mod, + enum smart_amp_mod_memblk blk, + struct smart_amp_buf *buf) +{ + return 0; +} + +static int passthru_mod_get_supported_fmts(struct smart_amp_mod_data_base *mod, + const uint16_t **mod_fmts, int *num_mod_fmts) +{ + *num_mod_fmts = supported_fmt_count; + *mod_fmts = supported_fmts; + return 0; +} + +static int passthru_mod_set_fmt(struct smart_amp_mod_data_base *mod, uint16_t mod_fmt) +{ + struct passthru_mod_data *pmd = (struct passthru_mod_data *)mod; + + comp_info(mod->dev, "[PassThru Amp] set fmt:%u", mod_fmt); + pmd->ff_fmt = mod_fmt; + pmd->fb_fmt = mod_fmt; + return 0; +} + +static int passthru_mod_ff_proc(struct smart_amp_mod_data_base *mod, + uint32_t frames, + struct smart_amp_mod_stream *in, + struct smart_amp_mod_stream *out) +{ + struct passthru_mod_data *pmd = (struct passthru_mod_data *)mod; + bool is_16bit = (pmd->ff_fmt == SOF_IPC_FRAME_S16_LE); + uint32_t szsample = (is_16bit ? 2 : 4); + uint32_t size = frames * in->channels * szsample; + + comp_dbg(mod->dev, "[PassThru Amp] bypass %u frames", frames); + + /* passthrough all frames */ + memcpy_s(out->buf.data, out->buf.size, in->buf.data, size); + in->consumed = frames; + out->produced = frames; + return 0; +} + +static int passthru_mod_fb_proc(struct smart_amp_mod_data_base *mod, + uint32_t frames, + struct smart_amp_mod_stream *in) +{ + in->consumed = frames; + return 0; +} + +static int passthru_mod_get_config(struct smart_amp_mod_data_base *mod, + struct sof_ipc_ctrl_data *cdata, uint32_t size) +{ + cdata->data->abi = SOF_ABI_VERSION; + cdata->data->size = 0; + return 0; +} + +static int passthru_mod_set_config(struct smart_amp_mod_data_base *mod, + struct sof_ipc_ctrl_data *cdata) +{ + return 0; +} + +static int passthru_mod_reset(struct smart_amp_mod_data_base *mod) +{ + comp_info(mod->dev, "[PassThru Amp] reset"); + return 0; +} + +static const struct inner_model_ops passthru_mod_ops = { + .init = passthru_mod_init, + .query_memblk_size = passthru_mod_query_memblk_size, + .set_memblk = passthru_mod_set_memblk, + .get_supported_fmts = passthru_mod_get_supported_fmts, + .set_fmt = passthru_mod_set_fmt, + .ff_proc = passthru_mod_ff_proc, + .fb_proc = passthru_mod_fb_proc, + .set_config = passthru_mod_set_config, + .get_config = passthru_mod_get_config, + .reset = passthru_mod_reset +}; + +/** + * mod_data_create() implementation. + */ + +struct smart_amp_mod_data_base *mod_data_create(const struct comp_dev *dev) +{ + struct passthru_mod_data *mod; + + mod = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*mod)); + if (!mod) + return NULL; + + mod->base.dev = dev; + mod->base.mod_ops = &passthru_mod_ops; + return &mod->base; +} diff --git a/src/audio/source_api_helper.c b/src/audio/source_api_helper.c index 91985aeed969..91eb026812a9 100644 --- a/src/audio/source_api_helper.c +++ b/src/audio/source_api_helper.c @@ -7,7 +7,7 @@ #include #include -void source_init(struct sof_source __sparse_cache *source, const struct source_ops *ops, +void source_init(struct sof_source *source, const struct source_ops *ops, struct sof_audio_stream_params *audio_stream_params) { source->ops = ops; @@ -15,13 +15,13 @@ void source_init(struct sof_source __sparse_cache *source, const struct source_o source->audio_stream_params = audio_stream_params; } -size_t source_get_data_available(struct sof_source __sparse_cache *source) +size_t source_get_data_available(struct sof_source *source) { return source->ops->get_data_available(source); } -int source_get_data(struct sof_source __sparse_cache *source, size_t req_size, - void **data_ptr, void **buffer_start, size_t *buffer_size) +int source_get_data(struct sof_source *source, size_t req_size, + void const **data_ptr, void const **buffer_start, size_t *buffer_size) { int ret; @@ -35,7 +35,7 @@ int source_get_data(struct sof_source __sparse_cache *source, size_t req_size, return ret; } -int source_release_data(struct sof_source __sparse_cache *source, size_t free_size) +int source_release_data(struct sof_source *source, size_t free_size) { int ret; @@ -56,47 +56,47 @@ int source_release_data(struct sof_source __sparse_cache *source, size_t free_si return ret; } -size_t source_get_num_of_processed_bytes(struct sof_source __sparse_cache *source) +size_t source_get_num_of_processed_bytes(struct sof_source *source) { return source->num_of_bytes_processed; } -void source_reset_num_of_processed_bytes(struct sof_source __sparse_cache *source) +void source_reset_num_of_processed_bytes(struct sof_source *source) { source->num_of_bytes_processed = 0; } -enum sof_ipc_frame source_get_frm_fmt(struct sof_source __sparse_cache *source) +enum sof_ipc_frame source_get_frm_fmt(struct sof_source *source) { return source->audio_stream_params->frame_fmt; } -enum sof_ipc_frame source_get_valid_fmt(struct sof_source __sparse_cache *source) +enum sof_ipc_frame source_get_valid_fmt(struct sof_source *source) { return source->audio_stream_params->valid_sample_fmt; } -unsigned int source_get_rate(struct sof_source __sparse_cache *source) +unsigned int source_get_rate(struct sof_source *source) { return source->audio_stream_params->rate; } -unsigned int source_get_channels(struct sof_source __sparse_cache *source) +unsigned int source_get_channels(struct sof_source *source) { return source->audio_stream_params->channels; } -uint32_t source_get_buffer_fmt(struct sof_source __sparse_cache *source) +uint32_t source_get_buffer_fmt(struct sof_source *source) { return source->audio_stream_params->buffer_fmt; } -bool source_get_underrun(struct sof_source __sparse_cache *source) +bool source_get_underrun(struct sof_source *source) { return source->audio_stream_params->underrun_permitted; } -int source_set_valid_fmt(struct sof_source __sparse_cache *source, +int source_set_valid_fmt(struct sof_source *source, enum sof_ipc_frame valid_sample_fmt) { source->audio_stream_params->valid_sample_fmt = valid_sample_fmt; @@ -105,7 +105,7 @@ int source_set_valid_fmt(struct sof_source __sparse_cache *source, return 0; } -int source_set_rate(struct sof_source __sparse_cache *source, unsigned int rate) +int source_set_rate(struct sof_source *source, unsigned int rate) { source->audio_stream_params->rate = rate; if (source->ops->on_audio_format_set) @@ -113,7 +113,7 @@ int source_set_rate(struct sof_source __sparse_cache *source, unsigned int rate) return 0; } -int source_set_channels(struct sof_source __sparse_cache *source, unsigned int channels) +int source_set_channels(struct sof_source *source, unsigned int channels) { source->audio_stream_params->channels = channels; if (source->ops->on_audio_format_set) @@ -121,7 +121,7 @@ int source_set_channels(struct sof_source __sparse_cache *source, unsigned int c return 0; } -int source_set_buffer_fmt(struct sof_source __sparse_cache *source, uint32_t buffer_fmt) +int source_set_buffer_fmt(struct sof_source *source, uint32_t buffer_fmt) { source->audio_stream_params->buffer_fmt = buffer_fmt; if (source->ops->on_audio_format_set) @@ -129,7 +129,7 @@ int source_set_buffer_fmt(struct sof_source __sparse_cache *source, uint32_t buf return 0; } -int source_set_underrun(struct sof_source __sparse_cache *source, bool underrun_permitted) +int source_set_underrun(struct sof_source *source, bool underrun_permitted) { source->audio_stream_params->underrun_permitted = underrun_permitted; if (source->ops->on_audio_format_set) @@ -137,19 +137,19 @@ int source_set_underrun(struct sof_source __sparse_cache *source, bool underrun_ return 0; } -size_t source_get_frame_bytes(struct sof_source __sparse_cache *source) +size_t source_get_frame_bytes(struct sof_source *source) { return get_frame_bytes(source_get_frm_fmt(source), source_get_channels(source)); } -size_t source_get_data_frames_available(struct sof_source __sparse_cache *source) +size_t source_get_data_frames_available(struct sof_source *source) { return source_get_data_available(source) / source_get_frame_bytes(source); } -int source_set_params(struct sof_source __sparse_cache *source, +int source_set_params(struct sof_source *source, struct sof_ipc_stream_params *params, bool force_update) { if (source->ops->audio_set_ipc_params) @@ -157,7 +157,7 @@ int source_set_params(struct sof_source __sparse_cache *source, return 0; } -int source_set_alignment_constants(struct sof_source __sparse_cache *source, +int source_set_alignment_constants(struct sof_source *source, const uint32_t byte_align, const uint32_t frame_align_req) { @@ -166,12 +166,12 @@ int source_set_alignment_constants(struct sof_source __sparse_cache *source, return 0; } -void source_set_ibs(struct sof_source __sparse_cache *source, size_t ibs) +void source_set_min_available(struct sof_source *source, size_t min_available) { - source->ibs = ibs; + source->min_available = min_available; } -size_t source_get_ibs(struct sof_source __sparse_cache *source) +size_t source_get_min_available(struct sof_source *source) { - return source->ibs; + return source->min_available; } diff --git a/src/audio/src/CMakeLists.txt b/src/audio/src/CMakeLists.txt index 1884f44ffd6f..2f3d2d561822 100644 --- a/src/audio/src/CMakeLists.txt +++ b/src/audio/src/CMakeLists.txt @@ -1,3 +1,9 @@ # SPDX-License-Identifier: BSD-3-Clause add_local_sources(sof src_generic.c src_hifi2ep.c src_hifi3.c src_hifi4.c src.c) + +if(CONFIG_IPC_MAJOR_3) + add_local_sources(sof src_ipc3.c) +elseif(CONFIG_IPC_MAJOR_4) + add_local_sources(sof src_ipc4.c) +endif() diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_10_21_2500_5000.h b/src/audio/src/coef/src_ipc4_int32_10_21_2500_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_10_21_2500_5000.h rename to src/audio/src/coef/src_ipc4_int32_10_21_2500_5000.h index 065a4222779b..48030954faa5 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_10_21_2500_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_10_21_2500_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_10_21_2500_5000_fir[480] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_10_21_3455_5000.h b/src/audio/src/coef/src_ipc4_int32_10_21_3455_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_10_21_3455_5000.h rename to src/audio/src/coef/src_ipc4_int32_10_21_3455_5000.h index a3e3c6314cdf..c0e8973896ad 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_10_21_3455_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_10_21_3455_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_10_21_3455_5000_fir[640] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_10_21_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_10_21_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_10_21_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_10_21_4535_5000.h index c683105b3be0..86d846a7c806 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_10_21_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_10_21_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_10_21_4535_5000_fir[2320] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_10_9_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_10_9_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_10_9_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_10_9_4535_5000.h index ad3b67a7d7ca..b8ce8872260a 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_10_9_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_10_9_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_10_9_4535_5000_fir[1080] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_16_21_4319_5000.h b/src/audio/src/coef/src_ipc4_int32_16_21_4319_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_16_21_4319_5000.h rename to src/audio/src/coef/src_ipc4_int32_16_21_4319_5000.h index 0fdff4295a78..7afecdab5e9a 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_16_21_4319_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_16_21_4319_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_16_21_4319_5000_fir[1472] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_16_21_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_16_21_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_16_21_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_16_21_4535_5000.h index 0a7175e0512e..f23f95bf5f36 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_16_21_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_16_21_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_16_21_4535_5000_fir[2048] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_16_7_4082_5000.h b/src/audio/src/coef/src_ipc4_int32_16_7_4082_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_16_7_4082_5000.h rename to src/audio/src/coef/src_ipc4_int32_16_7_4082_5000.h index 4daec91d4e62..a28a8804180f 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_16_7_4082_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_16_7_4082_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_16_7_4082_5000_fir[896] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_2268_5000.h b/src/audio/src/coef/src_ipc4_int32_1_2_2268_5000.h similarity index 96% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_2268_5000.h rename to src/audio/src/coef/src_ipc4_int32_1_2_2268_5000.h index c6406b56dfe8..6439054b1a53 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_2268_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_1_2_2268_5000.h @@ -5,7 +5,6 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include #include const int32_t src_int32_1_2_2268_5000_fir[36] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_2500_5000.h b/src/audio/src/coef/src_ipc4_int32_1_2_2500_5000.h similarity index 96% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_2500_5000.h rename to src/audio/src/coef/src_ipc4_int32_1_2_2500_5000.h index 15192f4b0f73..5e619afffb81 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_2500_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_1_2_2500_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_1_2_2500_5000_fir[40] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_2721_5000.h b/src/audio/src/coef/src_ipc4_int32_1_2_2721_5000.h similarity index 96% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_2721_5000.h rename to src/audio/src/coef/src_ipc4_int32_1_2_2721_5000.h index 685fdf20490d..c93526f5354a 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_2721_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_1_2_2721_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_1_2_2721_5000_fir[44] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_3401_5000.h b/src/audio/src/coef/src_ipc4_int32_1_2_3401_5000.h similarity index 97% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_3401_5000.h rename to src/audio/src/coef/src_ipc4_int32_1_2_3401_5000.h index e8573294477c..67b9e495a922 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_3401_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_1_2_3401_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_1_2_3401_5000_fir[60] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_3887_5000.h b/src/audio/src/coef/src_ipc4_int32_1_2_3887_5000.h similarity index 97% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_3887_5000.h rename to src/audio/src/coef/src_ipc4_int32_1_2_3887_5000.h index 9884373e089e..154fa629e140 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_3887_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_1_2_3887_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_1_2_3887_5000_fir[84] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_1_2_4535_5000.h similarity index 98% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_1_2_4535_5000.h index b06b5a258f83..eed23b13668e 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_2_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_1_2_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_1_2_4535_5000_fir[192] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_3_2268_5000.h b/src/audio/src/coef/src_ipc4_int32_1_3_2268_5000.h similarity index 96% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_1_3_2268_5000.h rename to src/audio/src/coef/src_ipc4_int32_1_3_2268_5000.h index 6da1f70dc034..5a455da33297 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_3_2268_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_1_3_2268_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_1_3_2268_5000_fir[52] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_3_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_1_3_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_1_3_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_1_3_4535_5000.h index 8e45ac26f184..a22d7c3da8e1 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_3_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_1_3_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_1_3_4535_5000_fir[260] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_4_1512_5000.h b/src/audio/src/coef/src_ipc4_int32_1_4_1512_5000.h similarity index 96% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_1_4_1512_5000.h rename to src/audio/src/coef/src_ipc4_int32_1_4_1512_5000.h index f98ba0f9be7c..5426a9ff0404 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_4_1512_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_1_4_1512_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_1_4_1512_5000_fir[52] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_4_2268_5000.h b/src/audio/src/coef/src_ipc4_int32_1_4_2268_5000.h similarity index 97% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_1_4_2268_5000.h rename to src/audio/src/coef/src_ipc4_int32_1_4_2268_5000.h index 8df1653d8afd..d375e6625f1f 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_4_2268_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_1_4_2268_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_1_4_2268_5000_fir[60] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_4_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_1_4_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_1_4_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_1_4_4535_5000.h index bab9a1df434b..9522110b2d66 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_4_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_1_4_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_1_4_4535_5000_fir[332] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_6_1134_5000.h b/src/audio/src/coef/src_ipc4_int32_1_6_1134_5000.h similarity index 97% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_1_6_1134_5000.h rename to src/audio/src/coef/src_ipc4_int32_1_6_1134_5000.h index 7342c541f490..02afd78663a4 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_1_6_1134_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_1_6_1134_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_1_6_1134_5000_fir[68] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_20_21_1250_5000.h b/src/audio/src/coef/src_ipc4_int32_20_21_1250_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_20_21_1250_5000.h rename to src/audio/src/coef/src_ipc4_int32_20_21_1250_5000.h index 0bda24345ace..dfd8d462b9ec 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_20_21_1250_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_20_21_1250_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_20_21_1250_5000_fir[320] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_20_21_2500_5000.h b/src/audio/src/coef/src_ipc4_int32_20_21_2500_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_20_21_2500_5000.h rename to src/audio/src/coef/src_ipc4_int32_20_21_2500_5000.h index 1624d3b5d039..021c9572342d 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_20_21_2500_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_20_21_2500_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_20_21_2500_5000_fir[560] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_20_21_3125_5000.h b/src/audio/src/coef/src_ipc4_int32_20_21_3125_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_20_21_3125_5000.h rename to src/audio/src/coef/src_ipc4_int32_20_21_3125_5000.h index 3063a4cb793b..09a71eb3dadd 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_20_21_3125_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_20_21_3125_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_20_21_3125_5000_fir[640] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_20_21_4167_5000.h b/src/audio/src/coef/src_ipc4_int32_20_21_4167_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_20_21_4167_5000.h rename to src/audio/src/coef/src_ipc4_int32_20_21_4167_5000.h index 4b83c9f4e32a..5eb7c718b39c 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_20_21_4167_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_20_21_4167_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_20_21_4167_5000_fir[1200] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_20_21_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_20_21_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_20_21_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_20_21_4535_5000.h index 2ebde5a89b7c..75e59fa53554 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_20_21_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_20_21_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_20_21_4535_5000_fir[2080] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_20_7_2976_5000.h b/src/audio/src/coef/src_ipc4_int32_20_7_2976_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_20_7_2976_5000.h rename to src/audio/src/coef/src_ipc4_int32_20_7_2976_5000.h index ffb4fbf6abbf..0e076dfa6b22 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_20_7_2976_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_20_7_2976_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_20_7_2976_5000_fir[560] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_10_2500_5000.h b/src/audio/src/coef/src_ipc4_int32_21_10_2500_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_10_2500_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_10_2500_5000.h index 0f2abed0ca46..8e59eac928a1 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_10_2500_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_10_2500_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_10_2500_5000_fir[504] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_10_3455_5000.h b/src/audio/src/coef/src_ipc4_int32_21_10_3455_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_10_3455_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_10_3455_5000.h index 9b1bcf324af2..2d3f3b0c4a22 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_10_3455_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_10_3455_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_10_3455_5000_fir[756] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_10_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_21_10_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_10_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_10_4535_5000.h index 35f53ab94add..ef37e5b74280 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_10_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_10_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_10_4535_5000_fir[2520] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_16_4319_5000.h b/src/audio/src/coef/src_ipc4_int32_21_16_4319_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_16_4319_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_16_4319_5000.h index a51f25af699b..be79e187c8a2 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_16_4319_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_16_4319_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_16_4319_5000_fir[1596] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_16_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_21_16_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_16_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_16_4535_5000.h index 2c82d535369f..9afb6408f986 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_16_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_16_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_16_4535_5000_fir[2436] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_20_1250_5000.h b/src/audio/src/coef/src_ipc4_int32_21_20_1250_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_20_1250_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_20_1250_5000.h index 1c952f207c14..a420745baa54 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_20_1250_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_20_1250_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_20_1250_5000_fir[420] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_20_2500_5000.h b/src/audio/src/coef/src_ipc4_int32_21_20_2500_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_20_2500_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_20_2500_5000.h index d5e0479f2c3b..87c0f8a79e01 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_20_2500_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_20_2500_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_20_2500_5000_fir[504] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_20_3125_5000.h b/src/audio/src/coef/src_ipc4_int32_21_20_3125_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_20_3125_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_20_3125_5000.h index 24d8d957b490..692597e7093e 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_20_3125_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_20_3125_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_20_3125_5000_fir[672] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_20_4167_5000.h b/src/audio/src/coef/src_ipc4_int32_21_20_4167_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_20_4167_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_20_4167_5000.h index 1511079ef865..a5125e18b35f 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_20_4167_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_20_4167_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_20_4167_5000_fir[1260] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_20_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_21_20_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_20_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_20_4535_5000.h index 2a9cc7a4bdaf..85f20e60c536 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_20_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_20_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_20_4535_5000_fir[2268] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_2_3239_5000.h b/src/audio/src/coef/src_ipc4_int32_21_2_3239_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_2_3239_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_2_3239_5000.h index f64f91cda9b6..d4a99940d49c 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_2_3239_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_2_3239_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_2_3239_5000_fir[672] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_32_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_21_32_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_32_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_32_4535_5000.h index a8f8d8a032c8..838aeab0b802 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_32_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_32_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_32_4535_5000_fir[3612] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_40_2381_5000.h b/src/audio/src/coef/src_ipc4_int32_21_40_2381_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_40_2381_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_40_2381_5000.h index 41bbf11c3a08..bcefb4d03299 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_40_2381_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_40_2381_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_40_2381_5000_fir[924] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_40_3968_5000.h b/src/audio/src/coef/src_ipc4_int32_21_40_3968_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_40_3968_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_40_3968_5000.h index 66b78a30d922..ce9e0cb6ddb1 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_40_3968_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_40_3968_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_40_3968_5000_fir[1680] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_4_1080_5000.h b/src/audio/src/coef/src_ipc4_int32_21_4_1080_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_4_1080_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_4_1080_5000.h index 6b183e05633f..de8beea74d01 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_4_1080_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_4_1080_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_4_1080_5000_fir[336] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_4_3239_5000.h b/src/audio/src/coef/src_ipc4_int32_21_4_3239_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_4_3239_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_4_3239_5000.h index 18b2cb0702e6..5b8aaf04755c 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_4_3239_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_4_3239_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_4_3239_5000_fir[672] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_5_1728_5000.h b/src/audio/src/coef/src_ipc4_int32_21_5_1728_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_5_1728_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_5_1728_5000.h index 95cdfda00bdf..0f6a4110f090 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_5_1728_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_5_1728_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_5_1728_5000_fir[420] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_5_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_21_5_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_5_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_5_4535_5000.h index ae1996ab8df3..e7e0f09a3d8f 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_5_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_5_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_5_4535_5000_fir[2184] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_80_3968_5000.h b/src/audio/src/coef/src_ipc4_int32_21_80_3968_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_80_3968_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_80_3968_5000.h index 4d20797dfb87..71ed1ba54db3 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_80_3968_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_80_3968_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_80_3968_5000_fir[3360] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_8_2160_5000.h b/src/audio/src/coef/src_ipc4_int32_21_8_2160_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_8_2160_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_8_2160_5000.h index da333448465a..54ccaae7be81 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_8_2160_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_8_2160_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_8_2160_5000_fir[420] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_8_3239_5000.h b/src/audio/src/coef/src_ipc4_int32_21_8_3239_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_8_3239_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_8_3239_5000.h index 748d19d4df8e..3c60f57466f6 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_8_3239_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_8_3239_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_8_3239_5000_fir[672] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_8_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_21_8_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_21_8_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_21_8_4535_5000.h index 43c10ee4f0b5..77061aec771d 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_21_8_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_21_8_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_21_8_4535_5000_fir[2436] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_2_1_2268_5000.h b/src/audio/src/coef/src_ipc4_int32_2_1_2268_5000.h similarity index 96% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_2_1_2268_5000.h rename to src/audio/src/coef/src_ipc4_int32_2_1_2268_5000.h index bce5bd4c6c05..5278f76504fd 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_2_1_2268_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_2_1_2268_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_2_1_2268_5000_fir[48] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_2_1_2500_5000.h b/src/audio/src/coef/src_ipc4_int32_2_1_2500_5000.h similarity index 96% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_2_1_2500_5000.h rename to src/audio/src/coef/src_ipc4_int32_2_1_2500_5000.h index 021876ed8312..ccd0fce5856c 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_2_1_2500_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_2_1_2500_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_2_1_2500_5000_fir[40] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_2_1_2721_5000.h b/src/audio/src/coef/src_ipc4_int32_2_1_2721_5000.h similarity index 96% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_2_1_2721_5000.h rename to src/audio/src/coef/src_ipc4_int32_2_1_2721_5000.h index 693de6c34e28..eaa8f4c38814 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_2_1_2721_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_2_1_2721_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_2_1_2721_5000_fir[48] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_2_1_3401_5000.h b/src/audio/src/coef/src_ipc4_int32_2_1_3401_5000.h similarity index 97% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_2_1_3401_5000.h rename to src/audio/src/coef/src_ipc4_int32_2_1_3401_5000.h index cbf4b40708e5..93afa72dc538 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_2_1_3401_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_2_1_3401_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_2_1_3401_5000_fir[72] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_2_1_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_2_1_4535_5000.h similarity index 98% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_2_1_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_2_1_4535_5000.h index ec672dfd00be..baf8f5fb4cfd 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_2_1_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_2_1_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_2_1_4535_5000_fir[240] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_2_3_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_2_3_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_2_3_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_2_3_4535_5000.h index 513075e3ff2e..9adf487a73be 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_2_3_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_2_3_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_2_3_4535_5000_fir[264] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_32_21_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_32_21_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_32_21_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_32_21_4535_5000.h index 92ab6b6e75e9..89c7e885a064 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_32_21_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_32_21_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_32_21_4535_5000_fir[3840] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_3_1_2268_5000.h b/src/audio/src/coef/src_ipc4_int32_3_1_2268_5000.h similarity index 97% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_3_1_2268_5000.h rename to src/audio/src/coef/src_ipc4_int32_3_1_2268_5000.h index dec77767fb6f..02ac3227cec4 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_3_1_2268_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_3_1_2268_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_3_1_2268_5000_fir[72] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_3_1_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_3_1_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_3_1_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_3_1_4535_5000.h index 488055f17f1d..6f3af03b34fb 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_3_1_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_3_1_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_3_1_4535_5000_fir[336] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_3_2_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_3_2_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_3_2_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_3_2_4535_5000.h index e1beb7178778..7b528ca29668 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_3_2_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_3_2_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_3_2_4535_5000_fir[324] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_3_4_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_3_4_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_3_4_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_3_4_4535_5000.h index 9be2b9b6a3f4..87183cbf7fab 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_3_4_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_3_4_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_3_4_4535_5000_fir[360] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_40_21_2381_5000.h b/src/audio/src/coef/src_ipc4_int32_40_21_2381_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_40_21_2381_5000.h rename to src/audio/src/coef/src_ipc4_int32_40_21_2381_5000.h index 757fee8933dc..5a0751a569e6 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_40_21_2381_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_40_21_2381_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_40_21_2381_5000_fir[960] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_40_21_2976_5000.h b/src/audio/src/coef/src_ipc4_int32_40_21_2976_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_40_21_2976_5000.h rename to src/audio/src/coef/src_ipc4_int32_40_21_2976_5000.h index 9fbb7a8f57de..6df84d8ec71b 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_40_21_2976_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_40_21_2976_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_40_21_2976_5000_fir[1120] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_40_21_3968_5000.h b/src/audio/src/coef/src_ipc4_int32_40_21_3968_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_40_21_3968_5000.h rename to src/audio/src/coef/src_ipc4_int32_40_21_3968_5000.h index 021b6075ac39..eb417efac43f 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_40_21_3968_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_40_21_3968_5000.h @@ -5,7 +5,6 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include #include const int32_t src_int32_40_21_3968_5000_fir[2080] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_40_7_2976_5000.h b/src/audio/src/coef/src_ipc4_int32_40_7_2976_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_40_7_2976_5000.h rename to src/audio/src/coef/src_ipc4_int32_40_7_2976_5000.h index 5058110df7be..ec29d256dc23 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_40_7_2976_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_40_7_2976_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_40_7_2976_5000_fir[1120] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_4_1_1134_5000.h b/src/audio/src/coef/src_ipc4_int32_4_1_1134_5000.h similarity index 97% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_4_1_1134_5000.h rename to src/audio/src/coef/src_ipc4_int32_4_1_1134_5000.h index 45dfaa500a92..94dc4fe2d061 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_4_1_1134_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_4_1_1134_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_4_1_1134_5000_fir[64] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_4_1_1512_5000.h b/src/audio/src/coef/src_ipc4_int32_4_1_1512_5000.h similarity index 97% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_4_1_1512_5000.h rename to src/audio/src/coef/src_ipc4_int32_4_1_1512_5000.h index 67a6f4e65363..d24439378e7d 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_4_1_1512_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_4_1_1512_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_4_1_1512_5000_fir[64] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_4_1_2268_5000.h b/src/audio/src/coef/src_ipc4_int32_4_1_2268_5000.h similarity index 97% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_4_1_2268_5000.h rename to src/audio/src/coef/src_ipc4_int32_4_1_2268_5000.h index fa992ea0fc89..6debcd407b01 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_4_1_2268_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_4_1_2268_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_4_1_2268_5000_fir[80] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_4_1_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_4_1_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_4_1_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_4_1_4535_5000.h index db0a1f73fbae..c54bcbaec041 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_4_1_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_4_1_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_4_1_4535_5000_fir[416] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_4_21_1080_5000.h b/src/audio/src/coef/src_ipc4_int32_4_21_1080_5000.h similarity index 98% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_4_21_1080_5000.h rename to src/audio/src/coef/src_ipc4_int32_4_21_1080_5000.h index 85e550434456..9087729b2c20 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_4_21_1080_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_4_21_1080_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_4_21_1080_5000_fir[224] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_4_21_3239_5000.h b/src/audio/src/coef/src_ipc4_int32_4_21_3239_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_4_21_3239_5000.h rename to src/audio/src/coef/src_ipc4_int32_4_21_3239_5000.h index 06b3e92c97da..8bccc923b22b 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_4_21_3239_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_4_21_3239_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_4_21_3239_5000_fir[512] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_4_3_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_4_3_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_4_3_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_4_3_4535_5000.h index 472e6cb9b2ce..0ec9006187bc 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_4_3_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_4_3_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_4_3_4535_5000_fir[432] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_5_21_1728_5000.h b/src/audio/src/coef/src_ipc4_int32_5_21_1728_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_5_21_1728_5000.h rename to src/audio/src/coef/src_ipc4_int32_5_21_1728_5000.h index dc6d468dd22f..6996b1b22e27 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_5_21_1728_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_5_21_1728_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_5_21_1728_5000_fir[320] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_5_21_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_5_21_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_5_21_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_5_21_4535_5000.h index e7b58e37f993..e6a61dde3ab1 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_5_21_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_5_21_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_5_21_4535_5000_fir[1740] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_5_7_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_5_7_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_5_7_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_5_7_4535_5000.h index 271b6d9e8e28..a53184414f6a 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_5_7_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_5_7_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_5_7_4535_5000_fir[680] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_6_1_1134_5000.h b/src/audio/src/coef/src_ipc4_int32_6_1_1134_5000.h similarity index 97% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_6_1_1134_5000.h rename to src/audio/src/coef/src_ipc4_int32_6_1_1134_5000.h index 006678f426a8..0a0fdc47204b 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_6_1_1134_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_6_1_1134_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_6_1_1134_5000_fir[96] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_7_3_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_7_3_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_7_3_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_7_3_4535_5000.h index 33a58e2228ec..182a13ff7da8 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_7_3_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_7_3_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_7_3_4535_5000_fir[728] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_7_5_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_7_5_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_7_5_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_7_5_4535_5000.h index 3704f52287df..9892f3419692 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_7_5_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_7_5_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_7_5_4535_5000_fir[812] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_7_8_1361_5000.h b/src/audio/src/coef/src_ipc4_int32_7_8_1361_5000.h similarity index 98% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_7_8_1361_5000.h rename to src/audio/src/coef/src_ipc4_int32_7_8_1361_5000.h index b21195f8e7d8..caa97de96c8a 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_7_8_1361_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_7_8_1361_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_7_8_1361_5000_fir[140] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_7_8_2468_5000.h b/src/audio/src/coef/src_ipc4_int32_7_8_2468_5000.h similarity index 98% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_7_8_2468_5000.h rename to src/audio/src/coef/src_ipc4_int32_7_8_2468_5000.h index 5dc8df90db50..f47683dadc66 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_7_8_2468_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_7_8_2468_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_7_8_2468_5000_fir[196] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_7_8_2721_5000.h b/src/audio/src/coef/src_ipc4_int32_7_8_2721_5000.h similarity index 98% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_7_8_2721_5000.h rename to src/audio/src/coef/src_ipc4_int32_7_8_2721_5000.h index 3bbf0802f8ed..1d53d3f887c1 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_7_8_2721_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_7_8_2721_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_7_8_2721_5000_fir[224] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_7_8_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_7_8_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_7_8_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_7_8_4535_5000.h index 05b14977a701..afbc84f69fb1 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_7_8_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_7_8_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_7_8_4535_5000_fir[840] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_21_2160_5000.h b/src/audio/src/coef/src_ipc4_int32_8_21_2160_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_8_21_2160_5000.h rename to src/audio/src/coef/src_ipc4_int32_8_21_2160_5000.h index 09735d1a5eff..a8db0edae0f1 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_21_2160_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_8_21_2160_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_8_21_2160_5000_fir[384] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_21_3239_5000.h b/src/audio/src/coef/src_ipc4_int32_8_21_3239_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_8_21_3239_5000.h rename to src/audio/src/coef/src_ipc4_int32_8_21_3239_5000.h index 34df502e0431..6c94c2eb5b1f 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_21_3239_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_8_21_3239_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_8_21_3239_5000_fir[544] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_21_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_8_21_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_8_21_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_8_21_4535_5000.h index 1e923f32b334..6ed9f654954f 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_21_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_8_21_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_8_21_4535_5000_fir[1984] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_7_1361_5000.h b/src/audio/src/coef/src_ipc4_int32_8_7_1361_5000.h similarity index 98% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_8_7_1361_5000.h rename to src/audio/src/coef/src_ipc4_int32_8_7_1361_5000.h index 2ac3837f35a3..78b22782c66a 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_7_1361_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_8_7_1361_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_8_7_1361_5000_fir[160] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_7_2468_5000.h b/src/audio/src/coef/src_ipc4_int32_8_7_2468_5000.h similarity index 98% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_8_7_2468_5000.h rename to src/audio/src/coef/src_ipc4_int32_8_7_2468_5000.h index 9e04cea51d53..f8c8b11efddc 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_7_2468_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_8_7_2468_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_8_7_2468_5000_fir[192] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_7_2721_5000.h b/src/audio/src/coef/src_ipc4_int32_8_7_2721_5000.h similarity index 98% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_8_7_2721_5000.h rename to src/audio/src/coef/src_ipc4_int32_8_7_2721_5000.h index 40ff2e3b153e..b71b96071313 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_7_2721_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_8_7_2721_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_8_7_2721_5000_fir[192] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_7_4082_5000.h b/src/audio/src/coef/src_ipc4_int32_8_7_4082_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_8_7_4082_5000.h rename to src/audio/src/coef/src_ipc4_int32_8_7_4082_5000.h index 6d58cd3f2a4c..2e02d9c80455 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_7_4082_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_8_7_4082_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_8_7_4082_5000_fir[480] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_7_4535_5000.h b/src/audio/src/coef/src_ipc4_int32_8_7_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_8_7_4535_5000.h rename to src/audio/src/coef/src_ipc4_int32_8_7_4535_5000.h index b5d8f6e0dec5..8754d53b2cad 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_8_7_4535_5000.h +++ b/src/audio/src/coef/src_ipc4_int32_8_7_4535_5000.h @@ -5,7 +5,7 @@ */ /** \cond GENERATED_BY_TOOLS_TUNE_SRC */ -#include + #include const int32_t src_int32_8_7_4535_5000_fir[896] = { diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_define.h b/src/audio/src/coef/src_ipc4_int32_define.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_define.h rename to src/audio/src/coef/src_ipc4_int32_define.h diff --git a/src/include/sof/audio/coefficients/src/src_ipc4_int32_table.h b/src/audio/src/coef/src_ipc4_int32_table.h similarity index 60% rename from src/include/sof/audio/coefficients/src/src_ipc4_int32_table.h rename to src/audio/src/coef/src_ipc4_int32_table.h index 1530b9f9d442..98f7cc0e9f09 100644 --- a/src/include/sof/audio/coefficients/src/src_ipc4_int32_table.h +++ b/src/audio/src/coef/src_ipc4_int32_table.h @@ -10,94 +10,93 @@ #define __SOF_AUDIO_COEFFICIENTS_SRC_SRC_IPC4_INT32_TABLE_H__ /* SRC conversions */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "src_ipc4_int32_1_2_2268_5000.h" +#include "src_ipc4_int32_1_2_2500_5000.h" +#include "src_ipc4_int32_1_2_2721_5000.h" +#include "src_ipc4_int32_1_2_3401_5000.h" +#include "src_ipc4_int32_1_2_3887_5000.h" +#include "src_ipc4_int32_1_2_4535_5000.h" +#include "src_ipc4_int32_1_3_2268_5000.h" +#include "src_ipc4_int32_1_3_4535_5000.h" +#include "src_ipc4_int32_1_4_1512_5000.h" +#include "src_ipc4_int32_1_4_2268_5000.h" +#include "src_ipc4_int32_1_4_4535_5000.h" +#include "src_ipc4_int32_1_6_1134_5000.h" +#include "src_ipc4_int32_2_1_2268_5000.h" +#include "src_ipc4_int32_2_1_2500_5000.h" +#include "src_ipc4_int32_2_1_2721_5000.h" +#include "src_ipc4_int32_2_1_3401_5000.h" +#include "src_ipc4_int32_2_1_4535_5000.h" +#include "src_ipc4_int32_2_3_4535_5000.h" +#include "src_ipc4_int32_3_1_2268_5000.h" +#include "src_ipc4_int32_3_1_4535_5000.h" +#include "src_ipc4_int32_3_2_4535_5000.h" +#include "src_ipc4_int32_3_4_4535_5000.h" +#include "src_ipc4_int32_4_1_1134_5000.h" +#include "src_ipc4_int32_4_1_1512_5000.h" +#include "src_ipc4_int32_4_1_2268_5000.h" +#include "src_ipc4_int32_4_1_4535_5000.h" +#include "src_ipc4_int32_4_3_4535_5000.h" +#include "src_ipc4_int32_4_21_1080_5000.h" +#include "src_ipc4_int32_4_21_3239_5000.h" +#include "src_ipc4_int32_5_7_4535_5000.h" +#include "src_ipc4_int32_5_21_1728_5000.h" +#include "src_ipc4_int32_5_21_4535_5000.h" +#include "src_ipc4_int32_6_1_1134_5000.h" +#include "src_ipc4_int32_7_3_4535_5000.h" +#include "src_ipc4_int32_7_5_4535_5000.h" +#include "src_ipc4_int32_7_8_1361_5000.h" +#include "src_ipc4_int32_7_8_2468_5000.h" +#include "src_ipc4_int32_7_8_2721_5000.h" +#include "src_ipc4_int32_7_8_4535_5000.h" +#include "src_ipc4_int32_8_7_1361_5000.h" +#include "src_ipc4_int32_8_7_2468_5000.h" +#include "src_ipc4_int32_8_7_2721_5000.h" +#include "src_ipc4_int32_8_7_4082_5000.h" +#include "src_ipc4_int32_8_7_4535_5000.h" +#include "src_ipc4_int32_8_21_2160_5000.h" +#include "src_ipc4_int32_8_21_3239_5000.h" +#include "src_ipc4_int32_8_21_4535_5000.h" +#include "src_ipc4_int32_10_9_4535_5000.h" +#include "src_ipc4_int32_10_21_2500_5000.h" +#include "src_ipc4_int32_10_21_3455_5000.h" +#include "src_ipc4_int32_10_21_4535_5000.h" +#include "src_ipc4_int32_16_7_4082_5000.h" +#include "src_ipc4_int32_16_21_4319_5000.h" +#include "src_ipc4_int32_16_21_4535_5000.h" +#include "src_ipc4_int32_20_7_2976_5000.h" +#include "src_ipc4_int32_20_21_1250_5000.h" +#include "src_ipc4_int32_20_21_2500_5000.h" +#include "src_ipc4_int32_20_21_3125_5000.h" +#include "src_ipc4_int32_20_21_4167_5000.h" +#include "src_ipc4_int32_20_21_4535_5000.h" +#include "src_ipc4_int32_21_2_3239_5000.h" +#include "src_ipc4_int32_21_4_1080_5000.h" +#include "src_ipc4_int32_21_4_3239_5000.h" +#include "src_ipc4_int32_21_5_1728_5000.h" +#include "src_ipc4_int32_21_5_4535_5000.h" +#include "src_ipc4_int32_21_8_2160_5000.h" +#include "src_ipc4_int32_21_8_3239_5000.h" +#include "src_ipc4_int32_21_8_4535_5000.h" +#include "src_ipc4_int32_21_10_2500_5000.h" +#include "src_ipc4_int32_21_10_3455_5000.h" +#include "src_ipc4_int32_21_10_4535_5000.h" +#include "src_ipc4_int32_21_16_4319_5000.h" +#include "src_ipc4_int32_21_16_4535_5000.h" +#include "src_ipc4_int32_21_20_1250_5000.h" +#include "src_ipc4_int32_21_20_2500_5000.h" +#include "src_ipc4_int32_21_20_3125_5000.h" +#include "src_ipc4_int32_21_20_4167_5000.h" +#include "src_ipc4_int32_21_20_4535_5000.h" +#include "src_ipc4_int32_21_32_4535_5000.h" +#include "src_ipc4_int32_21_40_2381_5000.h" +#include "src_ipc4_int32_21_40_3968_5000.h" +#include "src_ipc4_int32_21_80_3968_5000.h" +#include "src_ipc4_int32_32_21_4535_5000.h" +#include "src_ipc4_int32_40_7_2976_5000.h" +#include "src_ipc4_int32_40_21_2381_5000.h" +#include "src_ipc4_int32_40_21_2976_5000.h" +#include "src_ipc4_int32_40_21_3968_5000.h" #include /* SRC table */ diff --git a/src/audio/src/coef/src_lite_ipc4_int32_define.h b/src/audio/src/coef/src_lite_ipc4_int32_define.h new file mode 100644 index 000000000000..c690f3c7338f --- /dev/null +++ b/src/audio/src/coef/src_lite_ipc4_int32_define.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + * Author: Fabiola Jasinska + */ + +#ifndef __SOF_AUDIO_COEFFICIENTS_SRC_SRC_IPC4_INT32_DEFINE_H__ +#define __SOF_AUDIO_COEFFICIENTS_SRC_SRC_IPC4_INT32_DEFINE_H__ + +/* SRC constants */ +#define MAX_FIR_DELAY_SIZE 730 +#define MAX_OUT_DELAY_SIZE 900 +#define MAX_BLK_IN 80 +#define MAX_BLK_OUT 40 +#define NUM_IN_FS 16 +#define NUM_OUT_FS 10 +#define STAGE1_TIMES_MAX 32 +#define STAGE2_TIMES_MAX 32 +#define STAGE_BUF_SIZE 672 +#define NUM_ALL_COEFFICIENTS 69224 + +#endif /* __SOF_AUDIO_COEFFICIENTS_SRC_SRC_IPC4_INT32_DEFINE_H__ */ diff --git a/src/audio/src/coef/src_lite_ipc4_int32_table.h b/src/audio/src/coef/src_lite_ipc4_int32_table.h new file mode 100644 index 000000000000..90f6b6d15c8a --- /dev/null +++ b/src/audio/src/coef/src_lite_ipc4_int32_table.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + */ + +/** \cond GENERATED_BY_TOOLS_TUNE_SRC */ + +#ifndef __SOF_AUDIO_COEFFICIENTS_SRC_src_IPC4_INT32_TABLE_H__ +#define __SOF_AUDIO_COEFFICIENTS_SRC_src_IPC4_INT32_TABLE_H__ + +/* SRC conversions */ +#include "src_ipc4_int32_1_2_4535_5000.h" +#include "src_ipc4_int32_10_21_3455_5000.h" +#include "src_ipc4_int32_1_3_4535_5000.h" +#include "src_ipc4_int32_3_2_4535_5000.h" +#include "src_ipc4_int32_8_7_4535_5000.h" +#include "src_ipc4_int32_16_21_4535_5000.h" +#include "src_ipc4_int32_20_21_4167_5000.h" + +#include + +/* SRC table */ +int32_t src_fir_one = Q_CONVERT_FLOAT(1, 30); +struct src_stage src_int32_1_1_0_0 = { 0, 0, 1, 1, 1, 1, 1, 0, -1, &src_fir_one }; +struct src_stage src_int32_0_0_0_0 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, &src_fir_one }; +int src_in_fs[3] = { 32000, 44100, 48000}; +int src_out_fs[2] = {16000, 48000}; + +struct src_stage *src_table1[2][3] = { + { &src_int32_1_2_4535_5000, &src_int32_10_21_3455_5000, + &src_int32_1_3_4535_5000 }, + { &src_int32_3_2_4535_5000, &src_int32_8_7_4535_5000, &src_int32_1_1_0_0 } +}; + +struct src_stage *src_table2[2][3] = { + { &src_int32_1_1_0_0, &src_int32_16_21_4535_5000, &src_int32_1_1_0_0 }, + { &src_int32_1_1_0_0, &src_int32_20_21_4167_5000, &src_int32_1_1_0_0 } +}; + +#endif /* __SOF_AUDIO_COEFFICIENTS_SRC_src_IPC4_INT32_TABLE_H__ */ + +/** \endcond */ diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_1_2_2268_5000.h b/src/audio/src/coef/src_small_int32_1_2_2268_5000.h similarity index 96% rename from src/include/sof/audio/coefficients/src/src_small_int32_1_2_2268_5000.h rename to src/audio/src/coef/src_small_int32_1_2_2268_5000.h index 303d9f2520fc..e47e44345aa9 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_1_2_2268_5000.h +++ b/src/audio/src/coef/src_small_int32_1_2_2268_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_1_2_2268_5000_fir[40] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_1_2_4535_5000.h b/src/audio/src/coef/src_small_int32_1_2_4535_5000.h similarity index 98% rename from src/include/sof/audio/coefficients/src/src_small_int32_1_2_4535_5000.h rename to src/audio/src/coef/src_small_int32_1_2_4535_5000.h index 928e3448d58a..bc677003b18b 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_1_2_4535_5000.h +++ b/src/audio/src/coef/src_small_int32_1_2_4535_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_1_2_4535_5000_fir[200] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_1_3_2268_5000.h b/src/audio/src/coef/src_small_int32_1_3_2268_5000.h similarity index 96% rename from src/include/sof/audio/coefficients/src/src_small_int32_1_3_2268_5000.h rename to src/audio/src/coef/src_small_int32_1_3_2268_5000.h index f85f893ff16b..b56245e5b61c 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_1_3_2268_5000.h +++ b/src/audio/src/coef/src_small_int32_1_3_2268_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_1_3_2268_5000_fir[56] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_1_3_4535_5000.h b/src/audio/src/coef/src_small_int32_1_3_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_small_int32_1_3_4535_5000.h rename to src/audio/src/coef/src_small_int32_1_3_4535_5000.h index 972926179ed2..9086231b48b1 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_1_3_4535_5000.h +++ b/src/audio/src/coef/src_small_int32_1_3_4535_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_1_3_4535_5000_fir[268] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_20_21_4167_5000.h b/src/audio/src/coef/src_small_int32_20_21_4167_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_small_int32_20_21_4167_5000.h rename to src/audio/src/coef/src_small_int32_20_21_4167_5000.h index 4d674379a2f3..d8c4224bc811 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_20_21_4167_5000.h +++ b/src/audio/src/coef/src_small_int32_20_21_4167_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_20_21_4167_5000_fir[1120] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_21_20_4167_5000.h b/src/audio/src/coef/src_small_int32_21_20_4167_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_small_int32_21_20_4167_5000.h rename to src/audio/src/coef/src_small_int32_21_20_4167_5000.h index e952c70e4a01..19872b67f0fd 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_21_20_4167_5000.h +++ b/src/audio/src/coef/src_small_int32_21_20_4167_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_21_20_4167_5000_fir[1092] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_2_1_2268_5000.h b/src/audio/src/coef/src_small_int32_2_1_2268_5000.h similarity index 96% rename from src/include/sof/audio/coefficients/src/src_small_int32_2_1_2268_5000.h rename to src/audio/src/coef/src_small_int32_2_1_2268_5000.h index 494c2e75676a..cfc1c9c42728 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_2_1_2268_5000.h +++ b/src/audio/src/coef/src_small_int32_2_1_2268_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_2_1_2268_5000_fir[40] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_2_1_4535_5000.h b/src/audio/src/coef/src_small_int32_2_1_4535_5000.h similarity index 98% rename from src/include/sof/audio/coefficients/src/src_small_int32_2_1_4535_5000.h rename to src/audio/src/coef/src_small_int32_2_1_4535_5000.h index 200de76bf2b1..31e1d3e361f7 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_2_1_4535_5000.h +++ b/src/audio/src/coef/src_small_int32_2_1_4535_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_2_1_4535_5000_fir[200] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_2_3_4535_5000.h b/src/audio/src/coef/src_small_int32_2_3_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_small_int32_2_3_4535_5000.h rename to src/audio/src/coef/src_small_int32_2_3_4535_5000.h index 206f0a03a635..4c64cb49c4d1 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_2_3_4535_5000.h +++ b/src/audio/src/coef/src_small_int32_2_3_4535_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_2_3_4535_5000_fir[272] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_3_1_2268_5000.h b/src/audio/src/coef/src_small_int32_3_1_2268_5000.h similarity index 96% rename from src/include/sof/audio/coefficients/src/src_small_int32_3_1_2268_5000.h rename to src/audio/src/coef/src_small_int32_3_1_2268_5000.h index e6f4bc6216ea..f8a379ed0b3f 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_3_1_2268_5000.h +++ b/src/audio/src/coef/src_small_int32_3_1_2268_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_3_1_2268_5000_fir[60] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_3_1_4535_5000.h b/src/audio/src/coef/src_small_int32_3_1_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_small_int32_3_1_4535_5000.h rename to src/audio/src/coef/src_small_int32_3_1_4535_5000.h index 306409d4d04e..e7d2c66009f6 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_3_1_4535_5000.h +++ b/src/audio/src/coef/src_small_int32_3_1_4535_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_3_1_4535_5000_fir[276] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_3_2_4535_5000.h b/src/audio/src/coef/src_small_int32_3_2_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_small_int32_3_2_4535_5000.h rename to src/audio/src/coef/src_small_int32_3_2_4535_5000.h index 42f56dd77c6c..c221fb86dbdb 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_3_2_4535_5000.h +++ b/src/audio/src/coef/src_small_int32_3_2_4535_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_3_2_4535_5000_fir[276] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_3_4_4535_5000.h b/src/audio/src/coef/src_small_int32_3_4_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_small_int32_3_4_4535_5000.h rename to src/audio/src/coef/src_small_int32_3_4_4535_5000.h index f930daf54992..f0d1527b74aa 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_3_4_4535_5000.h +++ b/src/audio/src/coef/src_small_int32_3_4_4535_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_3_4_4535_5000_fir[348] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_4_3_4535_5000.h b/src/audio/src/coef/src_small_int32_4_3_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_small_int32_4_3_4535_5000.h rename to src/audio/src/coef/src_small_int32_4_3_4535_5000.h index 3505f63d196b..8cf22c9a9eb7 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_4_3_4535_5000.h +++ b/src/audio/src/coef/src_small_int32_4_3_4535_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_4_3_4535_5000_fir[352] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_4_5_4535_5000.h b/src/audio/src/coef/src_small_int32_4_5_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_small_int32_4_5_4535_5000.h rename to src/audio/src/coef/src_small_int32_4_5_4535_5000.h index 9af3feb400ec..10c49bd6f82f 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_4_5_4535_5000.h +++ b/src/audio/src/coef/src_small_int32_4_5_4535_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_4_5_4535_5000_fir[448] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_5_4_4535_5000.h b/src/audio/src/coef/src_small_int32_5_4_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_small_int32_5_4_4535_5000.h rename to src/audio/src/coef/src_small_int32_5_4_4535_5000.h index d608c8f5c0e1..3e8c24769c44 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_5_4_4535_5000.h +++ b/src/audio/src/coef/src_small_int32_5_4_4535_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_5_4_4535_5000_fir[440] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_5_6_4354_5000.h b/src/audio/src/coef/src_small_int32_5_6_4354_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_small_int32_5_6_4354_5000.h rename to src/audio/src/coef/src_small_int32_5_6_4354_5000.h index 51a71506d803..1323d07df6d0 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_5_6_4354_5000.h +++ b/src/audio/src/coef/src_small_int32_5_6_4354_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_5_6_4354_5000_fir[380] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_6_5_4354_5000.h b/src/audio/src/coef/src_small_int32_6_5_4354_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_small_int32_6_5_4354_5000.h rename to src/audio/src/coef/src_small_int32_6_5_4354_5000.h index 3ebd2e13b4c3..959a4cf8e041 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_6_5_4354_5000.h +++ b/src/audio/src/coef/src_small_int32_6_5_4354_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_6_5_4354_5000_fir[384] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_7_8_4535_5000.h b/src/audio/src/coef/src_small_int32_7_8_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_small_int32_7_8_4535_5000.h rename to src/audio/src/coef/src_small_int32_7_8_4535_5000.h index 5dd8e49e4e59..0dd63132b167 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_7_8_4535_5000.h +++ b/src/audio/src/coef/src_small_int32_7_8_4535_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_7_8_4535_5000_fir[644] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_8_7_4535_5000.h b/src/audio/src/coef/src_small_int32_8_7_4535_5000.h similarity index 99% rename from src/include/sof/audio/coefficients/src/src_small_int32_8_7_4535_5000.h rename to src/audio/src/coef/src_small_int32_8_7_4535_5000.h index ed965a4e762d..4f0aeecdde94 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_8_7_4535_5000.h +++ b/src/audio/src/coef/src_small_int32_8_7_4535_5000.h @@ -4,7 +4,6 @@ * */ -#include #include const int32_t src_int32_8_7_4535_5000_fir[640] = { diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_define.h b/src/audio/src/coef/src_small_int32_define.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_small_int32_define.h rename to src/audio/src/coef/src_small_int32_define.h diff --git a/src/include/sof/audio/coefficients/src/src_small_int32_table.h b/src/audio/src/coef/src_small_int32_table.h similarity index 68% rename from src/include/sof/audio/coefficients/src/src_small_int32_table.h rename to src/audio/src/coef/src_small_int32_table.h index 57af8877185c..3a01957e9560 100644 --- a/src/include/sof/audio/coefficients/src/src_small_int32_table.h +++ b/src/audio/src/coef/src_small_int32_table.h @@ -8,27 +8,27 @@ #define __SOF_AUDIO_COEFFICIENTS_SRC_SRC_SMALL_INT32_TABLE_H__ /* SRC conversions */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "src_small_int32_1_2_2268_5000.h" +#include "src_small_int32_1_2_4535_5000.h" +#include "src_small_int32_1_3_2268_5000.h" +#include "src_small_int32_1_3_4535_5000.h" +#include "src_small_int32_2_1_2268_5000.h" +#include "src_small_int32_2_1_4535_5000.h" +#include "src_small_int32_2_3_4535_5000.h" +#include "src_small_int32_3_1_2268_5000.h" +#include "src_small_int32_3_1_4535_5000.h" +#include "src_small_int32_3_2_4535_5000.h" +#include "src_small_int32_3_4_4535_5000.h" +#include "src_small_int32_4_3_4535_5000.h" +#include "src_small_int32_4_5_4535_5000.h" +#include "src_small_int32_5_4_4535_5000.h" +#include "src_small_int32_5_6_4354_5000.h" +#include "src_small_int32_6_5_4354_5000.h" +#include "src_small_int32_7_8_4535_5000.h" +#include "src_small_int32_8_7_4535_5000.h" +#include "src_small_int32_20_21_4167_5000.h" +#include "src_small_int32_21_20_4167_5000.h" + #include /* SRC table */ diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_10_21_4535_5000.h b/src/audio/src/coef/src_std_int32_10_21_4535_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_10_21_4535_5000.h rename to src/audio/src/coef/src_std_int32_10_21_4535_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_1_2_2268_5000.h b/src/audio/src/coef/src_std_int32_1_2_2268_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_1_2_2268_5000.h rename to src/audio/src/coef/src_std_int32_1_2_2268_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_1_2_4535_5000.h b/src/audio/src/coef/src_std_int32_1_2_4535_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_1_2_4535_5000.h rename to src/audio/src/coef/src_std_int32_1_2_4535_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_1_3_2268_5000.h b/src/audio/src/coef/src_std_int32_1_3_2268_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_1_3_2268_5000.h rename to src/audio/src/coef/src_std_int32_1_3_2268_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_1_3_4535_5000.h b/src/audio/src/coef/src_std_int32_1_3_4535_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_1_3_4535_5000.h rename to src/audio/src/coef/src_std_int32_1_3_4535_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_20_21_4167_5000.h b/src/audio/src/coef/src_std_int32_20_21_4167_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_20_21_4167_5000.h rename to src/audio/src/coef/src_std_int32_20_21_4167_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_20_7_2976_5000.h b/src/audio/src/coef/src_std_int32_20_7_2976_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_20_7_2976_5000.h rename to src/audio/src/coef/src_std_int32_20_7_2976_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_21_20_4167_5000.h b/src/audio/src/coef/src_std_int32_21_20_4167_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_21_20_4167_5000.h rename to src/audio/src/coef/src_std_int32_21_20_4167_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_21_40_3968_5000.h b/src/audio/src/coef/src_std_int32_21_40_3968_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_21_40_3968_5000.h rename to src/audio/src/coef/src_std_int32_21_40_3968_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_21_80_3968_5000.h b/src/audio/src/coef/src_std_int32_21_80_3968_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_21_80_3968_5000.h rename to src/audio/src/coef/src_std_int32_21_80_3968_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_2_1_2268_5000.h b/src/audio/src/coef/src_std_int32_2_1_2268_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_2_1_2268_5000.h rename to src/audio/src/coef/src_std_int32_2_1_2268_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_2_1_4535_5000.h b/src/audio/src/coef/src_std_int32_2_1_4535_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_2_1_4535_5000.h rename to src/audio/src/coef/src_std_int32_2_1_4535_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_2_3_4535_5000.h b/src/audio/src/coef/src_std_int32_2_3_4535_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_2_3_4535_5000.h rename to src/audio/src/coef/src_std_int32_2_3_4535_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_32_21_4535_5000.h b/src/audio/src/coef/src_std_int32_32_21_4535_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_32_21_4535_5000.h rename to src/audio/src/coef/src_std_int32_32_21_4535_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_3_1_2268_5000.h b/src/audio/src/coef/src_std_int32_3_1_2268_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_3_1_2268_5000.h rename to src/audio/src/coef/src_std_int32_3_1_2268_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_3_1_4535_5000.h b/src/audio/src/coef/src_std_int32_3_1_4535_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_3_1_4535_5000.h rename to src/audio/src/coef/src_std_int32_3_1_4535_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_3_2_4535_5000.h b/src/audio/src/coef/src_std_int32_3_2_4535_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_3_2_4535_5000.h rename to src/audio/src/coef/src_std_int32_3_2_4535_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_3_4_4535_5000.h b/src/audio/src/coef/src_std_int32_3_4_4535_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_3_4_4535_5000.h rename to src/audio/src/coef/src_std_int32_3_4_4535_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_40_21_3968_5000.h b/src/audio/src/coef/src_std_int32_40_21_3968_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_40_21_3968_5000.h rename to src/audio/src/coef/src_std_int32_40_21_3968_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_4_3_4535_5000.h b/src/audio/src/coef/src_std_int32_4_3_4535_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_4_3_4535_5000.h rename to src/audio/src/coef/src_std_int32_4_3_4535_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_4_5_4535_5000.h b/src/audio/src/coef/src_std_int32_4_5_4535_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_4_5_4535_5000.h rename to src/audio/src/coef/src_std_int32_4_5_4535_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_5_4_4535_5000.h b/src/audio/src/coef/src_std_int32_5_4_4535_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_5_4_4535_5000.h rename to src/audio/src/coef/src_std_int32_5_4_4535_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_5_6_4354_5000.h b/src/audio/src/coef/src_std_int32_5_6_4354_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_5_6_4354_5000.h rename to src/audio/src/coef/src_std_int32_5_6_4354_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_5_7_4535_5000.h b/src/audio/src/coef/src_std_int32_5_7_4535_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_5_7_4535_5000.h rename to src/audio/src/coef/src_std_int32_5_7_4535_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_6_5_4354_5000.h b/src/audio/src/coef/src_std_int32_6_5_4354_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_6_5_4354_5000.h rename to src/audio/src/coef/src_std_int32_6_5_4354_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_7_8_4535_5000.h b/src/audio/src/coef/src_std_int32_7_8_4535_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_7_8_4535_5000.h rename to src/audio/src/coef/src_std_int32_7_8_4535_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_8_21_3239_5000.h b/src/audio/src/coef/src_std_int32_8_21_3239_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_8_21_3239_5000.h rename to src/audio/src/coef/src_std_int32_8_21_3239_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_8_7_2468_5000.h b/src/audio/src/coef/src_std_int32_8_7_2468_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_8_7_2468_5000.h rename to src/audio/src/coef/src_std_int32_8_7_2468_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_8_7_4535_5000.h b/src/audio/src/coef/src_std_int32_8_7_4535_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_8_7_4535_5000.h rename to src/audio/src/coef/src_std_int32_8_7_4535_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_define.h b/src/audio/src/coef/src_std_int32_define.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_std_int32_define.h rename to src/audio/src/coef/src_std_int32_define.h diff --git a/src/include/sof/audio/coefficients/src/src_std_int32_table.h b/src/audio/src/coef/src_std_int32_table.h similarity index 79% rename from src/include/sof/audio/coefficients/src/src_std_int32_table.h rename to src/audio/src/coef/src_std_int32_table.h index 06a7965a382c..9d96da8c6658 100644 --- a/src/include/sof/audio/coefficients/src/src_std_int32_table.h +++ b/src/audio/src/coef/src_std_int32_table.h @@ -9,36 +9,36 @@ #define __SOF_AUDIO_COEFFICIENTS_SRC_SRC_STD_INT32_TABLE_H__ /* SRC conversions */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "src_std_int32_1_2_2268_5000.h" +#include "src_std_int32_1_2_4535_5000.h" +#include "src_std_int32_1_3_2268_5000.h" +#include "src_std_int32_1_3_4535_5000.h" +#include "src_std_int32_2_1_2268_5000.h" +#include "src_std_int32_2_1_4535_5000.h" +#include "src_std_int32_2_3_4535_5000.h" +#include "src_std_int32_3_1_2268_5000.h" +#include "src_std_int32_3_1_4535_5000.h" +#include "src_std_int32_3_2_4535_5000.h" +#include "src_std_int32_3_4_4535_5000.h" +#include "src_std_int32_4_3_4535_5000.h" +#include "src_std_int32_4_5_4535_5000.h" +#include "src_std_int32_5_4_4535_5000.h" +#include "src_std_int32_5_6_4354_5000.h" +#include "src_std_int32_5_7_4535_5000.h" +#include "src_std_int32_6_5_4354_5000.h" +#include "src_std_int32_7_8_4535_5000.h" +#include "src_std_int32_8_7_2468_5000.h" +#include "src_std_int32_8_7_4535_5000.h" +#include "src_std_int32_8_21_3239_5000.h" +#include "src_std_int32_10_21_4535_5000.h" +#include "src_std_int32_20_7_2976_5000.h" +#include "src_std_int32_20_21_4167_5000.h" +#include "src_std_int32_21_20_4167_5000.h" +#include "src_std_int32_21_40_3968_5000.h" +#include "src_std_int32_21_80_3968_5000.h" +#include "src_std_int32_32_21_4535_5000.h" +#include "src_std_int32_40_21_3968_5000.h" + #include /* SRC table */ diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_1_2_1814_5000.h b/src/audio/src/coef/src_tiny_int16_1_2_1814_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_1_2_1814_5000.h rename to src/audio/src/coef/src_tiny_int16_1_2_1814_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_1_3_1814_5000.h b/src/audio/src/coef/src_tiny_int16_1_3_1814_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_1_3_1814_5000.h rename to src/audio/src/coef/src_tiny_int16_1_3_1814_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_1_6_1814_5000.h b/src/audio/src/coef/src_tiny_int16_1_6_1814_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_1_6_1814_5000.h rename to src/audio/src/coef/src_tiny_int16_1_6_1814_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_20_21_1667_5000.h b/src/audio/src/coef/src_tiny_int16_20_21_1667_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_20_21_1667_5000.h rename to src/audio/src/coef/src_tiny_int16_20_21_1667_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_21_20_1667_5000.h b/src/audio/src/coef/src_tiny_int16_21_20_1667_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_21_20_1667_5000.h rename to src/audio/src/coef/src_tiny_int16_21_20_1667_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_24_25_1814_5000.h b/src/audio/src/coef/src_tiny_int16_24_25_1814_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_24_25_1814_5000.h rename to src/audio/src/coef/src_tiny_int16_24_25_1814_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_25_24_1814_5000.h b/src/audio/src/coef/src_tiny_int16_25_24_1814_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_25_24_1814_5000.h rename to src/audio/src/coef/src_tiny_int16_25_24_1814_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_2_1_1814_5000.h b/src/audio/src/coef/src_tiny_int16_2_1_1814_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_2_1_1814_5000.h rename to src/audio/src/coef/src_tiny_int16_2_1_1814_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_2_3_1814_5000.h b/src/audio/src/coef/src_tiny_int16_2_3_1814_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_2_3_1814_5000.h rename to src/audio/src/coef/src_tiny_int16_2_3_1814_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_3_1_1814_5000.h b/src/audio/src/coef/src_tiny_int16_3_1_1814_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_3_1_1814_5000.h rename to src/audio/src/coef/src_tiny_int16_3_1_1814_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_3_2_1814_5000.h b/src/audio/src/coef/src_tiny_int16_3_2_1814_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_3_2_1814_5000.h rename to src/audio/src/coef/src_tiny_int16_3_2_1814_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_6_1_1814_5000.h b/src/audio/src/coef/src_tiny_int16_6_1_1814_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_6_1_1814_5000.h rename to src/audio/src/coef/src_tiny_int16_6_1_1814_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_7_8_1814_5000.h b/src/audio/src/coef/src_tiny_int16_7_8_1814_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_7_8_1814_5000.h rename to src/audio/src/coef/src_tiny_int16_7_8_1814_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_8_7_1814_5000.h b/src/audio/src/coef/src_tiny_int16_8_7_1814_5000.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_8_7_1814_5000.h rename to src/audio/src/coef/src_tiny_int16_8_7_1814_5000.h diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_define.h b/src/audio/src/coef/src_tiny_int16_define.h similarity index 100% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_define.h rename to src/audio/src/coef/src_tiny_int16_define.h diff --git a/src/include/sof/audio/coefficients/src/src_tiny_int16_table.h b/src/audio/src/coef/src_tiny_int16_table.h similarity index 75% rename from src/include/sof/audio/coefficients/src/src_tiny_int16_table.h rename to src/audio/src/coef/src_tiny_int16_table.h index 4da547757cb5..3a6003db75d8 100644 --- a/src/include/sof/audio/coefficients/src/src_tiny_int16_table.h +++ b/src/audio/src/coef/src_tiny_int16_table.h @@ -9,21 +9,20 @@ #define __SOF_AUDIO_COEFFICIENTS_SRC_SRC_TINY_INT16_TABLE_H__ /* SRC conversions */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "src_tiny_int16_1_2_1814_5000.h" +#include "src_tiny_int16_1_3_1814_5000.h" +#include "src_tiny_int16_1_6_1814_5000.h" +#include "src_tiny_int16_2_1_1814_5000.h" +#include "src_tiny_int16_2_3_1814_5000.h" +#include "src_tiny_int16_3_1_1814_5000.h" +#include "src_tiny_int16_3_2_1814_5000.h" +#include "src_tiny_int16_6_1_1814_5000.h" +#include "src_tiny_int16_7_8_1814_5000.h" +#include "src_tiny_int16_8_7_1814_5000.h" +#include "src_tiny_int16_20_21_1667_5000.h" +#include "src_tiny_int16_21_20_1667_5000.h" +#include "src_tiny_int16_24_25_1814_5000.h" +#include "src_tiny_int16_25_24_1814_5000.h" #include /* SRC table */ diff --git a/src/audio/src/src.c b/src/audio/src/src.c index 82501728c59c..0be34245189a 100644 --- a/src/audio/src/src.c +++ b/src/audio/src/src.c @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include #include #include @@ -40,18 +38,24 @@ #include #include -#if SRC_SHORT || CONFIG_COMP_SRC_TINY -#include -#include +#include "src.h" +#include "src_config.h" + +#ifdef SRC_LITE +#include "coef/src_lite_ipc4_int32_define.h" +#include "coef/src_lite_ipc4_int32_table.h" +#elif SRC_SHORT || CONFIG_COMP_SRC_TINY +#include "coef/src_tiny_int16_define.h" +#include "coef/src_tiny_int16_table.h" #elif CONFIG_COMP_SRC_SMALL -#include -#include +#include "coef/src_small_int32_define.h" +#include "coef/src_small_int32_table.h" #elif CONFIG_COMP_SRC_STD -#include -#include +#include "coef/src_std_int32_define.h" +#include "coef/src_std_int32_table.h" #elif CONFIG_COMP_SRC_IPC4_FULL_MATRIX -#include -#include +#include "coef/src_ipc4_int32_define.h" +#include "coef/src_ipc4_int32_table.h" #else #error "No valid configuration selected for SRC" #endif @@ -62,78 +66,9 @@ LOG_MODULE_REGISTER(src, CONFIG_SOF_LOG_LEVEL); -#if CONFIG_IPC_MAJOR_4 -/* src component private data */ -struct ipc4_config_src { - struct ipc4_base_module_cfg base; - uint32_t sink_rate; -}; - -/* e61bb28d-149a-4c1f-b709-46823ef5f5a3 */ -DECLARE_SOF_RT_UUID("src", src_uuid, 0xe61bb28d, 0x149a, 0x4c1f, - 0xb7, 0x09, 0x46, 0x82, 0x3e, 0xf5, 0xf5, 0xae); -#elif CONFIG_IPC_MAJOR_3 -/* c1c5326d-8390-46b4-aa47-95c3beca6550 */ -DECLARE_SOF_RT_UUID("src", src_uuid, 0xc1c5326d, 0x8390, 0x46b4, - 0xaa, 0x47, 0x95, 0xc3, 0xbe, 0xca, 0x65, 0x50); -#else -#error "No or invalid IPC MAJOR version selected." -#endif /* CONFIG_IPC_MAJOR_4 */ - -DECLARE_TR_CTX(src_tr, SOF_UUID(src_uuid), LOG_LEVEL_INFO); - -struct comp_data { -#if CONFIG_IPC_MAJOR_4 - struct ipc4_config_src ipc_config; -#else - struct ipc_config_src ipc_config; -#endif /* CONFIG_IPC_MAJOR_4 */ - struct polyphase_src src; - struct src_param param; - int32_t *delay_lines; - uint32_t sink_rate; - uint32_t source_rate; - int32_t *sbuf_w_ptr; - int32_t *sbuf_r_ptr; - int sbuf_avail; - int data_shift; - int source_frames; - int sink_frames; - int sample_container_bytes; - int channels_count; - int (*src_func)(struct comp_data *cd, struct sof_source __sparse_cache *source, - struct sof_sink __sparse_cache *sink); - void (*polyphase_func)(struct src_stage_prm *s); -}; - -/* Calculates the needed FIR delay line length */ -static int src_fir_delay_length(struct src_stage *s) -{ - return s->subfilter_length + (s->num_of_subfilters - 1) * s->idm - + s->blk_in; -} - -/* Calculates the FIR output delay line length */ -static int src_out_delay_length(struct src_stage *s) -{ - return 1 + (s->num_of_subfilters - 1) * s->odm; -} - -/* Returns index of a matching sample rate */ -static int src_find_fs(int fs_list[], int list_length, int fs) -{ - int i; - - for (i = 0; i < list_length; i++) { - if (fs_list[i] == fs) - return i; - } - return -EINVAL; -} - /* Calculates buffers to allocate for a SRC mode */ -static int src_buffer_lengths(struct comp_dev *dev, struct comp_data *cd, - int nch) +int src_buffer_lengths(struct comp_dev *dev, struct comp_data *cd, + int nch) { struct src_stage *stage1; struct src_stage *stage2; @@ -215,15 +150,9 @@ static int src_buffer_lengths(struct comp_dev *dev, struct comp_data *cd, return 0; } -static void src_state_reset(struct src_state *state) -{ - state->fir_delay_size = 0; - state->out_delay_size = 0; -} - -static int init_stages(struct src_stage *stage1, struct src_stage *stage2, - struct polyphase_src *src, struct src_param *p, - int n, int32_t *delay_lines_start) +int init_stages(struct src_stage *stage1, struct src_stage *stage2, + struct polyphase_src *src, struct src_param *p, + int n, int32_t *delay_lines_start) { /* Clear FIR state */ src_state_reset(&src->state1); @@ -287,15 +216,6 @@ static int init_stages(struct src_stage *stage1, struct src_stage *stage2, return 0; } -void src_polyphase_reset(struct polyphase_src *src) -{ - src->number_of_stages = 0; - src->stage1 = NULL; - src->stage2 = NULL; - src_state_reset(&src->state1); - src_state_reset(&src->state2); -} - int src_polyphase_init(struct polyphase_src *src, struct src_param *p, int32_t *delay_lines_start) { @@ -334,16 +254,9 @@ int src_polyphase_init(struct polyphase_src *src, struct src_param *p, return n_stages; } -/* Fallback function */ -static int src_fallback(struct comp_data *cd, struct sof_source __sparse_cache *source, - struct sof_sink __sparse_cache *sink) -{ - return 0; -} - /* Normal 2 stage SRC */ -static int src_2s(struct comp_data *cd, - struct sof_source __sparse_cache *source, struct sof_sink __sparse_cache *sink) +int src_2s(struct comp_data *cd, + struct sof_source *source, struct sof_sink *sink) { struct src_stage_prm s1; struct src_stage_prm s2; @@ -353,7 +266,8 @@ static int src_2s(struct comp_data *cd, int s2_blk_out; uint32_t n_read = 0, n_written = 0; int ret; - uint8_t *buffer_start; + uint8_t const *source_buffer_start; + uint8_t *sink_buffer_start; void *sbuf_end_addr = &cd->delay_lines[cd->param.sbuf_length]; size_t sbuf_size = cd->param.sbuf_length * sizeof(int32_t); /* chan sink == chan src therefore we only need to use one*/ @@ -366,18 +280,18 @@ static int src_2s(struct comp_data *cd, uint32_t sink_frag_size = cd->param.blk_out * sink_get_frame_bytes(sink); ret = source_get_data(source, source_frag_size, - &s1.x_rptr, (void **)&buffer_start, &s1.x_size); + &s1.x_rptr, (void const **)&source_buffer_start, &s1.x_size); if (ret) return ret; - s1.x_end_addr = buffer_start + s1.x_size; + s1.x_end_addr = source_buffer_start + s1.x_size; ret = sink_get_buffer(sink, sink_frag_size, - &s2.y_wptr, (void **)&buffer_start, &s2.y_size); + &s2.y_wptr, (void **)&sink_buffer_start, &s2.y_size); if (ret) { source_release_data(source, 0); return ret; } - s2.y_end_addr = buffer_start + s2.y_size; + s2.y_end_addr = sink_buffer_start + s2.y_size; s1.y_end_addr = sbuf_end_addr; s1.y_size = sbuf_size; @@ -443,28 +357,29 @@ static int src_2s(struct comp_data *cd, } /* 1 stage SRC for simple conversions */ -static int src_1s(struct comp_data *cd, struct sof_source __sparse_cache *source, - struct sof_sink __sparse_cache *sink) +int src_1s(struct comp_data *cd, struct sof_source *source, + struct sof_sink *sink) { struct src_stage_prm s1; int ret; - uint8_t *buffer_start; + uint8_t const *source_buffer_start; + uint8_t *sink_buffer_start; uint32_t source_frag_size = cd->param.blk_in * source_get_frame_bytes(source); uint32_t sink_frag_size = cd->param.blk_out * sink_get_frame_bytes(sink); ret = source_get_data(source, source_frag_size, - &s1.x_rptr, (void **)&buffer_start, &s1.x_size); + &s1.x_rptr, (void const **)&source_buffer_start, &s1.x_size); if (ret) return ret; - s1.x_end_addr = buffer_start + s1.x_size; + s1.x_end_addr = source_buffer_start + s1.x_size; ret = sink_get_buffer(sink, sink_frag_size, - &s1.y_wptr, (void **)&buffer_start, &s1.y_size); + &s1.y_wptr, (void **)&sink_buffer_start, &s1.y_size); if (ret) { source_release_data(source, 0); return ret; } - s1.y_end_addr = buffer_start + s1.y_size; + s1.y_end_addr = sink_buffer_start + s1.y_size; s1.times = cd->param.stage1_times; s1.state = &cd->src.state1; @@ -482,8 +397,8 @@ static int src_1s(struct comp_data *cd, struct sof_source __sparse_cache *source } /* A fast copy function for same in and out rate */ -static int src_copy_sxx(struct comp_data *cd, struct sof_source __sparse_cache *source, - struct sof_sink __sparse_cache *sink) +int src_copy_sxx(struct comp_data *cd, struct sof_source *source, + struct sof_sink *sink) { int frames = cd->param.blk_in; @@ -500,132 +415,7 @@ static int src_copy_sxx(struct comp_data *cd, struct sof_source __sparse_cache * return -ENOTSUP; } -#if CONFIG_IPC_MAJOR_4 -static int src_rate_check(const void *spec) -{ - const struct ipc4_config_src *ipc_src = spec; - - if (ipc_src->base.audio_fmt.sampling_frequency == 0 || ipc_src->sink_rate == 0) - return -EINVAL; - - return 0; -} - -static int src_stream_pcm_source_rate_check(struct ipc4_config_src cfg, - struct sof_ipc_stream_params *params) -{ - /* Nothing to check */ - return 0; -} - -static int src_stream_pcm_sink_rate_check(struct ipc4_config_src cfg, - struct sof_ipc_stream_params *params) -{ - if (cfg.sink_rate && params->rate != cfg.sink_rate) - return -EINVAL; - - return 0; -} - -/* In ipc4 case param is figured out by module config so we need to first - * set up param then verify param. BTW for IPC3 path, the param is sent by - * host driver. - */ -static int src_set_params(struct processing_module *mod, struct sof_sink __sparse_cache *sink) -{ - struct sof_ipc_stream_params src_params; - struct sof_ipc_stream_params *params = mod->stream_params; - struct comp_data *cd = module_get_private_data(mod); - enum sof_ipc_frame frame_fmt, valid_fmt; - struct comp_dev *dev = mod->dev; - int ret; - - src_params = *params; - src_params.channels = mod->priv.cfg.base_cfg.audio_fmt.channels_count; - src_params.buffer_fmt = mod->priv.cfg.base_cfg.audio_fmt.interleaving_style; - src_params.rate = cd->ipc_config.sink_rate; - - /* Get frame_fmt and valid_fmt */ - audio_stream_fmt_conversion(mod->priv.cfg.base_cfg.audio_fmt.depth, - mod->priv.cfg.base_cfg.audio_fmt.valid_bit_depth, - &frame_fmt, &valid_fmt, - mod->priv.cfg.base_cfg.audio_fmt.s_type); - - src_params.frame_fmt = valid_fmt; - component_set_nearest_period_frames(dev, src_params.rate); - - ret = sink_set_params(sink, &src_params, true); - - /* Update module stream_params */ - params->rate = cd->ipc_config.sink_rate; - return ret; -} - -static void src_set_sink_params(struct comp_dev *dev, struct sof_sink __sparse_cache *sink) -{ - struct processing_module *mod = comp_get_drvdata(dev); - struct comp_data *cd = module_get_private_data(mod); - enum sof_ipc_frame frame_fmt, valid_fmt; - - /* convert IPC4 config to format used by the module */ - audio_stream_fmt_conversion(cd->ipc_config.base.audio_fmt.depth, - cd->ipc_config.base.audio_fmt.valid_bit_depth, - &frame_fmt, &valid_fmt, - cd->ipc_config.base.audio_fmt.s_type); - sink_set_frm_fmt(sink, frame_fmt); - sink_set_valid_fmt(sink, valid_fmt); - sink_set_channels(sink, cd->ipc_config.base.audio_fmt.channels_count); - sink_set_buffer_fmt(sink, cd->ipc_config.base.audio_fmt.interleaving_style); - sink_set_rate(sink, cd->ipc_config.sink_rate); -} - -#elif CONFIG_IPC_MAJOR_3 -static int src_rate_check(const void *spec) -{ - const struct ipc_config_src *ipc_src = spec; - - if (ipc_src->source_rate == 0 && ipc_src->sink_rate == 0) - return -EINVAL; - - return 0; -} - -static int src_stream_pcm_sink_rate_check(struct ipc_config_src cfg, - struct sof_ipc_stream_params *params) -{ - /* In playback, module adapter mod->stream_params from prepare() is for sink side */ - if (cfg.sink_rate && params->rate != cfg.sink_rate) - return -EINVAL; - - return 0; -} - -static int src_stream_pcm_source_rate_check(struct ipc_config_src cfg, - struct sof_ipc_stream_params *params) -{ - /* In capture, module adapter mod->stream_params from prepare() is for source side */ - if (cfg.source_rate && params->rate != cfg.source_rate) - return -EINVAL; - - return 0; -} - -static int src_set_params(struct processing_module *mod, struct sof_sink __sparse_cache *sink) -{ - return 0; -} - -static void src_set_sink_params(struct comp_dev *dev, struct sof_sink __sparse_cache *sink) -{ - /* empty */ -} - -#else -#error "No or invalid IPC MAJOR version selected." -#endif /* CONFIG_IPC_MAJOR_4 */ - -static void src_set_alignment(struct sof_source __sparse_cache *source, - struct sof_sink __sparse_cache *sink) +void src_set_alignment(struct sof_source *source, struct sof_sink *sink) { const uint32_t byte_align = 1; const uint32_t frame_align_req = 1; @@ -634,7 +424,7 @@ static void src_set_alignment(struct sof_source __sparse_cache *source, sink_set_alignment_constants(sink, byte_align, frame_align_req); } -static int src_verify_params(struct processing_module *mod) +int src_verify_params(struct processing_module *mod) { struct sof_ipc_stream_params *params = mod->stream_params; struct comp_data *cd = module_get_private_data(mod); @@ -671,9 +461,9 @@ static int src_verify_params(struct processing_module *mod) return ret; } -static bool src_get_copy_limits(struct comp_data *cd, - struct sof_source __sparse_cache *source, - struct sof_sink __sparse_cache *sink) +bool src_get_copy_limits(struct comp_data *cd, + struct sof_source *source, + struct sof_sink *sink) { struct src_param *sp; struct src_stage *s1; @@ -715,9 +505,9 @@ static bool src_get_copy_limits(struct comp_data *cd, return true; } -static int src_params_general(struct processing_module *mod, - struct sof_source __sparse_cache *source, - struct sof_sink __sparse_cache *sink) +int src_params_general(struct processing_module *mod, + struct sof_source *source, + struct sof_sink *sink) { struct comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; @@ -740,15 +530,8 @@ static int src_params_general(struct processing_module *mod, return err; } - src_set_sink_params(dev, sink); + src_get_source_sink_params(dev, source, sink); -#if CONFIG_IPC_MAJOR_3 - /* Set source/sink_rate/frames */ - cd->channels_count = source_get_channels(source); - cd->source_rate = source_get_rate(source); - cd->sink_rate = sink_get_rate(sink); - cd->sample_container_bytes = mod->stream_params->sample_container_bytes; -#endif comp_info(dev, "src_params(), source_rate = %u, sink_rate = %u", cd->source_rate, cd->sink_rate); comp_dbg(dev, "src_params(), sample_container_bytes = %d, channels = %u, dev->frames = %u", @@ -825,166 +608,9 @@ static int src_params_general(struct processing_module *mod, return 0; } -static int src_prepare_general(struct processing_module *mod, - struct sof_source __sparse_cache *source, - struct sof_sink __sparse_cache *sink) -{ - struct comp_data *cd = module_get_private_data(mod); - struct comp_dev *dev = mod->dev; - int ret = 0; -#if CONFIG_IPC_MAJOR_3 - enum sof_ipc_frame source_format; - enum sof_ipc_frame sink_format; -#endif - - - /* set align requirements */ - src_set_alignment(source, sink); - -#if CONFIG_IPC_MAJOR_4 - switch (cd->ipc_config.base.audio_fmt.depth) { -#if CONFIG_FORMAT_S16LE - case IPC4_DEPTH_16BIT: - cd->data_shift = 0; - cd->polyphase_func = src_polyphase_stage_cir_s16; - break; -#endif /* CONFIG_FORMAT_S16LE */ -#if CONFIG_FORMAT_S24LE - case IPC4_DEPTH_24BIT: - cd->data_shift = 8; - cd->polyphase_func = src_polyphase_stage_cir; - break; -#endif /* CONFIG_FORMAT_S24LE */ -#if CONFIG_FORMAT_S32LE - case IPC4_DEPTH_32BIT: - cd->data_shift = 0; - cd->polyphase_func = src_polyphase_stage_cir; - break; -#endif /* CONFIG_FORMAT_S32LE */ - default: - comp_err(dev, "src_prepare(): Invalid depth %d", - cd->ipc_config.base.audio_fmt.depth); - ret = -EINVAL; - goto out; - } -#elif CONFIG_IPC_MAJOR_3 - /* get source/sink data format */ - source_format = source_get_frm_fmt(source); - sink_format = sink_get_frm_fmt(sink); - - /* SRC supports S16_LE, S24_4LE and S32_LE formats */ - if (source_format != sink_format) { - comp_err(dev, "src_prepare(): Source fmt %d and sink fmt %d are different.", - source_format, sink_format); - ret = -EINVAL; - goto out; - } - - switch (source_format) { -#if CONFIG_FORMAT_S16LE - case SOF_IPC_FRAME_S16_LE: - cd->data_shift = 0; - cd->polyphase_func = src_polyphase_stage_cir_s16; - break; -#endif /* CONFIG_FORMAT_S16LE */ -#if CONFIG_FORMAT_S24LE - case SOF_IPC_FRAME_S24_4LE: - cd->data_shift = 8; - cd->polyphase_func = src_polyphase_stage_cir; - break; -#endif /* CONFIG_FORMAT_S24LE */ -#if CONFIG_FORMAT_S32LE - case SOF_IPC_FRAME_S32_LE: - cd->data_shift = 0; - cd->polyphase_func = src_polyphase_stage_cir; - break; -#endif /* CONFIG_FORMAT_S32LE */ - default: - comp_err(dev, "src_prepare(): invalid format %d", source_format); - ret = -EINVAL; - goto out; - } -#endif /* CONFIG_IPC_MAJOR_3 */ - -out: - if (ret < 0) - comp_set_state(dev, COMP_TRIGGER_RESET); - - return ret; -} - -static int src_init(struct processing_module *mod) -{ - struct module_data *md = &mod->priv; - struct module_config *cfg = &md->cfg; - struct comp_dev *dev = mod->dev; - struct comp_data *cd = NULL; - - comp_dbg(dev, "src_init()"); -#if CONFIG_IPC_MAJOR_3 - if (dev->ipc_config.type != SOF_COMP_SRC) { - comp_err(dev, "src_init(): Wrong IPC config type %u", - dev->ipc_config.type); - return -EINVAL; - } -#endif - if (!cfg->init_data || cfg->size != sizeof(cd->ipc_config)) { - comp_err(dev, "src_init(): Missing or bad size (%u) init data", - cfg->size); - return -EINVAL; - } - - /* validate init data - either SRC sink or source rate must be set */ - if (src_rate_check(cfg->init_data) < 0) { - comp_err(dev, "src_init(): SRC sink and source rate are not set"); - return -EINVAL; - } - - cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*cd)); - if (!cd) - return -ENOMEM; - - md->private = cd; - memcpy_s(&cd->ipc_config, sizeof(cd->ipc_config), cfg->init_data, sizeof(cd->ipc_config)); - - cd->delay_lines = NULL; - cd->src_func = src_fallback; - cd->polyphase_func = NULL; - src_polyphase_reset(&cd->src); - -#if CONFIG_IPC_MAJOR_4 - comp_dbg(dev, "src_init(), channels_count = %d, depth = %d", - cd->ipc_config.base.audio_fmt.channels_count, - cd->ipc_config.base.audio_fmt.depth); - comp_dbg(dev, "src_init(), sampling frequency = %d, sink rate = %d", - cd->ipc_config.base.audio_fmt.sampling_frequency, cd->ipc_config.sink_rate); - cd->source_rate = cd->ipc_config.base.audio_fmt.sampling_frequency; - cd->sink_rate = cd->ipc_config.sink_rate; - cd->channels_count = cd->ipc_config.base.audio_fmt.channels_count; - switch (cd->ipc_config.base.audio_fmt.depth) { - case IPC4_DEPTH_16BIT: - cd->sample_container_bytes = sizeof(int16_t); - break; - case IPC4_DEPTH_24BIT: - case IPC4_DEPTH_32BIT: - cd->sample_container_bytes = sizeof(int32_t); - break; - default: - comp_err(dev, "src_init(): Illegal sample depth %d", - cd->ipc_config.base.audio_fmt.depth); - rfree(cd); - return -EINVAL; - } -#elif CONFIG_IPC_MAJOR_3 - mod->verify_params_flags = BUFF_PARAMS_RATE; -#endif - - return 0; -} - -static int src_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) +int src_prepare(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { int ret; @@ -1001,18 +627,18 @@ static int src_prepare(struct processing_module *mod, } -static bool src_is_ready_to_process(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) +bool src_is_ready_to_process(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct comp_data *cd = module_get_private_data(mod); return src_get_copy_limits(cd, sources[0], sinks[0]); } -static int src_process(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) +int src_process(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct comp_data *cd = module_get_private_data(mod); @@ -1027,21 +653,21 @@ static int src_process(struct processing_module *mod, return cd->src_func(cd, sources[0], sinks[0]); } -static int src_set_config(struct processing_module *mod, uint32_t config_id, - enum module_cfg_fragment_position pos, uint32_t data_offset_size, - const uint8_t *fragment, size_t fragment_size, uint8_t *response, - size_t response_size) +int src_set_config(struct processing_module *mod, uint32_t config_id, + enum module_cfg_fragment_position pos, uint32_t data_offset_size, + const uint8_t *fragment, size_t fragment_size, uint8_t *response, + size_t response_size) { return -EINVAL; } -static int src_get_config(struct processing_module *mod, uint32_t config_id, - uint32_t *data_offset_size, uint8_t *fragment, size_t fragment_size) +int src_get_config(struct processing_module *mod, uint32_t config_id, + uint32_t *data_offset_size, uint8_t *fragment, size_t fragment_size) { return -EINVAL; } -static int src_reset(struct processing_module *mod) +int src_reset(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); @@ -1053,7 +679,7 @@ static int src_reset(struct processing_module *mod) return 0; } -static int src_free(struct processing_module *mod) +int src_free(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); @@ -1066,8 +692,8 @@ static int src_free(struct processing_module *mod) return 0; } -static struct module_interface src_interface = { - .init = src_init, +static const struct module_interface src_interface = { + .init = src_init, .prepare = src_prepare, .process = src_process, .is_ready_to_process = src_is_ready_to_process, diff --git a/src/audio/src/src.h b/src/audio/src/src.h new file mode 100644 index 000000000000..2ead7fa95062 --- /dev/null +++ b/src/audio/src/src.h @@ -0,0 +1,272 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2017 Intel Corporation. All rights reserved. + * + * Author: Seppo Ingalsuo + */ + +#ifndef __SOF_AUDIO_SRC_SRC_H__ +#define __SOF_AUDIO_SRC_SRC_H__ + +#include +#include +#include +#include +#include +#include +#include + +struct src_param { + int fir_s1; + int fir_s2; + int out_s1; + int out_s2; + int sbuf_length; + int src_multich; + int total; + int blk_in; + int blk_out; + int stage1_times; + int stage2_times; + int idx_in; + int idx_out; + int nch; +}; + +struct src_stage { + const int idm; + const int odm; + const int num_of_subfilters; + const int subfilter_length; + const int filter_length; + const int blk_in; + const int blk_out; + const int halfband; + const int shift; + const void *coefs; /* Can be int16_t or int32_t depending on config */ +}; + +struct src_state { + int fir_delay_size; /* samples */ + int out_delay_size; /* samples */ + int32_t *fir_delay; + int32_t *out_delay; + int32_t *fir_wp; + int32_t *out_rp; +}; + +struct polyphase_src { + int number_of_stages; + struct src_stage *stage1; + struct src_stage *stage2; + struct src_state state1; + struct src_state state2; +}; + +struct src_stage_prm { + int nch; + int times; + void const *x_rptr; + void const *x_end_addr; + size_t x_size; + void *y_wptr; + void *y_addr; + void *y_end_addr; + size_t y_size; + int shift; + struct src_state *state; + struct src_stage *stage; +}; + +static inline void src_inc_wrap(int32_t **ptr, int32_t *end, size_t size) +{ + if (*ptr >= end) + *ptr = (int32_t *)((uint8_t *)*ptr - size); +} + +static inline void src_dec_wrap(int32_t **ptr, int32_t *addr, size_t size) +{ + if (*ptr < addr) + *ptr = (int32_t *)((uint8_t *)*ptr + size); +} + +#if CONFIG_FORMAT_S16LE +static inline void src_inc_wrap_s16(int16_t **ptr, int16_t *end, size_t size) +{ + if (*ptr >= end) + *ptr = (int16_t *)((uint8_t *)*ptr - size); +} + +static inline void src_dec_wrap_s16(int16_t **ptr, int16_t *addr, size_t size) +{ + if (*ptr < addr) + *ptr = (int16_t *)((uint8_t *)*ptr + size); +} +#endif /* CONFIG_FORMAT_S16LE */ + +static inline void src_state_reset(struct src_state *state) +{ + state->fir_delay_size = 0; + state->out_delay_size = 0; +} + +static inline void src_polyphase_reset(struct polyphase_src *src) +{ + src->number_of_stages = 0; + src->stage1 = NULL; + src->stage2 = NULL; + src_state_reset(&src->state1); + src_state_reset(&src->state2); +} + +int src_polyphase_init(struct polyphase_src *src, struct src_param *p, + int32_t *delay_lines_start); + +int src_polyphase(struct polyphase_src *src, int32_t x[], int32_t y[], + int n_in); + +#if CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE +void src_polyphase_stage_cir(struct src_stage_prm *s); +#endif /* CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE */ + +#if CONFIG_FORMAT_S16LE +void src_polyphase_stage_cir_s16(struct src_stage_prm *s); +#endif /* CONFIG_FORMAT_S16LE */ + +int32_t src_input_rates(void); + +int32_t src_output_rates(void); + +void src_set_alignment(struct sof_source *source, struct sof_sink *sink); + +#if CONFIG_IPC_MAJOR_4 +/* src component private data */ +struct ipc4_config_src { + struct ipc4_base_module_cfg base; + uint32_t sink_rate; +}; +#endif + +struct comp_data { +#if CONFIG_IPC_MAJOR_4 + struct ipc4_config_src ipc_config; +#else + struct ipc_config_src ipc_config; +#endif /* CONFIG_IPC_MAJOR_4 */ + struct polyphase_src src; + struct src_param param; + int32_t *delay_lines; + uint32_t sink_rate; + uint32_t source_rate; + int32_t *sbuf_w_ptr; + int32_t const *sbuf_r_ptr; + int sbuf_avail; + int data_shift; + int source_frames; + int sink_frames; + int sample_container_bytes; + int channels_count; + int (*src_func)(struct comp_data *cd, struct sof_source *source, + struct sof_sink *sink); + void (*polyphase_func)(struct src_stage_prm *s); +}; + +#endif /* __SOF_AUDIO_SRC_SRC_H__ */ + +#if CONFIG_IPC_MAJOR_4 + +int src_stream_pcm_source_rate_check(struct ipc4_config_src cfg, + struct sof_ipc_stream_params *params); +int src_stream_pcm_sink_rate_check(struct ipc4_config_src cfg, + struct sof_ipc_stream_params *params); +#elif CONFIG_IPC_MAJOR_3 +int src_stream_pcm_sink_rate_check(struct ipc_config_src cfg, + struct sof_ipc_stream_params *params); +int src_stream_pcm_source_rate_check(struct ipc_config_src cfg, + struct sof_ipc_stream_params *params); +#endif /* CONFIG_IPC_MAJOR_4 */ + +/* Calculates the needed FIR delay line length */ +static inline int src_fir_delay_length(struct src_stage *s) +{ + return s->subfilter_length + (s->num_of_subfilters - 1) * s->idm + + s->blk_in; +} + +/* Calculates the FIR output delay line length */ +static inline int src_out_delay_length(struct src_stage *s) +{ + return 1 + (s->num_of_subfilters - 1) * s->odm; +} + +/* Returns index of a matching sample rate */ +static inline int src_find_fs(int fs_list[], int list_length, int fs) +{ + int i; + + for (i = 0; i < list_length; i++) { + if (fs_list[i] == fs) + return i; + } + return -EINVAL; +} + +/* Fallback function */ +static inline int src_fallback(struct comp_data *cd, + struct sof_source *source, + struct sof_sink *sink) +{ + return 0; +} + +int src_rate_check(const void *spec); +int src_set_params(struct processing_module *mod, struct sof_sink *sink); + +void src_get_source_sink_params(struct comp_dev *dev, struct sof_source *source, + struct sof_sink *sink); +int src_prepare_general(struct processing_module *mod, + struct sof_source *source, + struct sof_sink *sink); +int src_init(struct processing_module *mod); + +int src_buffer_lengths(struct comp_dev *dev, struct comp_data *cd, + int nch); +int init_stages(struct src_stage *stage1, struct src_stage *stage2, + struct polyphase_src *src, struct src_param *p, + int n, int32_t *delay_lines_start); +int src_1s(struct comp_data *cd, struct sof_source *source, + struct sof_sink *sink); +int src_copy_sxx(struct comp_data *cd, struct sof_source *source, + struct sof_sink *sink); +int src_verify_params(struct processing_module *mod); + +bool src_get_copy_limits(struct comp_data *cd, + struct sof_source *source, + struct sof_sink *sink); +int src_params_general(struct processing_module *mod, + struct sof_source *source, + struct sof_sink *sink); +int src_prepare(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks); +int src_2s(struct comp_data *cd, + struct sof_source *source, struct sof_sink *sink); + +bool src_is_ready_to_process(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks); +int src_process(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks); + +int src_set_config(struct processing_module *mod, uint32_t config_id, + enum module_cfg_fragment_position pos, uint32_t data_offset_size, + const uint8_t *fragment, size_t fragment_size, uint8_t *response, + size_t response_size); +int src_get_config(struct processing_module *mod, uint32_t config_id, + uint32_t *data_offset_size, uint8_t *fragment, size_t fragment_size); +int src_free(struct processing_module *mod); +int src_reset(struct processing_module *mod); +extern const struct sof_uuid src_uuid; +extern struct tr_ctx src_tr; + diff --git a/src/include/sof/audio/src/src_config.h b/src/audio/src/src_config.h similarity index 100% rename from src/include/sof/audio/src/src_config.h rename to src/audio/src/src_config.h diff --git a/src/audio/src/src_generic.c b/src/audio/src/src_generic.c index 745afc16c025..6b6661d02c66 100644 --- a/src/audio/src/src_generic.c +++ b/src/audio/src/src_generic.c @@ -8,15 +8,16 @@ * architecture. */ -#include +#include "src_config.h" #if SRC_GENERIC #include -#include #include #include +#include "src.h" + #if SRC_SHORT /* 16 bit coefficients version */ static inline void fir_filter_generic(int32_t *rp, const void *cp, int32_t *wp0, diff --git a/src/audio/src/src_hifi2ep.c b/src/audio/src/src_hifi2ep.c index b426c622cafb..6c1e06b23d96 100644 --- a/src/audio/src/src_hifi2ep.c +++ b/src/audio/src/src_hifi2ep.c @@ -6,11 +6,12 @@ /* HiFi EP optimized code parts for SRC */ -#include +#include "src_config.h" #if SRC_HIFIEP -#include +#include "src.h" + #include #include #include diff --git a/src/audio/src/src_hifi3.c b/src/audio/src/src_hifi3.c index 2811a422c05d..bd419fdbfbb1 100644 --- a/src/audio/src/src_hifi3.c +++ b/src/audio/src/src_hifi3.c @@ -6,11 +6,12 @@ /* HiFi3 optimized code parts for SRC */ -#include +#include "src_config.h" #if SRC_HIFI3 -#include +#include "src.h" + #include #include #include diff --git a/src/audio/src/src_hifi4.c b/src/audio/src/src_hifi4.c index a2d2cd313a5e..9e011bf800f3 100644 --- a/src/audio/src/src_hifi4.c +++ b/src/audio/src/src_hifi4.c @@ -6,12 +6,13 @@ /* HiFi4 optimized code parts for SRC */ -#include +#include "src_config.h" #if SRC_HIFI4 +#include "src.h" + #include -#include #include #include #include diff --git a/src/audio/src/src_ipc3.c b/src/audio/src/src_ipc3.c new file mode 100644 index 000000000000..b2c2fbfd0930 --- /dev/null +++ b/src/audio/src/src_ipc3.c @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2017 Intel Corporation. All rights reserved. +// +// Author: Seppo Ingalsuo +// Liam Girdwood +// Keyon Jie + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src.h" +#include "src_config.h" + +/* c1c5326d-8390-46b4-aa47-95c3beca6550 */ +DECLARE_SOF_RT_UUID("src", src_uuid, 0xc1c5326d, 0x8390, 0x46b4, + 0xaa, 0x47, 0x95, 0xc3, 0xbe, 0xca, 0x65, 0x50); + +DECLARE_TR_CTX(src_tr, SOF_UUID(src_uuid), LOG_LEVEL_INFO); + +LOG_MODULE_DECLARE(src, CONFIG_SOF_LOG_LEVEL); + +int src_rate_check(const void *spec) +{ + const struct ipc_config_src *ipc_src = spec; + + if (ipc_src->source_rate == 0 && ipc_src->sink_rate == 0) + return -EINVAL; + + return 0; +} + +int src_stream_pcm_sink_rate_check(struct ipc_config_src cfg, + struct sof_ipc_stream_params *params) +{ + /* In playback, module adapter mod->stream_params from prepare() is for sink side */ + if (cfg.sink_rate && params->rate != cfg.sink_rate) + return -EINVAL; + + return 0; +} + +int src_stream_pcm_source_rate_check(struct ipc_config_src cfg, + struct sof_ipc_stream_params *params) +{ + /* In capture, module adapter mod->stream_params from prepare() is for source side */ + if (cfg.source_rate && params->rate != cfg.source_rate) + return -EINVAL; + + return 0; +} + +int src_set_params(struct processing_module *mod, struct sof_sink *sink) +{ + return 0; +} + +void src_get_source_sink_params(struct comp_dev *dev, struct sof_source *source, + struct sof_sink *sink) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct comp_data *cd = module_get_private_data(mod); + + /* Set source/sink_rate/frames */ + cd->channels_count = source_get_channels(source); + cd->source_rate = source_get_rate(source); + cd->sink_rate = sink_get_rate(sink); + cd->sample_container_bytes = mod->stream_params->sample_container_bytes; +} + +int src_prepare_general(struct processing_module *mod, + struct sof_source *source, + struct sof_sink *sink) +{ + struct comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + int ret = 0; + enum sof_ipc_frame source_format; + enum sof_ipc_frame sink_format; + + /* set align requirements */ + src_set_alignment(source, sink); + + /* get source/sink data format */ + source_format = source_get_frm_fmt(source); + sink_format = sink_get_frm_fmt(sink); + + /* SRC supports S16_LE, S24_4LE and S32_LE formats */ + if (source_format != sink_format) { + comp_err(dev, "src_prepare(): Source fmt %d and sink fmt %d are different.", + source_format, sink_format); + ret = -EINVAL; + goto out; + } + + switch (source_format) { +#if CONFIG_FORMAT_S16LE + case SOF_IPC_FRAME_S16_LE: + cd->data_shift = 0; + cd->polyphase_func = src_polyphase_stage_cir_s16; + break; +#endif /* CONFIG_FORMAT_S16LE */ +#if CONFIG_FORMAT_S24LE + case SOF_IPC_FRAME_S24_4LE: + cd->data_shift = 8; + cd->polyphase_func = src_polyphase_stage_cir; + break; +#endif /* CONFIG_FORMAT_S24LE */ +#if CONFIG_FORMAT_S32LE + case SOF_IPC_FRAME_S32_LE: + cd->data_shift = 0; + cd->polyphase_func = src_polyphase_stage_cir; + break; +#endif /* CONFIG_FORMAT_S32LE */ + default: + comp_err(dev, "src_prepare(): invalid format %d", source_format); + ret = -EINVAL; + goto out; + } + +out: + if (ret < 0) + comp_set_state(dev, COMP_TRIGGER_RESET); + + return ret; +} + +int src_init(struct processing_module *mod) +{ + struct module_data *md = &mod->priv; + struct module_config *cfg = &md->cfg; + struct comp_dev *dev = mod->dev; + struct comp_data *cd = NULL; + + comp_dbg(dev, "src_init()"); + + if (dev->ipc_config.type != SOF_COMP_SRC) { + comp_err(dev, "src_init(): Wrong IPC config type %u", + dev->ipc_config.type); + return -EINVAL; + } + + if (!cfg->init_data || cfg->size != sizeof(cd->ipc_config)) { + comp_err(dev, "src_init(): Missing or bad size (%u) init data", + cfg->size); + return -EINVAL; + } + + /* validate init data - either SRC sink or source rate must be set */ + if (src_rate_check(cfg->init_data) < 0) { + comp_err(dev, "src_init(): SRC sink and source rate are not set"); + return -EINVAL; + } + + cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*cd)); + if (!cd) + return -ENOMEM; + + md->private = cd; + memcpy_s(&cd->ipc_config, sizeof(cd->ipc_config), cfg->init_data, sizeof(cd->ipc_config)); + + cd->delay_lines = NULL; + cd->src_func = src_fallback; + cd->polyphase_func = NULL; + src_polyphase_reset(&cd->src); + + mod->verify_params_flags = BUFF_PARAMS_RATE; + + return 0; +} + diff --git a/src/audio/src/src_ipc4.c b/src/audio/src/src_ipc4.c new file mode 100644 index 000000000000..cf87bde47554 --- /dev/null +++ b/src/audio/src/src_ipc4.c @@ -0,0 +1,243 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2017 Intel Corporation. All rights reserved. +// +// Author: Seppo Ingalsuo +// Liam Girdwood +// Keyon Jie + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src.h" +#include "src_config.h" + +/* e61bb28d-149a-4c1f-b709-46823ef5f5a3 */ +DECLARE_SOF_RT_UUID("src", src_uuid, 0xe61bb28d, 0x149a, 0x4c1f, + 0xb7, 0x09, 0x46, 0x82, 0x3e, 0xf5, 0xf5, 0xae); + +DECLARE_TR_CTX(src_tr, SOF_UUID(src_uuid), LOG_LEVEL_INFO); + +LOG_MODULE_DECLARE(src, CONFIG_SOF_LOG_LEVEL); + +int src_rate_check(const void *spec) +{ + const struct ipc4_config_src *ipc_src = spec; + + if (ipc_src->base.audio_fmt.sampling_frequency == 0 || ipc_src->sink_rate == 0) + return -EINVAL; + + return 0; +} + +int src_stream_pcm_source_rate_check(struct ipc4_config_src cfg, + struct sof_ipc_stream_params *params) +{ + /* Nothing to check */ + return 0; +} + +int src_stream_pcm_sink_rate_check(struct ipc4_config_src cfg, + struct sof_ipc_stream_params *params) +{ + if (cfg.sink_rate && params->rate != cfg.sink_rate) + return -EINVAL; + + return 0; +} + +/* In ipc4 case param is figured out by module config so we need to first + * set up param then verify param. BTW for IPC3 path, the param is sent by + * host driver. + */ +int src_set_params(struct processing_module *mod, struct sof_sink *sink) +{ + struct sof_ipc_stream_params src_params; + struct sof_ipc_stream_params *params = mod->stream_params; + struct comp_data *cd = module_get_private_data(mod); + enum sof_ipc_frame frame_fmt, valid_fmt; + struct comp_dev *dev = mod->dev; + int ret; + + src_params = *params; + src_params.channels = mod->priv.cfg.base_cfg.audio_fmt.channels_count; + src_params.buffer_fmt = mod->priv.cfg.base_cfg.audio_fmt.interleaving_style; + src_params.rate = cd->ipc_config.sink_rate; + + /* Get frame_fmt and valid_fmt */ + audio_stream_fmt_conversion(mod->priv.cfg.base_cfg.audio_fmt.depth, + mod->priv.cfg.base_cfg.audio_fmt.valid_bit_depth, + &frame_fmt, &valid_fmt, + mod->priv.cfg.base_cfg.audio_fmt.s_type); + + src_params.frame_fmt = valid_fmt; + ret = sink_set_params(sink, &src_params, true); + + /* if module is to be run as DP, calculate module period + * according to OBS size and data rate + * as SRC uses period value to calculate its internal buffers, + * it must be done here, right after setting sink parameters + */ + if (dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) + dev->period = 1000000 * sink_get_min_free_space(sink) / + (sink_get_frame_bytes(sink) * sink_get_rate(sink)); + + comp_info(dev, "SRC DP period calculated as: %u", dev->period); + + component_set_nearest_period_frames(dev, src_params.rate); + /* Update module stream_params */ + params->rate = cd->ipc_config.sink_rate; + return ret; +} + +void src_get_source_sink_params(struct comp_dev *dev, struct sof_source *source, + struct sof_sink *sink) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct comp_data *cd = module_get_private_data(mod); + enum sof_ipc_frame frame_fmt, valid_fmt; + + /* convert IPC4 config to format used by the module */ + audio_stream_fmt_conversion(cd->ipc_config.base.audio_fmt.depth, + cd->ipc_config.base.audio_fmt.valid_bit_depth, + &frame_fmt, &valid_fmt, + cd->ipc_config.base.audio_fmt.s_type); + sink_set_frm_fmt(sink, frame_fmt); + sink_set_valid_fmt(sink, valid_fmt); + sink_set_channels(sink, cd->ipc_config.base.audio_fmt.channels_count); + sink_set_buffer_fmt(sink, cd->ipc_config.base.audio_fmt.interleaving_style); + sink_set_rate(sink, cd->ipc_config.sink_rate); +} + +int src_prepare_general(struct processing_module *mod, + struct sof_source *source, + struct sof_sink *sink) +{ + struct comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + int ret = 0; + + /* set align requirements */ + src_set_alignment(source, sink); + + switch (cd->ipc_config.base.audio_fmt.depth) { +#if CONFIG_FORMAT_S16LE + case IPC4_DEPTH_16BIT: + cd->data_shift = 0; + cd->polyphase_func = src_polyphase_stage_cir_s16; + break; +#endif /* CONFIG_FORMAT_S16LE */ +#if CONFIG_FORMAT_S24LE + case IPC4_DEPTH_24BIT: + cd->data_shift = 8; + cd->polyphase_func = src_polyphase_stage_cir; + break; +#endif /* CONFIG_FORMAT_S24LE */ +#if CONFIG_FORMAT_S32LE + case IPC4_DEPTH_32BIT: + cd->data_shift = 0; + cd->polyphase_func = src_polyphase_stage_cir; + break; +#endif /* CONFIG_FORMAT_S32LE */ + default: + comp_err(dev, "src_prepare(): Invalid depth %d", + cd->ipc_config.base.audio_fmt.depth); + ret = -EINVAL; + goto out; + } + +out: + if (ret < 0) + comp_set_state(dev, COMP_TRIGGER_RESET); + + return ret; +} + +int src_init(struct processing_module *mod) +{ + struct module_data *md = &mod->priv; + struct module_config *cfg = &md->cfg; + struct comp_dev *dev = mod->dev; + struct comp_data *cd = NULL; + + comp_dbg(dev, "src_init()"); + + if (!cfg->init_data || cfg->size != sizeof(cd->ipc_config)) { + comp_err(dev, "src_init(): Missing or bad size (%u) init data", + cfg->size); + return -EINVAL; + } + + /* validate init data - either SRC sink or source rate must be set */ + if (src_rate_check(cfg->init_data) < 0) { + comp_err(dev, "src_init(): SRC sink and source rate are not set"); + return -EINVAL; + } + + cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*cd)); + if (!cd) + return -ENOMEM; + + md->private = cd; + memcpy_s(&cd->ipc_config, sizeof(cd->ipc_config), cfg->init_data, sizeof(cd->ipc_config)); + + cd->delay_lines = NULL; + cd->src_func = src_fallback; + cd->polyphase_func = NULL; + src_polyphase_reset(&cd->src); + + comp_dbg(dev, "src_init(), channels_count = %d, depth = %d", + cd->ipc_config.base.audio_fmt.channels_count, + cd->ipc_config.base.audio_fmt.depth); + comp_dbg(dev, "src_init(), sampling frequency = %d, sink rate = %d", + cd->ipc_config.base.audio_fmt.sampling_frequency, cd->ipc_config.sink_rate); + cd->source_rate = cd->ipc_config.base.audio_fmt.sampling_frequency; + cd->sink_rate = cd->ipc_config.sink_rate; + cd->channels_count = cd->ipc_config.base.audio_fmt.channels_count; + switch (cd->ipc_config.base.audio_fmt.depth) { + case IPC4_DEPTH_16BIT: + cd->sample_container_bytes = sizeof(int16_t); + break; + case IPC4_DEPTH_24BIT: + case IPC4_DEPTH_32BIT: + cd->sample_container_bytes = sizeof(int32_t); + break; + default: + comp_err(dev, "src_init(): Illegal sample depth %d", + cd->ipc_config.base.audio_fmt.depth); + rfree(cd); + return -EINVAL; + } + + return 0; +} + diff --git a/src/audio/src/src_lite.c b/src/audio/src/src_lite.c new file mode 100644 index 000000000000..5b6bf40f832a --- /dev/null +++ b/src/audio/src/src_lite.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. +// +// Author: Fabiola Jasinska + +#include +#include "src.h" +#include "src_config.h" + +#define SRC_LITE 1 + +LOG_MODULE_REGISTER(src_lite, CONFIG_SOF_LOG_LEVEL); + +static const struct module_interface src_lite_interface = { + .init = src_init, + .prepare = src_prepare, + .process = src_process, + .is_ready_to_process = src_is_ready_to_process, + .set_configuration = src_set_config, + .get_configuration = src_get_config, + .reset = src_reset, + .free = src_free, +}; + +DECLARE_SOF_RT_UUID("src_lite", src_lite_uuid, 0x33441051, 0x44CD, 0x466A, + 0x83, 0xA3, 0x17, 0x84, 0x78, 0x70, 0x8A, 0xEA); + +DECLARE_TR_CTX(src_lite_tr, SOF_UUID(src_lite_uuid), LOG_LEVEL_INFO); + +DECLARE_MODULE_ADAPTER(src_lite_interface, src_lite_uuid, src_lite_tr); +SOF_MODULE_INIT(src_lite, sys_comp_module_src_lite_interface_init); diff --git a/src/audio/tdfb/tdfb.c b/src/audio/tdfb/tdfb.c index d1b04b7faf42..38ff7ee240d8 100644 --- a/src/audio/tdfb/tdfb.c +++ b/src/audio/tdfb/tdfb.c @@ -40,6 +40,12 @@ #include #include +#if CONFIG_IPC_MAJOR_4 +#include +#include +#include +#endif + /* The driver assigns running numbers for control index. If there's single control of * type switch, enum, binary they all have index 0. */ @@ -57,10 +63,60 @@ DECLARE_SOF_RT_UUID("tdfb", tdfb_uuid, 0xdd511749, 0xd9fa, 0x455c, 0xb3, 0xa7, DECLARE_TR_CTX(tdfb_tr, SOF_UUID(tdfb_uuid), LOG_LEVEL_INFO); -/* IPC */ +/* IPC helpers for control update to user space */ -/* TODO: ALSA control update to user space need to be moved to module adapter */ +#if CONFIG_IPC_MAJOR_4 +static struct ipc_msg *tdfb_notification_init(struct processing_module *mod, + uint32_t control_type_param_id, + uint32_t control_id) +{ + struct ipc_msg msg_proto; + struct comp_dev *dev = mod->dev; + struct comp_ipc_config *ipc_config = &dev->ipc_config; + union ipc4_notification_header *primary = + (union ipc4_notification_header *)&msg_proto.header; + struct ipc_msg *msg; + struct tdfb_notification_payload *payload; + + /* Clear header, extension, and other ipc_msg members */ + memset_s(&msg_proto, sizeof(msg_proto), 0, sizeof(msg_proto)); + primary->r.notif_type = SOF_IPC4_MODULE_NOTIFICATION; + primary->r.type = SOF_IPC4_GLB_NOTIFICATION; + primary->r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST; + primary->r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG; + msg = ipc_msg_w_ext_init(msg_proto.header, msg_proto.extension, + sizeof(struct tdfb_notification_payload)); + if (!msg) + return NULL; + + payload = (struct tdfb_notification_payload *)msg->tx_data; + payload->module_data.instance_id = IPC4_INST_ID(ipc_config->id); + payload->module_data.module_id = IPC4_MOD_ID(ipc_config->id); + payload->module_data.event_id = SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_VAL | + control_type_param_id; + payload->module_data.event_data_size = sizeof(struct sof_ipc4_control_msg_payload) + + sizeof(struct sof_ipc4_ctrl_value_chan); + payload->control_msg.id = control_id; + payload->control_msg.num_elems = 1; + payload->control_value.channel = 0; + + comp_dbg(dev, "instance_id = 0x%08x, module_id = 0x%08x", + payload->module_data.instance_id, payload->module_data.module_id); + return msg; +} + +static void tdfb_send_notification(struct ipc_msg *msg, uint32_t val) +{ + struct tdfb_notification_payload *ipc_payload; + + ipc_payload = (struct tdfb_notification_payload *)msg->tx_data; + ipc_payload->control_value.value = val; + ipc_msg_send(msg, NULL, false); +} +/* end CONFIG_IPC_MAJOR_4 */ + +#elif CONFIG_IPC_MAJOR_3 static int init_get_ctl_ipc(struct processing_module *mod) { struct tdfb_comp_data *cd = module_get_private_data(mod); @@ -94,6 +150,7 @@ static void send_get_ctl_ipc(struct processing_module *mod) ipc_msg_send(cd->msg, cd->ctrl_data, false); } +#endif /* CONFIG_IPC_MAJOR_3 */ /* * The optimized FIR functions variants need to be updated into function @@ -447,9 +504,19 @@ static int tdfb_init(struct processing_module *mod) */ /* Initialize IPC for direction of arrival estimate update */ +#if CONFIG_IPC_MAJOR_4 + cd->msg = tdfb_notification_init(mod, SOF_IPC4_ENUM_CONTROL_PARAM_ID, + CTRL_INDEX_AZIMUTH_ESTIMATE); + if (!cd->msg) { + comp_err(dev, "Failed to initialize control notification."); + ret = -EINVAL; + goto err_free_cd; + } +#elif CONFIG_IPC_MAJOR_3 ret = init_get_ctl_ipc(mod); if (ret) goto err_free_cd; +#endif /* Handler for configuration data */ cd->model_handler = comp_data_blob_handler_new(dev); @@ -476,7 +543,9 @@ static int tdfb_init(struct processing_module *mod) return 0; err: + /* These are null if not used for IPC version */ rfree(cd->ctrl_data); + ipc_msg_free(cd->msg); err_free_cd: rfree(cd); @@ -503,6 +572,7 @@ static int tdfb_free(struct processing_module *mod) * Module commands handling */ +#if CONFIG_IPC_MAJOR_3 static int tdfb_cmd_switch_get(struct sof_ipc_ctrl_data *cdata, struct tdfb_comp_data *cd) { int j; @@ -557,11 +627,16 @@ static int tdfb_cmd_get_value(struct processing_module *mod, struct sof_ipc_ctrl comp_err(mod->dev, "tdfb_cmd_get_value() error: invalid cdata->cmd"); return -EINVAL; } +#endif /* CONFIG_IPC_MAJOR_3 */ static int tdfb_get_config(struct processing_module *mod, - uint32_t config_id, uint32_t *data_offset_size, + uint32_t param_id, uint32_t *data_offset_size, uint8_t *fragment, size_t fragment_size) { +#if CONFIG_IPC_MAJOR_4 + comp_err(mod->dev, "tdfb_get_config(), Not supported, should not happen"); + return -EINVAL; +#elif CONFIG_IPC_MAJOR_3 struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; struct tdfb_comp_data *cd = module_get_private_data(mod); @@ -570,8 +645,10 @@ static int tdfb_get_config(struct processing_module *mod, comp_dbg(mod->dev, "tdfb_get_config(), binary"); return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); +#endif /* CONFIG_IPC_MAJOR_3 */ } +#if CONFIG_IPC_MAJOR_3 static int tdfb_cmd_enum_set(struct sof_ipc_ctrl_data *cdata, struct tdfb_comp_data *cd) { if (cdata->num_elems != 1) @@ -634,16 +711,80 @@ static int tdfb_cmd_set_value(struct processing_module *mod, struct sof_ipc_ctrl return -EINVAL; } -static int tdfb_set_config(struct processing_module *mod, uint32_t config_id, +/* end CONFIG_IPC_MAJOR_3 */ + +#elif CONFIG_IPC_MAJOR_4 +static int tdfb_cmd_enum_set(struct sof_ipc4_control_msg_payload *ctl, struct tdfb_comp_data *cd) +{ + if (ctl->num_elems != 1) + return -EINVAL; + + if (ctl->chanv[0].value > SOF_TDFB_MAX_ANGLES) + return -EINVAL; + + switch (ctl->id) { + case CTRL_INDEX_AZIMUTH: + cd->az_value = ctl->chanv[0].value; + cd->update = true; + break; + case CTRL_INDEX_AZIMUTH_ESTIMATE: + cd->az_value_estimate = ctl->chanv[0].value; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int tdfb_cmd_switch_set(struct sof_ipc4_control_msg_payload *ctl, struct tdfb_comp_data *cd) +{ + if (ctl->num_elems != 1) + return -EINVAL; + + switch (ctl->id) { + case CTRL_INDEX_PROCESS: + cd->beam_on = ctl->chanv[0].value; + cd->update = true; + break; + case CTRL_INDEX_DIRECTION: + cd->direction_updates = ctl->chanv[0].value; + break; + default: + return -EINVAL; + } + + return 0; +} +#endif + +static int tdfb_set_config(struct processing_module *mod, uint32_t param_id, enum module_cfg_fragment_position pos, uint32_t data_offset_size, const uint8_t *fragment, size_t fragment_size, uint8_t *response, size_t response_size) { struct tdfb_comp_data *cd = module_get_private_data(mod); + +#if CONFIG_IPC_MAJOR_4 + struct sof_ipc4_control_msg_payload *ctl = (struct sof_ipc4_control_msg_payload *)fragment; + + switch (param_id) { + case SOF_IPC4_SWITCH_CONTROL_PARAM_ID: + comp_info(mod->dev, "SOF_IPC4_SWITCH_CONTROL_PARAM_ID id = %d, num_elems = %d", + ctl->id, ctl->num_elems); + return tdfb_cmd_switch_set(ctl, cd); + + case SOF_IPC4_ENUM_CONTROL_PARAM_ID: + comp_info(mod->dev, "SOF_IPC4_ENUM_CONTROL_PARAM_ID id = %d, num_elems = %d", + ctl->id, ctl->num_elems); + return tdfb_cmd_enum_set(ctl, cd); + } +#elif CONFIG_IPC_MAJOR_3 struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; if (cdata->cmd != SOF_CTRL_CMD_BINARY) return tdfb_cmd_set_value(mod, cdata); +#endif /* CONFIG_IPC_MAJOR_3 */ comp_dbg(mod->dev, "tdfb_set_config(), binary"); return comp_data_blob_set(cd->model_handler, pos, data_offset_size, @@ -660,8 +801,8 @@ static int tdfb_process(struct processing_module *mod, { struct comp_dev *dev = mod->dev; struct tdfb_comp_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = input_buffers[0].data; - struct audio_stream __sparse_cache *sink = output_buffers[0].data; + struct audio_stream *source = input_buffers[0].data; + struct audio_stream *sink = output_buffers[0].data; int frame_count = input_buffers[0].size; int ret; @@ -705,7 +846,11 @@ static int tdfb_process(struct processing_module *mod, (int32_t)(cd->direction.level_ambient >> 32), cd->direction.az_slow); if (cd->direction_updates && cd->direction_change) { +#if CONFIG_IPC_MAJOR_3 send_get_ctl_ipc(mod); +#elif CONFIG_IPC_MAJOR_4 + tdfb_send_notification(cd->msg, cd->az_value_estimate); +#endif cd->direction_change = false; comp_dbg(dev, "tdfb_dupd %d %d", cd->az_value_estimate, cd->direction.az_slow); @@ -715,8 +860,8 @@ static int tdfb_process(struct processing_module *mod, return 0; } -static void tdfb_set_alignment(struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink) +static void tdfb_set_alignment(struct audio_stream *source, + struct audio_stream *sink) { const uint32_t byte_align = 1; const uint32_t frame_align_req = 2; /* Process multiples of 2 frames */ @@ -725,13 +870,30 @@ static void tdfb_set_alignment(struct audio_stream __sparse_cache *source, audio_stream_init_alignment_constants(byte_align, frame_align_req, sink); } +#if CONFIG_IPC_MAJOR_4 +static void tdfb_params(struct processing_module *mod) +{ + struct sof_ipc_stream_params *params = mod->stream_params; + struct comp_buffer *sinkb, *sourceb; + struct comp_dev *dev = mod->dev; + + ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); + component_set_nearest_period_frames(dev, params->rate); + + sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); + ipc4_update_buffer_format(sourceb, &mod->priv.cfg.base_cfg.audio_fmt); + + sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + ipc4_update_buffer_format(sinkb, &mod->priv.cfg.base_cfg.audio_fmt); +} +#endif + static int tdfb_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct tdfb_comp_data *cd = module_get_private_data(mod); struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; struct comp_dev *dev = mod->dev; enum sof_ipc_frame frame_fmt; int source_channels; @@ -741,19 +903,19 @@ static int tdfb_prepare(struct processing_module *mod, comp_info(dev, "tdfb_prepare()"); +#if CONFIG_IPC_MAJOR_4 + tdfb_params(mod); +#endif + /* Find source and sink buffers */ sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - tdfb_set_alignment(&source_c->stream, &sink_c->stream); + tdfb_set_alignment(&sourceb->stream, &sinkb->stream); - frame_fmt = audio_stream_get_frm_fmt(&source_c->stream); - source_channels = audio_stream_get_channels(&source_c->stream); - sink_channels = audio_stream_get_channels(&sink_c->stream); - rate = audio_stream_get_rate(&source_c->stream); - buffer_release(sink_c); - buffer_release(source_c); + frame_fmt = audio_stream_get_frm_fmt(&sourceb->stream); + source_channels = audio_stream_get_channels(&sourceb->stream); + sink_channels = audio_stream_get_channels(&sinkb->stream); + rate = audio_stream_get_rate(&sourceb->stream); /* Initialize filter */ cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); @@ -819,7 +981,7 @@ static int tdfb_reset(struct processing_module *mod) return 0; } -static struct module_interface tdfb_interface = { +static const struct module_interface tdfb_interface = { .init = tdfb_init, .free = tdfb_free, .set_configuration = tdfb_set_config, diff --git a/src/audio/tdfb/tdfb_generic.c b/src/audio/tdfb/tdfb_generic.c index 8306bb6a8991..22f74702ac06 100644 --- a/src/audio/tdfb/tdfb_generic.c +++ b/src/audio/tdfb/tdfb_generic.c @@ -58,8 +58,8 @@ static inline void tdfb_core(struct tdfb_comp_data *cd, int in_nch, int out_nch) void tdfb_fir_s16(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int16_t *x = audio_stream_get_rptr(source); int16_t *y = audio_stream_get_wptr(sink); int fmax; @@ -104,8 +104,8 @@ void tdfb_fir_s16(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource void tdfb_fir_s24(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t *x = audio_stream_get_rptr(source); int32_t *y = audio_stream_get_wptr(sink); int fmax; @@ -150,8 +150,8 @@ void tdfb_fir_s24(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource void tdfb_fir_s32(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t *x = audio_stream_get_rptr(source); int32_t *y = audio_stream_get_wptr(sink); int fmax; diff --git a/src/audio/tdfb/tdfb_hifi3.c b/src/audio/tdfb/tdfb_hifi3.c index 97b5229d02dd..421784db9d1d 100644 --- a/src/audio/tdfb/tdfb_hifi3.c +++ b/src/audio/tdfb/tdfb_hifi3.c @@ -19,8 +19,8 @@ void tdfb_fir_s16(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; struct sof_tdfb_config *cfg = cd->config; struct fir_state_32x16 *f; ae_int16x4 d; @@ -108,8 +108,8 @@ void tdfb_fir_s16(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource void tdfb_fir_s24(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; struct sof_tdfb_config *cfg = cd->config; struct fir_state_32x16 *f; ae_int32x2 d; @@ -197,8 +197,8 @@ void tdfb_fir_s24(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource void tdfb_fir_s32(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; struct sof_tdfb_config *cfg = cd->config; struct fir_state_32x16 *f; ae_int32x2 d; diff --git a/src/audio/tdfb/tdfb_hifiep.c b/src/audio/tdfb/tdfb_hifiep.c index eba8d7c7807e..1f5b71dbe612 100644 --- a/src/audio/tdfb/tdfb_hifiep.c +++ b/src/audio/tdfb/tdfb_hifiep.c @@ -58,8 +58,8 @@ static inline void tdfb_core(struct tdfb_comp_data *cd, int in_nch, int out_nch) void tdfb_fir_s16(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int16_t *x = audio_stream_get_rptr(source); int16_t *y = audio_stream_get_wptr(sink); int fmax; @@ -104,8 +104,8 @@ void tdfb_fir_s16(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource void tdfb_fir_s24(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t *x = audio_stream_get_rptr(source); int32_t *y = audio_stream_get_wptr(sink); int fmax; @@ -150,8 +150,8 @@ void tdfb_fir_s24(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource void tdfb_fir_s32(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t *x = audio_stream_get_rptr(source); int32_t *y = audio_stream_get_wptr(sink); int fmax; diff --git a/src/audio/tone.c b/src/audio/tone.c index 65c934246909..c669698bd13e 100644 --- a/src/audio/tone.c +++ b/src/audio/tone.c @@ -95,7 +95,7 @@ struct comp_data { uint32_t frame_bytes; uint32_t rate; struct tone_state sg[PLATFORM_MAX_CHANNELS]; - void (*tone_func)(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, + void (*tone_func)(struct comp_dev *dev, struct audio_stream *sink, uint32_t frames); }; @@ -113,7 +113,7 @@ static inline void tone_circ_inc_wrap(int32_t **ptr, int32_t *end, size_t size) *ptr = (int32_t *)((size_t)*ptr - size); } -static void tone_s32_default(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, +static void tone_s32_default(struct comp_dev *dev, struct audio_stream *sink, uint32_t frames) { struct comp_data *cd = comp_get_drvdata(dev); @@ -429,7 +429,6 @@ static int tone_params(struct comp_dev *dev, { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); @@ -444,18 +443,12 @@ static int tone_params(struct comp_dev *dev, if (dev->ipc_config.frame_fmt != SOF_IPC_FRAME_S32_LE) return -EINVAL; - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - - audio_stream_set_frm_fmt(&source_c->stream, dev->ipc_config.frame_fmt); - audio_stream_set_frm_fmt(&sink_c->stream, dev->ipc_config.frame_fmt); + audio_stream_set_frm_fmt(&sourceb->stream, dev->ipc_config.frame_fmt); + audio_stream_set_frm_fmt(&sinkb->stream, dev->ipc_config.frame_fmt); /* calculate period size based on config */ cd->period_bytes = dev->frames * - audio_stream_frame_bytes(&source_c->stream); - - buffer_release(sink_c); - buffer_release(source_c); + audio_stream_frame_bytes(&sourceb->stream); return 0; } @@ -634,7 +627,6 @@ static int tone_trigger(struct comp_dev *dev, int cmd) static int tone_copy(struct comp_dev *dev) { struct comp_buffer *sink; - struct comp_buffer __sparse_cache *sink_c; struct comp_data *cd = comp_get_drvdata(dev); uint32_t free; int ret = 0; @@ -645,25 +637,22 @@ static int tone_copy(struct comp_dev *dev) sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); - free = audio_stream_get_free_bytes(&sink_c->stream); + free = audio_stream_get_free_bytes(&sink->stream); /* Test that sink has enough free frames. Then run once to maintain * low latency and steady load for tones. */ if (free >= cd->period_bytes) { /* create tone */ - cd->tone_func(dev, &sink_c->stream, dev->frames); - buffer_stream_writeback(sink_c, cd->period_bytes); + cd->tone_func(dev, &sink->stream, dev->frames); + buffer_stream_writeback(sink, cd->period_bytes); /* calc new free and available */ - comp_update_buffer_produce(sink_c, cd->period_bytes); + comp_update_buffer_produce(sink, cd->period_bytes); ret = dev->frames; } - buffer_release(sink_c); - return ret; } diff --git a/src/audio/up_down_mixer/up_down_mixer.c b/src/audio/up_down_mixer/up_down_mixer.c index e1887865ac70..c6e6c6b5bd58 100644 --- a/src/audio/up_down_mixer/up_down_mixer.c +++ b/src/audio/up_down_mixer/up_down_mixer.c @@ -400,8 +400,8 @@ static int up_down_mixer_init(struct processing_module *mod) /* just stubs for now. Remove these after making these ops optional in the module adapter */ static int up_down_mixer_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct up_down_mixer_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; @@ -456,8 +456,8 @@ up_down_mixer_process(struct processing_module *mod, return 0; } -static struct module_interface up_down_mixer_interface = { - .init = up_down_mixer_init, +static const struct module_interface up_down_mixer_interface = { + .init = up_down_mixer_init, .prepare = up_down_mixer_prepare, .process_audio_stream = up_down_mixer_process, .reset = up_down_mixer_reset, diff --git a/src/audio/volume/Kconfig b/src/audio/volume/Kconfig new file mode 100644 index 000000000000..a0daa89a2940 --- /dev/null +++ b/src/audio/volume/Kconfig @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: BSD-3-Clause + + config COMP_VOLUME + bool "Volume component" + default y + help + Select for Volume component + +if COMP_VOLUME + +config COMP_VOLUME_WINDOWS_FADE + bool "Windows Fade shape volume transitions support" + help + This option enables volume ramp shape that follows + power of 1.75. The shape is not linear, not logarithmic. + The power function uses a lookup table that consumes + 256 bytes. The topology must set volume ramp token to + SOF_VOLUME_WINDOWS_FADE for the volume instance to use + this ramp shape. + +config COMP_VOLUME_LINEAR_RAMP + bool "Linear ramp volume transitions support" + default y + help + This option enables volume linear ramp shape. + +config COMP_PEAK_VOL + bool "Report peak vol data to host" + default y + depends on IPC_MAJOR_4 + help + This option enables reporting to host peak vol regs. + See: struct ipc4_peak_volume_regs + +choice "PEAK_METER_UPDATE_PERIOD_CHOICE" + prompt "The periods(ms) of updating peak meter value" + default PEAK_METER_UPDATE_10MS + depends on COMP_PEAK_VOL + + config PEAK_METER_UPDATE_1MS + bool "1ms" + help + Update the peak meter value every 1ms + + config PEAK_METER_UPDATE_10MS + bool "10ms" + help + Update the peak meter value every 10ms + + config PEAK_METER_UPDATE_100MS + bool "100ms" + help + Update the peak meter value every 100ms + + config PEAK_METER_UPDATE_1000MS + bool "1000ms" + help + Update the peak meter value every 1000ms + endchoice + +config PEAK_METER_UPDATE_PERIOD + int + depends on COMP_PEAK_VOL + default 1 if PEAK_METER_UPDATE_1MS + default 10 if PEAK_METER_UPDATE_10MS + default 100 if PEAK_METER_UPDATE_100MS + default 1000 if PEAK_METER_UPDATE_1000MS + help + Decide which period of update the peak volume meter value + +config COMP_GAIN + bool "GAIN component" + default y + depends on IPC_MAJOR_4 + help + This option enables gain to change volume. It works + as peak volume without updating peak vol to host + +endif # volume \ No newline at end of file diff --git a/src/audio/volume/peak_volume.h b/src/audio/volume/peak_volume.h index fd4a078f0ad5..057db458277a 100644 --- a/src/audio/volume/peak_volume.h +++ b/src/audio/volume/peak_volume.h @@ -24,6 +24,7 @@ #ifndef __SOF_IPC4_PEAK_VOL_H__ #define __SOF_IPC4_PEAK_VOL_H__ +#include #include enum ipc4_vol_mode { @@ -43,7 +44,11 @@ enum ipc4_peak_volume_param { enum ipc4_curve_type { IPC4_AUDIO_CURVE_TYPE_NONE = 0, - IPC4_AUDIO_CURVE_TYPE_WINDOWS_FADE + IPC4_AUDIO_CURVE_TYPE_WINDOWS_FADE, + IPC4_AUDIO_CURVE_TYPE_LINEAR, + IPC4_AUDIO_CURVE_TYPE_LOG, + IPC4_AUDIO_CURVE_TYPE_LINEAR_ZC, + IPC4_AUDIO_CURVE_TYPE_LOG_ZC, }; static const uint32_t IPC4_ALL_CHANNELS_MASK = 0xffffffff; @@ -74,4 +79,28 @@ struct ipc4_peak_volume_module_cfg { struct ipc4_base_module_cfg base_cfg; struct ipc4_peak_volume_config config[]; } __packed __aligned(8); + +static inline enum sof_volume_ramp ipc4_curve_type_convert(enum ipc4_curve_type ipc4_type) +{ + switch (ipc4_type) { + case IPC4_AUDIO_CURVE_TYPE_WINDOWS_FADE: + return SOF_VOLUME_WINDOWS_FADE; + + case IPC4_AUDIO_CURVE_TYPE_LINEAR: + return SOF_VOLUME_LINEAR; + + case IPC4_AUDIO_CURVE_TYPE_LOG: + return SOF_VOLUME_LOG; + + case IPC4_AUDIO_CURVE_TYPE_LINEAR_ZC: + return SOF_VOLUME_LINEAR_ZC; + + case IPC4_AUDIO_CURVE_TYPE_LOG_ZC: + return SOF_VOLUME_LOG_ZC; + + case IPC4_AUDIO_CURVE_TYPE_NONE: + default: + return SOF_VOLUME_WINDOWS_NO_FADE; + } +} #endif diff --git a/src/audio/volume/volume.c b/src/audio/volume/volume.c index a4128136a5e5..002ceff9d852 100644 --- a/src/audio/volume/volume.c +++ b/src/audio/volume/volume.c @@ -57,7 +57,7 @@ LOG_MODULE_REGISTER(volume, CONFIG_SOF_LOG_LEVEL); * \param[in] frames Number of frames. * \param[in,out] prev_sum Previous sum of channel samples. */ -static uint32_t vol_zc_get_s16(const struct audio_stream __sparse_cache *source, +static uint32_t vol_zc_get_s16(const struct audio_stream *source, uint32_t frames, int64_t *prev_sum) { uint32_t curr_frames = frames; @@ -105,7 +105,7 @@ static uint32_t vol_zc_get_s16(const struct audio_stream __sparse_cache *source, * \param[in] frames Number of frames. * \param[in,out] prev_sum Previous sum of channel samples. */ -static uint32_t vol_zc_get_s24(const struct audio_stream __sparse_cache *source, +static uint32_t vol_zc_get_s24(const struct audio_stream *source, uint32_t frames, int64_t *prev_sum) { int64_t sum; @@ -153,7 +153,7 @@ static uint32_t vol_zc_get_s24(const struct audio_stream __sparse_cache *source, * \param[in] frames Number of frames. * \param[in,out] prev_sum Previous sum of channel samples. */ -static uint32_t vol_zc_get_s32(const struct audio_stream __sparse_cache *source, +static uint32_t vol_zc_get_s32(const struct audio_stream *source, uint32_t frames, int64_t *prev_sum) { int64_t sum; @@ -243,6 +243,24 @@ static inline int32_t volume_windows_fade_ramp(struct vol_data *cd, int32_t ramp } #endif +void volume_set_ramp_channel_counter(struct vol_data *cd, uint32_t channels_count) +{ + int i; + bool is_same_volume = true; + + for (i = 1; i < channels_count; i++) { + if (cd->tvolume[0] != cd->tvolume[i]) { + is_same_volume = false; + break; + } + } + + if (is_same_volume) + cd->ramp_channel_counter = 1; + else + cd->ramp_channel_counter = channels_count; +} + /** * \brief Ramps volume changes over time. * \param[in,out] vol_data Volume component data @@ -272,7 +290,7 @@ static inline void volume_ramp(struct processing_module *mod) #endif /* Update each volume if it's not at target for active channels */ - for (i = 0; i < cd->channels; i++) { + for (i = 0; i < cd->ramp_channel_counter; i++) { /* skip if target reached */ volume = cd->volume[i]; tvolume = cd->tvolume[i]; @@ -283,18 +301,22 @@ static inline void volume_ramp(struct processing_module *mod) * calculated from previous gain and ramp time. The slope * coefficient is calculated in volume_set_chan(). */ -#if defined CONFIG_COMP_VOLUME_WINDOWS_FADE && defined CONFIG_COMP_VOLUME_LINEAR_RAMP - if (cd->ramp_type == SOF_VOLUME_WINDOWS_FADE) + switch (cd->ramp_type) { +#if CONFIG_COMP_VOLUME_WINDOWS_FADE + case SOF_VOLUME_WINDOWS_FADE: new_vol = volume_windows_fade_ramp(cd, ramp_time, i); - else + break; +#endif +#if CONFIG_COMP_VOLUME_LINEAR_RAMP + case SOF_VOLUME_LINEAR: + case SOF_VOLUME_LINEAR_ZC: new_vol = volume_linear_ramp(cd, ramp_time, i); -#elif defined CONFIG_COMP_VOLUME_WINDOWS_FADE - new_vol = volume_windows_fade_ramp(cd, ramp_time, i); -#elif defined CONFIG_COMP_VOLUME_LINEAR_RAMP - new_vol = volume_linear_ramp(cd, ramp_time, i); -#else - new_vol = tvolume; + break; #endif + default: + new_vol = tvolume; + } + if (volume < tvolume) { /* ramp up, check if ramp completed */ if (new_vol < tvolume) @@ -310,6 +332,9 @@ static inline void volume_ramp(struct processing_module *mod) } cd->volume[i] = new_vol; } + /* assign other channel volume as the first calculated volume with same volume case */ + for (i = cd->ramp_channel_counter; i < cd->channels; i++) + cd->volume[i] = cd->volume[0]; cd->is_passthrough = cd->ramp_finished; for (i = 0; i < cd->channels; i++) { @@ -532,8 +557,9 @@ static int volume_process(struct processing_module *mod, comp_dbg(mod->dev, "volume_process()"); while (avail_frames) { +#if CONFIG_COMP_PEAK_VOL volume_update_current_vol_ipc4(cd); - +#endif if (cd->ramp_finished || cd->vol_ramp_frames > avail_frames) { /* without ramping process all at once */ frames = avail_frames; @@ -575,7 +601,7 @@ static int volume_process(struct processing_module *mod, * \param[in,out] dev Volume base component device. */ static vol_zc_func vol_get_zc_function(struct comp_dev *dev, - struct comp_buffer __sparse_cache *sinkb) + struct comp_buffer *sinkb) { int i; @@ -593,8 +619,8 @@ static vol_zc_func vol_get_zc_function(struct comp_dev *dev, * \param[in,out] source Structure pointer of source. * \param[in,out] sink Structure pointer of sink. */ -static void volume_set_alignment(struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink) +static void volume_set_alignment(struct audio_stream *source, + struct audio_stream *sink) { #if XCHAL_HAVE_HIFI3 || XCHAL_HAVE_HIFI4 @@ -631,14 +657,13 @@ static void volume_set_alignment(struct audio_stream __sparse_cache *source, * to also do some type of conversion here. */ static int volume_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct vol_data *cd = module_get_private_data(mod); struct module_data *md = &mod->priv; struct comp_dev *dev = mod->dev; struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; uint32_t sink_period_bytes; int ret; int i; @@ -653,20 +678,15 @@ static int volume_prepare(struct processing_module *mod, sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - sink_c = buffer_acquire(sinkb); - source_c = buffer_acquire(sourceb); - - volume_set_alignment(&source_c->stream, &sink_c->stream); - - buffer_release(source_c); + volume_set_alignment(&sourceb->stream, &sinkb->stream); /* get sink period bytes */ - sink_period_bytes = audio_stream_period_bytes(&sink_c->stream, + sink_period_bytes = audio_stream_period_bytes(&sinkb->stream, dev->frames); - if (audio_stream_get_size(&sink_c->stream) < sink_period_bytes) { + if (audio_stream_get_size(&sinkb->stream) < sink_period_bytes) { comp_err(dev, "volume_prepare(): sink buffer size %d is insufficient < %d", - audio_stream_get_size(&sink_c->stream), sink_period_bytes); + audio_stream_get_size(&sinkb->stream), sink_period_bytes); ret = -ENOMEM; goto err; } @@ -680,7 +700,7 @@ static int volume_prepare(struct processing_module *mod, goto err; } - cd->zc_get = vol_get_zc_function(dev, sink_c); + cd->zc_get = vol_get_zc_function(dev, sinkb); if (!cd->zc_get) { comp_err(dev, "volume_prepare(): invalid cd->zc_get"); ret = -EINVAL; @@ -695,16 +715,14 @@ static int volume_prepare(struct processing_module *mod, */ cd->ramp_finished = false; - cd->channels = audio_stream_get_channels(&sink_c->stream); + cd->channels = audio_stream_get_channels(&sinkb->stream); if (cd->channels > SOF_IPC_MAX_CHANNELS) { ret = -EINVAL; goto err; } cd->sample_rate_inv = (int32_t)(1000LL * INT32_MAX / - audio_stream_get_rate(&sink_c->stream)); - - buffer_release(sink_c); + audio_stream_get_rate(&sinkb->stream)); for (i = 0; i < cd->channels; i++) { cd->volume[i] = cd->vol_min; @@ -725,7 +743,6 @@ static int volume_prepare(struct processing_module *mod, return 0; err: - buffer_release(sink_c); comp_set_state(dev, COMP_TRIGGER_RESET); return ret; } @@ -745,8 +762,8 @@ static int volume_reset(struct processing_module *mod) return 0; } -static struct module_interface volume_interface = { - .init = volume_init, +static const struct module_interface volume_interface = { + .init = volume_init, .prepare = volume_prepare, .process_audio_stream = volume_process, .set_configuration = volume_set_config, @@ -759,8 +776,8 @@ DECLARE_MODULE_ADAPTER(volume_interface, volume_uuid, volume_tr); SOF_MODULE_INIT(volume, sys_comp_module_volume_interface_init); #if CONFIG_COMP_GAIN -static struct module_interface gain_interface = { - .init = volume_init, +static const struct module_interface gain_interface = { + .init = volume_init, .prepare = volume_prepare, .process_audio_stream = volume_process, .set_configuration = volume_set_config, diff --git a/src/audio/volume/volume.h b/src/audio/volume/volume.h index 856c27568d84..5e8f46a54389 100644 --- a/src/audio/volume/volume.h +++ b/src/audio/volume/volume.h @@ -134,7 +134,7 @@ typedef void (*vol_scale_func)(struct processing_module *mod, struct input_strea /** * \brief volume interface for function getting nearest zero crossing frame */ -typedef uint32_t (*vol_zc_func)(const struct audio_stream __sparse_cache *source, +typedef uint32_t (*vol_zc_func)(const struct audio_stream *source, uint32_t frames, int64_t *prev_sum); /** @@ -176,6 +176,7 @@ struct vol_data { bool copy_gain; /**< control copy gain or not */ uint32_t attenuation; /**< peakmeter adjustment in range [0 - 31] */ bool is_passthrough; /**< is passthrough or do gain multiplication */ + uint32_t ramp_channel_counter; /**< channels need new ramp volume */ }; /** \brief Volume processing functions map. */ @@ -205,7 +206,7 @@ struct comp_zc_func_map { * \param[in] cd Volume data structure. */ static inline vol_scale_func vol_get_processing_function(struct comp_dev *dev, - struct comp_buffer __sparse_cache *sinkb, + struct comp_buffer *sinkb, struct vol_data *cd) { int i; @@ -308,4 +309,6 @@ void volume_set_chan_mute(struct processing_module *mod, int chan); void volume_set_chan_unmute(struct processing_module *mod, int chan); +void volume_set_ramp_channel_counter(struct vol_data *cd, uint32_t channels_count); + #endif /* __SOF_AUDIO_VOLUME_H__ */ diff --git a/src/audio/volume/volume_generic.c b/src/audio/volume/volume_generic.c index 966f62b7da34..30498bc992eb 100644 --- a/src/audio/volume/volume_generic.c +++ b/src/audio/volume/volume_generic.c @@ -61,8 +61,8 @@ static void vol_s24_to_s24(struct processing_module *mod, struct input_stream_bu uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t vol; int32_t *x, *x0; int32_t *y, *y0; @@ -110,8 +110,8 @@ static void vol_passthrough_s24_to_s24(struct processing_module *mod, struct output_stream_buffer *bsink, uint32_t frames, uint32_t attenuation) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t *x; int32_t *y; int nmax, n; @@ -153,8 +153,8 @@ static void vol_s32_to_s32(struct processing_module *mod, struct input_stream_bu uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t vol; int32_t *x, *x0; int32_t *y, *y0; @@ -205,8 +205,8 @@ static void vol_passthrough_s32_to_s32(struct processing_module *mod, struct output_stream_buffer *bsink, uint32_t frames, uint32_t attenuation) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t *x; int32_t *y; int nmax, n; @@ -247,8 +247,8 @@ static void vol_s16_to_s16(struct processing_module *mod, struct input_stream_bu uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t vol; int16_t *x, *x0; int16_t *y, *y0; @@ -296,8 +296,8 @@ static void vol_passthrough_s16_to_s16(struct processing_module *mod, struct output_stream_buffer *bsink, uint32_t frames, uint32_t attenuation) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int16_t *x; int16_t *y; int nmax, n; diff --git a/src/audio/volume/volume_generic_with_peakvol.c b/src/audio/volume/volume_generic_with_peakvol.c index fb0cff0bee3a..0ef720d78665 100644 --- a/src/audio/volume/volume_generic_with_peakvol.c +++ b/src/audio/volume/volume_generic_with_peakvol.c @@ -57,8 +57,8 @@ static void vol_s24_to_s24(struct processing_module *mod, struct input_stream_bu uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t vol; int32_t *x, *x0; int32_t *y, *y0; @@ -112,8 +112,8 @@ static void vol_passthrough_s24_to_s24(struct processing_module *mod, uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t *x, *x0; int32_t *y, *y0; int nmax, n, i, j; @@ -166,8 +166,8 @@ static void vol_s32_to_s32(struct processing_module *mod, struct input_stream_bu uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t vol; int32_t *x, *x0; int32_t *y, *y0; @@ -224,8 +224,8 @@ static void vol_passthrough_s32_to_s32(struct processing_module *mod, uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t *x, *x0; int32_t *y, *y0; int nmax, n, i, j; @@ -280,8 +280,8 @@ static void vol_s16_to_s16(struct processing_module *mod, struct input_stream_bu uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t vol; int16_t *x, *x0; int16_t *y, *y0; @@ -336,8 +336,8 @@ static void vol_passthrough_s16_to_s16(struct processing_module *mod, uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t *x, *x0; int32_t *y, *y0; int nmax, n, i, j; diff --git a/src/audio/volume/volume_hifi3.c b/src/audio/volume/volume_hifi3.c index 05746ab40f67..e32b8551c775 100644 --- a/src/audio/volume/volume_hifi3.c +++ b/src/audio/volume/volume_hifi3.c @@ -61,8 +61,8 @@ static void vol_s24_to_s24_s32(struct processing_module *mod, struct input_strea uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); ae_f32x2 out_sample = AE_ZERO32(); ae_f32x2 volume = AE_ZERO32(); @@ -147,8 +147,8 @@ static void vol_passthrough_s24_to_s24_s32(struct processing_module *mod, struct output_stream_buffer *bsink, uint32_t frames, uint32_t attenuation) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); int i, n, m; ae_valign inu = AE_ZALIGN64(); @@ -198,8 +198,8 @@ static void vol_s32_to_s24_s32(struct processing_module *mod, struct input_strea uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); ae_f32x2 out_sample = AE_ZERO32(); ae_f32x2 volume = AE_ZERO32(); @@ -289,8 +289,8 @@ static void vol_passthrough_s32_to_s24_s32(struct processing_module *mod, struct output_stream_buffer *bsink, uint32_t frames, uint32_t attenuation) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); int i, n, m; ae_valign inu = AE_ZALIGN64(); @@ -339,8 +339,8 @@ static void vol_s16_to_s16(struct processing_module *mod, struct input_stream_bu uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 volume0 = AE_ZERO32(); ae_f32x2 volume1 = AE_ZERO32(); ae_f32x2 out_sample0 = AE_ZERO32(); @@ -436,8 +436,8 @@ static void vol_passthrough_s16_to_s16(struct processing_module *mod, struct output_stream_buffer *bsink, uint32_t frames, uint32_t attenuation) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f16x4 in_sample = AE_ZERO16(); int i, n, m; ae_valign inu = AE_ZALIGN64(); diff --git a/src/audio/volume/volume_hifi3_with_peakvol.c b/src/audio/volume/volume_hifi3_with_peakvol.c index 5d0ff31b0385..9bda00a27bc7 100644 --- a/src/audio/volume/volume_hifi3_with_peakvol.c +++ b/src/audio/volume/volume_hifi3_with_peakvol.c @@ -41,8 +41,8 @@ static void vol_s24_to_s24_s32(struct processing_module *mod, struct input_strea uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); ae_f32x2 out_sample = AE_ZERO32(); ae_f32x2 volume = AE_ZERO32(); @@ -116,8 +116,8 @@ static void vol_passthrough_s24_to_s24_s32(struct processing_module *mod, uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); int channel, n, i, m; ae_f32 *in0 = (ae_f32 *)audio_stream_wrap(source, (char *)audio_stream_get_rptr(source) @@ -176,8 +176,8 @@ static void vol_s32_to_s24_s32(struct processing_module *mod, struct input_strea uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); ae_f32x2 out_sample = AE_ZERO32(); ae_f32x2 volume = AE_ZERO32(); @@ -252,8 +252,8 @@ static void vol_passthrough_s32_to_s24_s32(struct processing_module *mod, uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); int i, n, channel, m; const int channels_count = audio_stream_get_channels(sink); @@ -312,8 +312,8 @@ static void vol_s16_to_s16(struct processing_module *mod, struct input_stream_bu uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 volume = AE_ZERO32(); ae_f32x2 out_sample0 = AE_ZERO32(); ae_f16x4 in_sample = AE_ZERO16(); @@ -394,8 +394,8 @@ static void vol_passthrough_s16_to_s16(struct processing_module *mod, uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f16x4 in_sample = AE_ZERO16(); int i, n, channel, m; ae_f16 *in; diff --git a/src/audio/volume/volume_hifi4.c b/src/audio/volume/volume_hifi4.c index 880aef23f139..d0d114dcfc5d 100644 --- a/src/audio/volume/volume_hifi4.c +++ b/src/audio/volume/volume_hifi4.c @@ -61,8 +61,8 @@ static void vol_s24_to_s24_s32(struct processing_module *mod, struct input_strea uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); ae_f32x2 out_sample = AE_ZERO32(); ae_f32x2 volume = AE_ZERO32(); @@ -147,8 +147,8 @@ static void vol_passthrough_s24_to_s24_s32(struct processing_module *mod, struct output_stream_buffer *bsink, uint32_t frames, uint32_t attenuation) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); int i, n, m; ae_valign inu = AE_ZALIGN64(); @@ -198,8 +198,8 @@ static void vol_s32_to_s24_s32(struct processing_module *mod, struct input_strea uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); ae_f32x2 out_sample = AE_ZERO32(); ae_f32x2 volume = AE_ZERO32(); @@ -289,8 +289,8 @@ static void vol_passthrough_s32_to_s24_s32(struct processing_module *mod, struct output_stream_buffer *bsink, uint32_t frames, uint32_t attenuation) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); int i, n, m; ae_valign inu = AE_ZALIGN64(); @@ -338,8 +338,8 @@ static void vol_s16_to_s16(struct processing_module *mod, struct input_stream_bu uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 volume0 = AE_ZERO32(); ae_f32x2 volume1 = AE_ZERO32(); ae_f32x2 out_sample0 = AE_ZERO32(); @@ -435,8 +435,8 @@ static void vol_passthrough_s16_to_s16(struct processing_module *mod, struct output_stream_buffer *bsink, uint32_t frames, uint32_t attenuation) { - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f16x4 in_sample = AE_ZERO16(); int i, n, m; ae_valign inu = AE_ZALIGN64(); diff --git a/src/audio/volume/volume_hifi4_with_peakvol.c b/src/audio/volume/volume_hifi4_with_peakvol.c index df1eafff2788..cbb08e297b87 100644 --- a/src/audio/volume/volume_hifi4_with_peakvol.c +++ b/src/audio/volume/volume_hifi4_with_peakvol.c @@ -54,8 +54,8 @@ static void vol_s24_to_s24_s32(struct processing_module *mod, struct input_strea uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); ae_f32x2 out_sample = AE_ZERO32(); ae_f32x2 volume = AE_ZERO32(); @@ -150,8 +150,8 @@ static void vol_passthrough_s24_to_s24_s32(struct processing_module *mod, uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); int i, n, m; @@ -217,8 +217,8 @@ static void vol_s32_to_s24_s32(struct processing_module *mod, struct input_strea uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); ae_f32x2 out_sample = AE_ZERO32(); ae_f32x2 volume = AE_ZERO32(); @@ -321,8 +321,8 @@ static void vol_passthrough_s32_to_s24_s32(struct processing_module *mod, uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); int i, n, m; ae_valign inu = AE_ZALIGN64(); @@ -385,8 +385,8 @@ static void vol_s16_to_s16(struct processing_module *mod, struct input_stream_bu uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 volume0 = AE_ZERO32(); ae_f32x2 volume1 = AE_ZERO32(); ae_f32x2 out_sample0 = AE_ZERO32(); @@ -501,8 +501,8 @@ static void vol_passthrough_s16_to_s16(struct processing_module *mod, uint32_t attenuation) { struct vol_data *cd = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f16x4 in_sample = AE_ZERO16(); int i, n, m; ae_valign inu = AE_ZALIGN64(); diff --git a/src/audio/volume/volume_ipc3.c b/src/audio/volume/volume_ipc3.c index c1378acbdd45..4a68d4a6d2df 100644 --- a/src/audio/volume/volume_ipc3.c +++ b/src/audio/volume/volume_ipc3.c @@ -37,7 +37,6 @@ LOG_MODULE_DECLARE(volume, CONFIG_SOF_LOG_LEVEL); void set_volume_process(struct vol_data *cd, struct comp_dev *dev, bool source_or_sink) { struct comp_buffer *bufferb; - struct comp_buffer __sparse_cache *buffer_c; if (source_or_sink) bufferb = list_first_item(&dev->bsource_list, @@ -46,10 +45,7 @@ void set_volume_process(struct vol_data *cd, struct comp_dev *dev, bool source_o bufferb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - buffer_c = buffer_acquire(bufferb); - cd->scale_vol = vol_get_processing_function(dev, buffer_c, cd); - - buffer_release(buffer_c); + cd->scale_vol = vol_get_processing_function(dev, bufferb, cd); } /** @@ -149,6 +145,9 @@ int volume_init(struct processing_module *mod) cd->muted[i] = false; } + /* all target volume are same */ + cd->ramp_channel_counter = 1; + switch (cd->ramp_type) { #if CONFIG_COMP_VOLUME_LINEAR_RAMP case SOF_VOLUME_LINEAR: @@ -221,6 +220,7 @@ int volume_set_config(struct processing_module *mod, uint32_t config_id, return ret; } } + volume_set_ramp_channel_counter(cd, cd->channels); volume_ramp_check(mod); break; diff --git a/src/audio/volume/volume_ipc4.c b/src/audio/volume/volume_ipc4.c index 0ec4c4c275f0..f5826501f256 100644 --- a/src/audio/volume/volume_ipc4.c +++ b/src/audio/volume/volume_ipc4.c @@ -58,13 +58,10 @@ static int set_volume_ipc4(struct vol_data *cd, uint32_t const channel, cd->mvolume[channel] = 0; /* set muted as false*/ cd->muted[channel] = false; -#if CONFIG_COMP_VOLUME_WINDOWS_FADE + /* ATM there is support for the same ramp for all channels */ - if (curve_type == IPC4_AUDIO_CURVE_TYPE_WINDOWS_FADE) - cd->ramp_type = SOF_VOLUME_WINDOWS_FADE; - else - cd->ramp_type = SOF_VOLUME_WINDOWS_NO_FADE; -#endif + cd->ramp_type = ipc4_curve_type_convert((enum ipc4_curve_type)curve_type); + return 0; } @@ -89,8 +86,13 @@ static void init_ramp(struct vol_data *cd, uint32_t curve_duration, uint32_t tar /* In IPC4 driver sends curve_duration in hundred of ns - it should be * converted into ms value required by firmware */ - cd->initial_ramp = Q_MULTSR_32X32((int64_t)curve_duration, - Q_CONVERT_FLOAT(1.0 / 10000, 31), 0, 31, 0); + if (cd->ramp_type == SOF_VOLUME_WINDOWS_NO_FADE) { + cd->initial_ramp = 0; + cd->ramp_finished = true; + } else { + cd->initial_ramp = Q_MULTSR_32X32((int64_t)curve_duration, + Q_CONVERT_FLOAT(1.0 / 10000, 31), 0, 31, 0); + } if (!cd->initial_ramp) { /* In case when initial ramp time is equal to zero, vol_min and @@ -157,7 +159,7 @@ int volume_init(struct processing_module *mod) md->private = cd; - for (channel = 0; channel < channels_count ; channel++) { + for (channel = 0; channel < channels_count; channel++) { if (vol->config[0].channel_id == IPC4_ALL_CHANNELS_MASK) channel_cfg = 0; else @@ -174,6 +176,8 @@ int volume_init(struct processing_module *mod) init_ramp(cd, vol->config[0].curve_duration, target_volume[0]); + volume_set_ramp_channel_counter(cd, channels_count); + cd->mailbox_offset = offsetof(struct ipc4_fw_registers, peak_vol_regs); cd->mailbox_offset += instance_id * sizeof(struct ipc4_peak_volume_regs); @@ -256,6 +260,8 @@ static int volume_set_volume(struct processing_module *mod, const uint8_t *data, } } + volume_set_ramp_channel_counter(cd, channels_count); + cd->scale_vol = vol_get_processing_function(dev, cd); volume_prepare_ramp(dev, cd); @@ -366,7 +372,6 @@ int volume_get_config(struct processing_module *mod, static int volume_params(struct processing_module *mod) { struct sof_ipc_stream_params *params = mod->stream_params; - struct comp_buffer __sparse_cache *sink_c, *source_c; struct comp_buffer *sinkb, *sourceb; struct comp_dev *dev = mod->dev; @@ -378,14 +383,10 @@ static int volume_params(struct processing_module *mod) /* volume component will only ever have 1 sink buffer */ sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sinkb); - ipc4_update_buffer_format(sink_c, &mod->priv.cfg.base_cfg.audio_fmt); - buffer_release(sink_c); + ipc4_update_buffer_format(sinkb, &mod->priv.cfg.base_cfg.audio_fmt); sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - source_c = buffer_acquire(sourceb); - ipc4_update_buffer_format(source_c, &mod->priv.cfg.base_cfg.audio_fmt); - buffer_release(source_c); + ipc4_update_buffer_format(sourceb, &mod->priv.cfg.base_cfg.audio_fmt); return 0; } diff --git a/src/drivers/amd/CMakeLists.txt b/src/drivers/amd/CMakeLists.txt index f3c352bb17fc..962104a1fc3a 100644 --- a/src/drivers/amd/CMakeLists.txt +++ b/src/drivers/amd/CMakeLists.txt @@ -2,7 +2,7 @@ add_subdirectory(common) if(CONFIG_RENOIR) add_subdirectory(renoir) -elseif(CONFIG_REMBRANDT) +elseif(CONFIG_REMBRANDT OR CONFIG_ACP_6_3) add_subdirectory(rembrandt) elseif(CONFIG_VANGOGH) add_subdirectory(vangogh) diff --git a/src/drivers/amd/rembrandt/acp_hs_dai.c b/src/drivers/amd/rembrandt/acp_hs_dai.c index 69aba78da6bd..651dd3bfbf37 100644 --- a/src/drivers/amd/rembrandt/acp_hs_dai.c +++ b/src/drivers/amd/rembrandt/acp_hs_dai.c @@ -158,6 +158,9 @@ static int hsdai_get_fifo(struct dai *dai, int direction, int stream_id) static int hsdai_get_handshake(struct dai *dai, int direction, int stream_id) { + int handshake = dai->plat_data.fifo[direction].handshake; + + interrupt_get_irq(handshake, "irqsteer1"); return dai->plat_data.fifo[direction].handshake; } diff --git a/src/drivers/amd/rembrandt/acp_hs_dma.c b/src/drivers/amd/rembrandt/acp_hs_dma.c index dd3026236055..e49fca13615e 100644 --- a/src/drivers/amd/rembrandt/acp_hs_dma.c +++ b/src/drivers/amd/rembrandt/acp_hs_dma.c @@ -96,9 +96,13 @@ static int acp_dai_hs_dma_start(struct dma_chan_data *channel) acp_pdm_en = (uint32_t)io_reg_read(PU_REGISTER_BASE + ACP_WOV_PDM_ENABLE); if (!hs_iter.bits.hstdm_txen && !hs_irer.bits.hstdm_rx_en && !acp_pdm_en) { - io_reg_write((PU_REGISTER_BASE + ACP_CLKMUX_SEL), ACP_ACLK_CLK_SEL); /* Request SMU to set aclk to 600 Mhz */ acp_change_clock_notify(600000000); + io_reg_write((PU_REGISTER_BASE + ACP_CLKMUX_SEL), ACP_ACLK_CLK_SEL); +#ifdef CONFIG_ACP_6_3 + if (!io_reg_read(PU_REGISTER_BASE + ACP_I2S_196MHZ_CLK_SEL)) + io_reg_write((PU_REGISTER_BASE + ACP_I2S_196MHZ_CLK_SEL), 0x1); +#endif } if (channel->direction == DMA_DIR_MEM_TO_DEV) { @@ -180,8 +184,12 @@ static int acp_dai_hs_dma_stop(struct dma_chan_data *channel) io_reg_write((PU_REGISTER_BASE + ACP_HSTDM_IER), HS_IER_DISABLE); /* Request SMU to scale down aclk to minimum clk */ if (!acp_pdm_en) { - acp_change_clock_notify(0); io_reg_write((PU_REGISTER_BASE + ACP_CLKMUX_SEL), ACP_INTERNAL_CLK_SEL); + acp_change_clock_notify(0); +#ifdef CONFIG_ACP_6_3 + if (io_reg_read(PU_REGISTER_BASE + ACP_I2S_196MHZ_CLK_SEL)) + io_reg_write((PU_REGISTER_BASE + ACP_I2S_196MHZ_CLK_SEL), 0x0); +#endif } } return 0; diff --git a/src/drivers/amd/rembrandt/interrupt.c b/src/drivers/amd/rembrandt/interrupt.c index 93b03d66978b..f183186c2f74 100644 --- a/src/drivers/amd/rembrandt/interrupt.c +++ b/src/drivers/amd/rembrandt/interrupt.c @@ -104,6 +104,45 @@ static int get_first_irq(uint64_t ints) return ffs(ints) - 1; } +static inline void acp_handle_irq_5(struct irq_cascade_desc *cascade, + uint32_t line_index, uint64_t status) +{ + int core = cpu_get_id(); + struct list_item *clist; + struct irq_desc *child = NULL; + int bit; + bool handled; + k_spinlock_key_t key; + + while (status) { + bit = get_first_irq(status); + handled = false; + status &= ~(1ull << bit); + bit = 5; + + key = k_spin_lock(&cascade->lock); + + list_for_item(clist, &cascade->child[bit].list) { + child = container_of(clist, struct irq_desc, irq_list); + + if (child->handler && (child->cpu_mask & 1 << core)) { + k_spin_unlock(&cascade->lock, key); + child->handler(child->handler_arg); + k_spin_lock(&cascade->lock); + handled = true; + } + } + + k_spin_unlock(&cascade->lock, key); + + if (!handled) { + tr_err(&acp_irq_tr, "irq_handler(): not handled, bit %d", + bit); + acp_irq_mask_int(line_index * IRQS_PER_LINE + bit); + } + } +} + static inline void acp_handle_irq(struct irq_cascade_desc *cascade, uint32_t line_index, uint64_t status) { @@ -140,6 +179,24 @@ static inline void acp_handle_irq(struct irq_cascade_desc *cascade, } } +static void irqhandler_5(void *data) +{ + uint32_t line_index = 5; + struct irq_desc *parent = data; + struct irq_cascade_desc *cascade = + container_of(parent, struct irq_cascade_desc, desc); + uint64_t status; + + line_index = 5; + status = acp_get_irq_interrupts(line_index); + + if (status) + /* Handle current interrupts */ + acp_handle_irq_5(cascade, line_index, status); + else + tr_err(&acp_irq_tr, "invalid interrupt status"); +} + static inline void irq_handler(void *data, uint32_t line_index) { struct irq_desc *parent = data; @@ -165,7 +222,6 @@ DEFINE_IRQ_HANDLER(0) DEFINE_IRQ_HANDLER(1) DEFINE_IRQ_HANDLER(3) DEFINE_IRQ_HANDLER(4) -DEFINE_IRQ_HANDLER(5) static void acp_irq_mask(struct irq_desc *desc, uint32_t irq, unsigned int core) { @@ -207,6 +263,7 @@ static const struct irq_cascade_tmpl dsp_irq[] = { .global_mask = false, }, { + .name = "irqsteer1", .irq = IRQ_NUM_EXT_LEVEL5, .handler = irqhandler_5, .ops = &irq_ops, diff --git a/src/drivers/amd/rembrandt/ipc.c b/src/drivers/amd/rembrandt/ipc.c index 8628ffecfb4f..f8a17cdedab5 100644 --- a/src/drivers/amd/rembrandt/ipc.c +++ b/src/drivers/amd/rembrandt/ipc.c @@ -121,7 +121,7 @@ int ipc_platform_send_msg(const struct ipc_msg *msg) sw_intr_stat = (acp_dsp_sw_intr_stat_t) io_reg_read(PU_REGISTER_BASE + ACP_DSP_SW_INTR_STAT); status = sw_intr_stat.bits.dsp0_to_host_intr_stat; - return ret; + return -EBUSY; } lock = io_reg_read(PU_REGISTER_BASE + ACP_AXI2DAGB_SEM_0); while (lock) diff --git a/src/drivers/imx/CMakeLists.txt b/src/drivers/imx/CMakeLists.txt index 874e8c012190..b5dc724256c7 100644 --- a/src/drivers/imx/CMakeLists.txt +++ b/src/drivers/imx/CMakeLists.txt @@ -16,10 +16,10 @@ endif() if(CONFIG_IMX_SDMA) add_local_sources(sof sdma.c) +endif() - if (CONFIG_HAVE_SDMA_FIRMWARE) - target_include_directories(sof PRIVATE ${CONFIG_SDMA_SCRIPT_CODE}) - endif() +if(CONFIG_IMX_MICFIL) + add_local_sources(sof micfil.c) endif() if(CONFIG_IMX_INTERRUPT_IRQSTEER) diff --git a/src/drivers/imx/Kconfig b/src/drivers/imx/Kconfig index a74cc8e552e4..85f2a50a1162 100644 --- a/src/drivers/imx/Kconfig +++ b/src/drivers/imx/Kconfig @@ -21,6 +21,16 @@ config IMX_ESAI help Select this to enable support for i.MX ESAI IP. +config IMX_MICFIL + bool "i.MX MICFIL PDM driver" + default n + depends on IMX + select HAVE_SDMA_FIRMWARE + help + Select this to enable support for i.MX MICFIL PDM IP. This block implements + the required digital interface to provide a 24-bits audio signal from a PDM + microphone bitstream in a configurable output sampling rate + config IMX_INTERRUPT_IRQSTEER bool default n @@ -36,16 +46,8 @@ config IMX_INTERRUPT_GENERIC It enables NXP platforms-specific features. config HAVE_SDMA_FIRMWARE - bool + bool "Enable SDMA firmware load" default n help Select this to load SDMA firmware to enable additional functionality for SDMA controller. - -if HAVE_SDMA_FIRMWARE - config SDMA_SCRIPT_CODE - string "SDMA script code path" - help - This option is a string and provides the path where to find the sdma script - code header. -endif diff --git a/src/drivers/imx/micfil.c b/src/drivers/imx/micfil.c new file mode 100644 index 000000000000..3995dbc48589 --- /dev/null +++ b/src/drivers/imx/micfil.c @@ -0,0 +1,335 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright 2023 NXP +// +// Author: Daniel Baluta + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(micfil_dai, CONFIG_SOF_LOG_LEVEL); + +/* dd400475-35d7-4045-ab03-0c34957d7a08 */ +DECLARE_SOF_UUID("micfil-dai", micfil_uuid, 0xdd400475, 0x35d7, 0x4045, + 0xab, 0x03, 0x0c, 0x34, 0x95, 0x7d, 0x7a, 0x08); + +DECLARE_TR_CTX(micfil_tr, SOF_UUID(micfil_uuid), LOG_LEVEL_INFO); + +#define MICFIL_OSR_DEFAULT 16 +/* set default gain to 2 */ +#define MICFIL_DEFAULT_ADJ_RANGE 0x22222222 +#define MICFIL_CLK_ROOT 24576000 + +enum micfil_quality { + QUALITY_HIGH, + QUALITY_MEDIUM, + QUALITY_LOW, + QUALITY_VLOW0, + QUALITY_VLOW1, + QUALITY_VLOW2, +}; + +static void micfil_reset(struct dai *dai) +{ + dai_update_bits(dai, REG_MICFIL_CTRL1, MICFIL_CTRL1_MDIS, 0); + dai_update_bits(dai, REG_MICFIL_CTRL1, MICFIL_CTRL1_SRES, MICFIL_CTRL1_SRES); + dai_update_bits(dai, REG_MICFIL_STAT, 0xff, 0xff); +} + +static int micfil_get_hw_params(struct dai *dai, + struct sof_ipc_stream_params *params, int dir) +{ + struct micfil_pdata *micfil = dai_get_drvdata(dai); + + dai_info(dai, "micfil_get_hw_params()"); + + params->rate = micfil->params.pdm_rate; + params->channels = micfil->params.pdm_ch; + params->buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED; + params->frame_fmt = SOF_IPC_FRAME_S32_LE; + + return 0; +} + +static int micfil_set_quality(struct dai *dai) +{ + struct micfil_pdata *micfil = dai_get_drvdata(dai); + int qsel; + + switch (micfil->quality) { + case QUALITY_HIGH: + qsel = MICFIL_QSEL_HIGH_QUALITY; + break; + case QUALITY_MEDIUM: + qsel = MICFIL_QSEL_MEDIUM_QUALITY; + break; + case QUALITY_LOW: + qsel = MICFIL_QSEL_LOW_QUALITY; + break; + case QUALITY_VLOW0: + qsel = MICFIL_QSEL_VLOW0_QUALITY; + break; + case QUALITY_VLOW1: + qsel = MICFIL_QSEL_VLOW1_QUALITY; + break; + case QUALITY_VLOW2: + qsel = MICFIL_QSEL_VLOW2_QUALITY; + break; + default: + dai_err(dai, "MICFIL: invalid quality mode %d", micfil->quality); + return -EINVAL; + } + + dai_update_bits(dai, REG_MICFIL_CTRL2, MICFIL_CTRL2_QSEL, + MICFIL_CTRL2_QSEL_BITS(qsel)); + + return 0; +} + +/* get_pdm_clk - computes the product between k-factor and PDM_CLK rate + * @param dai, SOF DAI struct + * @param rate, output sampling rate + * + * PDM_CLK depends on Quality Mode, output sampling rate and quality + * mode + */ +static unsigned int micfil_get_pdm_clk(struct dai *dai, int rate) +{ + unsigned int osr; + unsigned int qsel; + unsigned int ctrl2_reg; + unsigned int pdm_clk = 0; + + ctrl2_reg = dai_read(dai, REG_MICFIL_CTRL2); + osr = 16 - ((ctrl2_reg & MICFIL_CTRL2_CICOSR) >> MICFIL_CTRL2_CICOSR_SHIFT); + qsel = (ctrl2_reg & MICFIL_CTRL2_QSEL) >> MICFIL_CTRL2_QSEL_SHIFT; + + /* See Quality modes chapter in MICFIL documentation */ + switch (qsel) { + case MICFIL_QSEL_HIGH_QUALITY: + pdm_clk = rate * 8 * osr / 2; /* kfactor = 0.5 */ + break; + case MICFIL_QSEL_MEDIUM_QUALITY: + case MICFIL_QSEL_VLOW0_QUALITY: + pdm_clk = rate * 4 * osr; /* kfactor = 1 */ + break; + case MICFIL_QSEL_LOW_QUALITY: + case MICFIL_QSEL_VLOW1_QUALITY: + pdm_clk = rate * 2 * osr * 2; /* kfactor = 2 */ + break; + case MICFIL_QSEL_VLOW2_QUALITY: + pdm_clk = rate * osr; /* kfactor = 4 */ + break; + default: + break; + } + + return pdm_clk; +} + +static int micfil_get_clk_div(struct dai *dai, int rate) +{ + unsigned int pdm_clk; + + pdm_clk = micfil_get_pdm_clk(dai, rate); + if (!pdm_clk) + return -EINVAL; + + /* + * + * See: Clock divider chapter from micfil documentation + * PDM_CLK rate = MICFIL_CLK_ROOT rate / (2 * K * CLKDIV) + * + * this means that if we want to compute CLKDIV then: + * CLKDIV = MICFIL_CLK_ROOT rate / (PDM_CLK rate * K * 2) + * + * micfil_get_pdm_clk function returns K * PDM_CLK rate + */ + return MICFIL_CLK_ROOT / (pdm_clk * 2); +} + +static int micfil_set_clock_params(struct dai *dai, int rate) +{ + int clk_div; + + dai_update_bits(dai, REG_MICFIL_CTRL2, MICFIL_CTRL2_CICOSR, + MICFIL_CTRL2_CICOSR_BITS(MICFIL_OSR_DEFAULT)); + + clk_div = micfil_get_clk_div(dai, rate); + if (clk_div < 0) + return clk_div; + + dai_update_bits(dai, REG_MICFIL_CTRL2, MICFIL_CTRL2_CLKDIV, + MICFIL_CTRL2_CLKDIV_BITS(clk_div)); + + return 0; +} + +static int micfil_set_config(struct dai *dai, struct ipc_config_dai *common_config, + const void *spec_config) +{ + int i, ret; + unsigned int val = 0; + struct micfil_pdata *micfil = dai_get_drvdata(dai); + const struct sof_ipc_dai_config *config = spec_config; + + micfil->params = config->micfil; + + dai_info(dai, "micfil_set_config() dai_idx %d channels %d sampling_freq %d", + common_config->dai_index, micfil->params.pdm_ch, micfil->params.pdm_rate); + + /* disable the module */ + dai_update_bits(dai, REG_MICFIL_CTRL1, MICFIL_CTRL1_PDMIEN, 0); + + micfil_set_quality(dai); + + /* set default gain to 2 */ + dai_write(dai, REG_MICFIL_OUT_CTRL, MICFIL_DEFAULT_ADJ_RANGE); + + /* set DC Remover in bypass mode */ + for (i = 0; i < MICFIL_OUTPUT_CHANNELS; i++) + val |= MICFIL_DC_BYPASS << MICFIL_DC_CHX_SHIFT(i); + dai_update_bits(dai, REG_MICFIL_DC_CTRL, MICFIL_DC_CTRL_CONFIG, val); + + /* FIFO WMK */ + dai_update_bits(dai, REG_MICFIL_FIFO_CTRL, MICFIL_FIFO_CTRL_FIFOWMK, + MICFIL_FIFO_CTRL_FIFOWMK_BITS(31)); + + /* enable channels */ + dai_update_bits(dai, REG_MICFIL_CTRL1, MICFIL_CTRL1_CHNEN, + ((1 << micfil->params.pdm_ch) - 1)); + + ret = micfil_set_clock_params(dai, micfil->params.pdm_rate); + if (ret < 0) + return ret; + + return 0; +} + +static int micfil_get_handshake(struct dai *dai, int direction, int stream_id) +{ + return dai->plat_data.fifo[SOF_IPC_STREAM_CAPTURE].handshake; +} + +static int micfil_get_fifo(struct dai *dai, int direction, int stream_id) +{ + return dai->plat_data.fifo[SOF_IPC_STREAM_CAPTURE].offset; +} + +static int micfil_get_fifo_depth(struct dai *dai, int direction) +{ + return dai->plat_data.fifo[SOF_IPC_STREAM_CAPTURE].depth; +} + +static void micfil_start(struct dai *dai) +{ + dai_info(dai, "micfil_start()"); + + micfil_reset(dai); + + /* DMA Interrupt Selection - DISEL bits + * 00 - DMA and IRQ disabled + * 01 - DMA req enabled + * 10 - IRQ enabled + * 11 - reserved + */ + dai_update_bits(dai, REG_MICFIL_CTRL1, + MICFIL_CTRL1_DISEL, + MICFIL_CTRL1_DISEL_BITS(MICFIL_CTRL1_DISEL_DMA)); + + /* Enable the module */ + dai_update_bits(dai, REG_MICFIL_CTRL1, MICFIL_CTRL1_PDMIEN, MICFIL_CTRL1_PDMIEN); +} + +static void micfil_stop(struct dai *dai) +{ + dai_info(dai, "micfil_stop()"); + + /* Disable the module */ + dai_update_bits(dai, REG_MICFIL_CTRL1, MICFIL_CTRL1_PDMIEN, 0); + + dai_update_bits(dai, REG_MICFIL_CTRL1, MICFIL_CTRL1_DISEL, + MICFIL_CTRL1_DISEL_BITS(MICFIL_CTRL1_DISEL_DISABLE)); +} + +static int micfil_trigger(struct dai *dai, int cmd, int direction) +{ + dai_info(dai, "micfil_trigger() cmd %d dir %d", cmd, direction); + + switch (cmd) { + case COMP_TRIGGER_START: + case COMP_TRIGGER_RELEASE: + micfil_start(dai); + break; + case COMP_TRIGGER_STOP: + case COMP_TRIGGER_PAUSE: + micfil_stop(dai); + case COMP_TRIGGER_PRE_START: + case COMP_TRIGGER_PRE_RELEASE: + break; + default: + dai_err(dai, "MICFIL: invalid trigger cmd %d", cmd); + return -EINVAL; + } + + return 0; +} + +static int micfil_probe(struct dai *dai) +{ + struct micfil_pdata *micfil; + + dai_info(dai, "micfil_probe()"); + + micfil = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*micfil)); + if (!micfil) { + dai_err(dai, "micfil probe failed"); + return -ENOMEM; + } + + micfil->quality = QUALITY_VLOW0; + + dai_set_drvdata(dai, micfil); + + return 0; +} + +static int micfil_remove(struct dai *dai) +{ + struct micfil_pdata *micfil = dai_get_drvdata(dai); + + dai_info(dai, "micfil_remove()"); + + rfree(micfil); + dai_set_drvdata(dai, NULL); + + return 0; +} + +const struct dai_driver micfil_driver = { + .type = SOF_DAI_IMX_MICFIL, + .uid = SOF_UUID(micfil_uuid), + .tctx = &micfil_tr, + .dma_dev = DMA_DEV_MICFIL, + .ops = { + .trigger = micfil_trigger, + .set_config = micfil_set_config, + .get_hw_params = micfil_get_hw_params, + .get_handshake = micfil_get_handshake, + .get_fifo = micfil_get_fifo, + .get_fifo_depth = micfil_get_fifo_depth, + .probe = micfil_probe, + .remove = micfil_remove, + }, +}; diff --git a/src/drivers/imx/sai.c b/src/drivers/imx/sai.c index df9690eb8d7c..c6e30f791fb2 100644 --- a/src/drivers/imx/sai.c +++ b/src/drivers/imx/sai.c @@ -229,6 +229,7 @@ static inline int sai_set_config(struct dai *dai, struct ipc_config_dai *common_ uint32_t val_cr2 = 0, val_cr4 = 0, val_cr5 = 0; uint32_t mask_cr2 = 0, mask_cr4 = 0, mask_cr5 = 0; uint32_t clk_div; + bool tdm_enable; struct sai_pdata *sai = dai_get_drvdata(dai); sai->config = *config; @@ -251,6 +252,14 @@ static inline int sai_set_config(struct dai *dai, struct ipc_config_dai *common_ clk_div = (config->sai.mclk_rate / config->sai.bclk_rate / 2) - 1; } + /* TDM mode is enabled only when fmt is dsp_a or dsp_b and + * we can have from 1 to 32 channels. + * for any other formats we assume I2S like interface where + * audio frames have 2 channels, even for mono scenario. The + * second channel will be masked out. + */ + tdm_enable = false; + switch (config->format & SOF_DAI_FMT_FORMAT_MASK) { case SOF_DAI_FMT_I2S: /* @@ -285,6 +294,7 @@ static inline int sai_set_config(struct dai *dai, struct ipc_config_dai *common_ val_cr2 |= REG_SAI_CR2_BCP; val_cr4 |= REG_SAI_CR4_FSE; val_cr4 |= REG_SAI_CR4_SYWD(1U); + tdm_enable = true; break; case SOF_DAI_FMT_DSP_B: /* @@ -293,6 +303,7 @@ static inline int sai_set_config(struct dai *dai, struct ipc_config_dai *common_ */ val_cr2 |= REG_SAI_CR2_BCP; val_cr4 |= REG_SAI_CR4_SYWD(1U); + tdm_enable = true; break; case SOF_DAI_FMT_PDM: val_cr2 |= REG_SAI_CR2_BCP; @@ -355,6 +366,7 @@ static inline int sai_set_config(struct dai *dai, struct ipc_config_dai *common_ return -EINVAL; } +#ifndef CONFIG_IMX8ULP switch (sai->params.tdm_slot_width) { case 8: val_cr4 |= REG_SAI_CR4_FPACK_8; @@ -365,8 +377,14 @@ static inline int sai_set_config(struct dai *dai, struct ipc_config_dai *common_ default: break; } +#endif + + if (tdm_enable) + val_cr4 |= REG_SAI_CR4_FRSZ(sai->params.tdm_slots); + else + val_cr4 |= REG_SAI_CR4_FRSZ( + (sai->params.tdm_slots == 1) ? 2 : sai->params.tdm_slots); - val_cr4 |= REG_SAI_CR4_FRSZ(sai->params.tdm_slots); val_cr4 |= REG_SAI_CR4_CHMOD; val_cr4 |= REG_SAI_CR4_MF; diff --git a/src/drivers/imx/sdma.c b/src/drivers/imx/sdma.c index 70d801f97f20..902bb03eb245 100644 --- a/src/drivers/imx/sdma.c +++ b/src/drivers/imx/sdma.c @@ -69,6 +69,9 @@ struct sdma_chan { int next_bd; int sdma_chan_type; int fifo_paddr; + + unsigned int watermark_level; + unsigned int sw_done_sel; /* software done selector */ }; /* Private data for the whole controller */ @@ -438,6 +441,8 @@ static struct dma_chan_data *sdma_channel_get(struct dma *dma, static void sdma_enable_event(struct dma_chan_data *channel, int eventnum) { + struct sdma_chan *pdata = dma_chan_get_data(channel); + tr_dbg(&sdma_tr, "sdma_enable_event(%d, %d)", channel->index, eventnum); if (eventnum < 0 || eventnum > SDMA_HWEVENTS_COUNT) @@ -445,6 +450,13 @@ static void sdma_enable_event(struct dma_chan_data *channel, int eventnum) dma_reg_update_bits(channel->dma, SDMA_CHNENBL(eventnum), BIT(channel->index), BIT(channel->index)); + + if (pdata->sw_done_sel & BIT(31)) { + unsigned int done0; + + done0 = SDMA_DONE0_CONFIG_DONE_SEL | ~SDMA_DONE0_CONFIG_DONE_DIS; + dma_reg_update_bits(channel->dma, SDMA_DONE0_CONFIG, 0xFF, done0); + } } static void sdma_disable_event(struct dma_chan_data *channel, int eventnum) @@ -589,6 +601,7 @@ static int sdma_status(struct dma_chan_data *channel, break; case SDMA_CHAN_TYPE_AP2MCU: case SDMA_CHAN_TYPE_MCU2SHP: + case SDMA_CHAN_TYPE_SAI2MCU: status->r_pos = bd->buf_addr; status->w_pos = pdata->fifo_paddr; /* We cannot see the target address */ @@ -602,11 +615,54 @@ static int sdma_status(struct dma_chan_data *channel, return 0; } +static void sdma_set_watermarklevel(struct dma_chan_data *chan) +{ + struct sdma_chan *pdata = dma_chan_get_data(chan); + + /* TODO: retrieve this information from DAI */ + unsigned int n_fifos = 4; /* number of HW fifos used */ + unsigned int words_per_fifo = 1; /* number of audio channels per frame */ + + /* sw_done_sel mimics software done configuration from Linux + * see Documentation/devicetree/bindings/fsl-imx-sdma.txt + */ + unsigned int sw_done_sel = 0; + + /* sw_done_sel configuration + * - bit31: sw_done + * - bit15:8 selector + * - bit7-0 priority + */ + sw_done_sel |= BIT(31); + + /* watermark level: + * bit0~11: wartermark level(wml*fifo_number) + * bit15~12: to do-fifo number + * bit16~19: fifo offset + * bit27~24: sw done selector + * bit28~31: numbers of audio channels in one frame, 0: 1 channel,1: 2 channels + * bit23: sw done enable + */ + + pdata->watermark_level |= SDMA_WATERMARK_LEVEL_SW_DONE | + (sw_done_sel & 0xff) << SDMA_WATERMARK_LEVEL_SW_DONE_SEL_OFF; + + pdata->watermark_level |= + SDMA_WATERMARK_LEVEL_N_FIFOS(n_fifos); + + pdata->watermark_level |= + SDMA_WATERMARK_LEVEL_WORDS_PER_FIFO(words_per_fifo - 1); + + pdata->sw_done_sel = sw_done_sel; +} + static int sdma_read_config(struct dma_chan_data *channel, struct dma_sg_config *config) { int i; struct sdma_chan *pdata = dma_chan_get_data(channel); + struct dai_data *dd = channel->dev_data; + uint32_t dma_dev = dd->dai->drv->dma_dev; switch (config->direction) { case DMA_DIR_MEM_TO_DEV: @@ -616,7 +672,10 @@ static int sdma_read_config(struct dma_chan_data *channel, break; case DMA_DIR_DEV_TO_MEM: pdata->hw_event = config->src_dev; - pdata->sdma_chan_type = SDMA_CHAN_TYPE_SHP2MCU; + if (dma_dev == DMA_DEV_MICFIL) + pdata->sdma_chan_type = SDMA_CHAN_TYPE_SAI2MCU; + else + pdata->sdma_chan_type = SDMA_CHAN_TYPE_SHP2MCU; pdata->fifo_paddr = config->elem_array.elems[0].src; break; case DMA_DIR_MEM_TO_MEM: @@ -760,6 +819,9 @@ static int sdma_prep_desc(struct dma_chan_data *channel, case SDMA_CHAN_TYPE_SHP2MCU: sdma_script_addr = SDMA_SCRIPT_SHP2MCU_OFF; break; + case SDMA_CHAN_TYPE_SAI2MCU: + sdma_script_addr = SDMA_SCRIPT_SAI2MCU_OFF; + break; default: /* This case doesn't happen; we need to assign the other cases * for AP2MCU and MCU2AP @@ -770,6 +832,13 @@ static int sdma_prep_desc(struct dma_chan_data *channel, watermark = (config->burst_elems * width) / 8; + if (pdata->sdma_chan_type == SDMA_CHAN_TYPE_SAI2MCU) { + sdma_set_watermarklevel(channel); + watermark |= pdata->watermark_level; + } else { + watermark = (config->burst_elems * width) / 8; + } + memset(pdata->ctx, 0, sizeof(*pdata->ctx)); pdata->ctx->pc = sdma_script_addr; diff --git a/src/idc/idc.c b/src/idc/idc.c index 9a630ca6fbf7..860f427a551d 100644 --- a/src/idc/idc.c +++ b/src/idc/idc.c @@ -227,8 +227,8 @@ static int idc_prepare(uint32_t comp_id) dev = ipc_dev->cd; - /* we're running on different core, so allocate our own task */ - if (!dev->task) { + /* we're running LL on different core, so allocate our own task */ + if (!dev->task && dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL) { /* allocate task for shared component */ dev->task = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*dev->task)); diff --git a/src/idc/zephyr_idc.c b/src/idc/zephyr_idc.c index 36b373e1aad8..9c33128349f4 100644 --- a/src/idc/zephyr_idc.c +++ b/src/idc/zephyr_idc.c @@ -63,7 +63,8 @@ static void idc_handler(struct k_p4wq_work *work) int payload = -1; k_spinlock_key_t key; - sys_cache_data_flush_range(msg, sizeof(*msg)); + /* A message is received from another core, invalidate local cache */ + sys_cache_data_invd_range(msg, sizeof(*msg)); if (msg->size == sizeof(int)) { const int idc_handler_memcpy_err __unused = @@ -123,12 +124,14 @@ int idc_send_msg(struct idc_msg *msg, uint32_t mode) msg->payload, msg->size); assert(!idc_send_memcpy_err); + /* Sending a message to another core, write back local payload cache */ sys_cache_data_flush_range(payload->data, MIN(sizeof(payload->data), msg->size)); } /* Temporarily store sender core ID */ msg_cp->core = cpu_get_id(); + /* Sending a message to another core, write back local message cache */ sys_cache_data_flush_range(msg_cp, sizeof(*msg_cp)); k_p4wq_submit(q_zephyr_idc + target_cpu, work); diff --git a/src/include/ipc/dai-imx.h b/src/include/ipc/dai-imx.h index bc478f0c97ad..5f9fc4dce837 100644 --- a/src/include/ipc/dai-imx.h +++ b/src/include/ipc/dai-imx.h @@ -54,4 +54,11 @@ struct sof_ipc_dai_sai_params { uint16_t reserved2; /* alignment */ } __attribute__((packed, aligned(4))); + +/* MICFIL Configuration Request - SOF_IPC_DAI_MICFIL_CONFIG */ +struct sof_ipc_dai_micfil_params { + uint32_t pdm_rate; + uint32_t pdm_ch; +} __attribute__((packed, aligned(4))); + #endif /* __IPC_DAI_IMX_H__ */ diff --git a/src/include/ipc/dai.h b/src/include/ipc/dai.h index b0ea6d7f6af5..37bd91fa6c29 100644 --- a/src/include/ipc/dai.h +++ b/src/include/ipc/dai.h @@ -92,7 +92,8 @@ enum sof_ipc_dai_type { SOF_DAI_MEDIATEK_AFE, /**< Mtk AFE */ SOF_DAI_AMD_HS, /**< Amd HS */ SOF_DAI_AMD_SP_VIRTUAL, /** -#include "base-config.h" - -struct ipc4_aria_module_cfg { - struct ipc4_base_module_cfg base_cfg; - uint32_t attenuation; -} __packed __aligned(8); -#endif diff --git a/src/include/ipc4/base-config.h b/src/include/ipc4/base-config.h index 26eeb07bf355..2e54478efd3a 100644 --- a/src/include/ipc4/base-config.h +++ b/src/include/ipc4/base-config.h @@ -242,7 +242,7 @@ struct sof_ipc_stream_params; void ipc4_base_module_cfg_to_stream_params(const struct ipc4_base_module_cfg *base_cfg, struct sof_ipc_stream_params *params); struct comp_buffer; -void ipc4_update_buffer_format(struct comp_buffer __sparse_cache *buf_c, +void ipc4_update_buffer_format(struct comp_buffer *buf_c, const struct ipc4_audio_format *fmt); #endif diff --git a/src/include/ipc4/base_fw.h b/src/include/ipc4/base_fw.h index bd049fdded8c..3c4a953405e2 100644 --- a/src/include/ipc4/base_fw.h +++ b/src/include/ipc4/base_fw.h @@ -4,15 +4,8 @@ */ /* - * This file contains structures that are exact copies of an existing ABI used - * by IOT middleware. They are Intel specific and will be used by one middleware. - * * Some of the structures may contain programming implementations that makes them * unsuitable for generic use and general usage. - * - * This code is mostly copied "as-is" from existing C++ interface files hence the use of - * different style in places. The intention is to keep the interface as close as possible to - * original so it's easier to track changes with IPC host code. */ /** @@ -21,6 +14,9 @@ * NOTE: This ABI uses bit fields and is non portable. */ +#ifndef __SOF_IPC4_BASE_FW_H__ +#define __SOF_IPC4_BASE_FW_H__ + /* Three clk src states :low power XTAL, low power ring * and high power ring oscillator */ @@ -666,3 +662,5 @@ enum ipc4_power_state_type { IPC4_ACTIVE_CORES_MASK = 0, IPC4_CORE_KCPS = 1, }; + +#endif /* __SOF_IPC4_BASE_FW_H__ */ diff --git a/src/include/ipc4/copier.h b/src/include/ipc4/copier.h index 285b6ca3f4d4..23953d6aca97 100644 --- a/src/include/ipc4/copier.h +++ b/src/include/ipc4/copier.h @@ -272,7 +272,7 @@ struct copier_data { }; int apply_attenuation(struct comp_dev *dev, struct copier_data *cd, - struct comp_buffer __sparse_cache *sink, int frame); + struct comp_buffer *sink, int frame); pcm_converter_func get_converter_func(const struct ipc4_audio_format *in_fmt, const struct ipc4_audio_format *out_fmt, diff --git a/src/include/ipc4/fw_reg.h b/src/include/ipc4/fw_reg.h index 732de50600be..a0f450954050 100644 --- a/src/include/ipc4/fw_reg.h +++ b/src/include/ipc4/fw_reg.h @@ -30,7 +30,7 @@ #include #include #include -#include +#include /* Reports current ROM/FW status. */ struct ipc4_fw_status_reg { diff --git a/src/include/ipc4/header.h b/src/include/ipc4/header.h index 4a91b1a8cb13..5abef50342b0 100644 --- a/src/include/ipc4/header.h +++ b/src/include/ipc4/header.h @@ -171,4 +171,48 @@ struct ipc4_message_reply { } extension; } __attribute((packed, aligned(4))); +#define SOF_IPC4_SWITCH_CONTROL_PARAM_ID 200 +#define SOF_IPC4_ENUM_CONTROL_PARAM_ID 201 +#define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_VAL ((uint32_t)(0xA15A << 16)) + +/** + * struct sof_ipc4_ctrl_value_chan: generic channel mapped value data + * @channel: Channel ID + * @value: control value + */ +struct sof_ipc4_ctrl_value_chan { + uint32_t channel; + uint32_t value; +} __attribute((packed, aligned(4))); + +/** + * struct sof_ipc4_control_msg_payload - IPC payload for kcontrol parameters + * @id: unique id of the control + * @num_elems: Number of elememnts in the chanv array + * @reserved: reserved for future use, must be set to 0 + * @chanv: channel ID and value array + */ +struct sof_ipc4_control_msg_payload { + uint16_t id; + uint16_t num_elems; + uint32_t reserved[4]; + struct sof_ipc4_ctrl_value_chan chanv[]; +} __attribute((packed, aligned(4))); + +/** + * struct sof_ipc4_notify_module_data - payload for module notification + * @instance_id: instance ID of the originator module of the notification + * @module_id: module ID of the originator of the notification + * @event_id: module specific event id + * @event_data_size: Size of the @event_data (if any) in bytes + * @event_data: Optional notification data, module and notification dependent + */ +struct sof_ipc4_notify_module_data { + uint16_t instance_id; + uint16_t module_id; + uint32_t event_id; + uint32_t event_data_size; + uint8_t event_data[]; +} __attribute((packed, aligned(4))); + #endif diff --git a/src/include/ipc4/kpb.h b/src/include/ipc4/kpb.h index ad558bc4ac25..0c56942313c3 100644 --- a/src/include/ipc4/kpb.h +++ b/src/include/ipc4/kpb.h @@ -19,4 +19,16 @@ struct ipc4_kpb_module_cfg { struct ipc4_base_module_cfg base_cfg; } __packed __aligned(4); + +/* For the sake of compatibility, do not change IDs, only add new ones.*/ +enum ipc4_kpb_module_config_params { + /*! Configure the module ID's which would be part of the Fast mode tasks */ + KP_BUF_CFG_FM_MODULE = 1, + /* Mic selector for client - sets microphone id for real time sink mic selector + * IPC4-compatible ID - please do not change the number + */ + KP_BUF_CLIENT_MIC_SELECT = 11, +}; + #endif + diff --git a/src/include/ipc4/logging.h b/src/include/ipc4/logging.h index 55f4a5edbffc..bbb913677231 100644 --- a/src/include/ipc4/logging.h +++ b/src/include/ipc4/logging.h @@ -8,10 +8,20 @@ #define SOF_IPC4_LOGGING_MTRACE_PAGE_SIZE 0x1000 +#if CONFIG_LIBRARY +static inline int ipc4_logging_enable_logs(bool first_block, + bool last_block, + uint32_t data_offset_or_size, + const char *data) +{ + return 0; +} +#else int ipc4_logging_enable_logs(bool first_block, bool last_block, uint32_t data_offset_or_size, const char *data); +#endif int ipc4_logging_shutdown(void); diff --git a/src/include/ipc4/mixin_mixout.h b/src/include/ipc4/mixin_mixout.h index f44ef97e0b37..49184e2aa51b 100644 --- a/src/include/ipc4/mixin_mixout.h +++ b/src/include/ipc4/mixin_mixout.h @@ -105,15 +105,15 @@ struct ipc4_mixer_mode_config { /** * \brief normal mode mixin_mixout processing function interface */ -typedef void (*normal_mix_func)(struct audio_stream __sparse_cache *sink, int32_t start_frame, +typedef void (*normal_mix_func)(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, - const struct audio_stream __sparse_cache *source, + const struct audio_stream *source, int32_t frame_count, uint16_t gain); /** * \brief mixin_mixout mute processing function interface */ -typedef void (*mute_func) (struct audio_stream __sparse_cache *stream, int32_t channel_index, +typedef void (*mute_func) (struct audio_stream *stream, int32_t channel_index, int32_t start_frame, int32_t mixed_frames, int32_t frame_count); /** diff --git a/src/include/ipc4/module.h b/src/include/ipc4/module.h index cf5f60b453bc..86279567cb85 100644 --- a/src/include/ipc4/module.h +++ b/src/include/ipc4/module.h @@ -36,6 +36,9 @@ #define SOF_IPC4_DST_QUEUE_ID_BITFIELD_SIZE 3 #define SOF_IPC4_SRC_QUEUE_ID_BITFIELD_SIZE 3 +/* Special large_param_id values */ +#define VENDOR_CONFIG_PARAM 0xFF + enum sof_ipc4_module_type { SOF_IPC4_MOD_INIT_INSTANCE = 0, SOF_IPC4_MOD_CONFIG_GET = 1, @@ -51,6 +54,18 @@ enum sof_ipc4_module_type { SOF_IPC4_MOD_DELETE_INSTANCE = 11, }; +/* + * Structs for Vendor Config Set + */ + +union ipc4_extended_param_id { + uint32_t full; + struct{ + uint32_t parameter_type : 8; + uint32_t parameter_instance : 24; + } part; +} __packed __aligned(4); + /* * Host Driver sends this message to create a new module instance. */ @@ -408,7 +423,7 @@ struct ipc4_module_load_library { } __packed __aligned(4); #define IPC4_COMP_ID(x, y) ((y) << 16 | (x)) -#define IPC4_MOD_ID(x) ((x) & 0xffff) +#define IPC4_MOD_ID(x) (IS_ENABLED(CONFIG_IPC_MAJOR_4) ? ((x) & 0xffff) : 0) #define IPC4_INST_ID(x) ((x) >> 16) #define IPC4_SRC_QUEUE_ID(x) ((x) & 0xffff) #define IPC4_SINK_QUEUE_ID(x) (((x) >> 16) & 0xffff) diff --git a/src/include/sof/audio/audio_stream.h b/src/include/sof/audio/audio_stream.h index ecfc63432d86..75060b0e1ef3 100644 --- a/src/include/sof/audio/audio_stream.h +++ b/src/include/sof/audio/audio_stream.h @@ -104,148 +104,146 @@ struct audio_stream { struct sof_audio_stream_params runtime_stream_params; }; -static inline void *audio_stream_get_rptr(const struct audio_stream __sparse_cache *buf) +static inline void *audio_stream_get_rptr(const struct audio_stream *buf) { return buf->r_ptr; } -static inline void *audio_stream_get_wptr(const struct audio_stream __sparse_cache *buf) +static inline void *audio_stream_get_wptr(const struct audio_stream *buf) { return buf->w_ptr; } -static inline void *audio_stream_get_end_addr(const struct audio_stream __sparse_cache *buf) +static inline void *audio_stream_get_end_addr(const struct audio_stream *buf) { return buf->end_addr; } -static inline void *audio_stream_get_addr(const struct audio_stream __sparse_cache *buf) +static inline void *audio_stream_get_addr(const struct audio_stream *buf) { return buf->addr; } -static inline uint32_t audio_stream_get_size(const struct audio_stream __sparse_cache *buf) +static inline uint32_t audio_stream_get_size(const struct audio_stream *buf) { return buf->size; } -static inline uint32_t audio_stream_get_avail(const struct audio_stream __sparse_cache *buf) +static inline uint32_t audio_stream_get_avail(const struct audio_stream *buf) { return buf->avail; } -static inline uint32_t audio_stream_get_free(const struct audio_stream __sparse_cache *buf) +static inline uint32_t audio_stream_get_free(const struct audio_stream *buf) { return buf->free; } -static inline enum sof_ipc_frame audio_stream_get_frm_fmt( - const struct audio_stream __sparse_cache *buf) +static inline enum sof_ipc_frame audio_stream_get_frm_fmt(const struct audio_stream *buf) { return buf->runtime_stream_params.frame_fmt; } -static inline enum sof_ipc_frame audio_stream_get_valid_fmt( - const struct audio_stream __sparse_cache *buf) +static inline enum sof_ipc_frame audio_stream_get_valid_fmt(const struct audio_stream *buf) { return buf->runtime_stream_params.valid_sample_fmt; } -static inline uint32_t audio_stream_get_rate(const struct audio_stream __sparse_cache *buf) +static inline uint32_t audio_stream_get_rate(const struct audio_stream *buf) { return buf->runtime_stream_params.rate; } -static inline uint32_t audio_stream_get_channels(const struct audio_stream __sparse_cache *buf) +static inline uint32_t audio_stream_get_channels(const struct audio_stream *buf) { return buf->runtime_stream_params.channels; } -static inline bool audio_stream_get_underrun(const struct audio_stream __sparse_cache *buf) +static inline bool audio_stream_get_underrun(const struct audio_stream *buf) { return buf->runtime_stream_params.underrun_permitted; } -static inline uint32_t audio_stream_get_buffer_fmt(const struct audio_stream __sparse_cache *buf) +static inline uint32_t audio_stream_get_buffer_fmt(const struct audio_stream *buf) { return buf->runtime_stream_params.buffer_fmt; } -static inline bool audio_stream_get_overrun(const struct audio_stream __sparse_cache *buf) +static inline bool audio_stream_get_overrun(const struct audio_stream *buf) { return buf->runtime_stream_params.overrun_permitted; } -static inline void audio_stream_set_rptr(struct audio_stream __sparse_cache *buf, void *val) +static inline void audio_stream_set_rptr(struct audio_stream *buf, void *val) { buf->r_ptr = val; } -static inline void audio_stream_set_wptr(struct audio_stream __sparse_cache *buf, void *val) +static inline void audio_stream_set_wptr(struct audio_stream *buf, void *val) { buf->w_ptr = val; } -static inline void audio_stream_set_end_addr(struct audio_stream __sparse_cache *buf, void *val) +static inline void audio_stream_set_end_addr(struct audio_stream *buf, void *val) { buf->end_addr = val; } -static inline void audio_stream_set_addr(struct audio_stream __sparse_cache *buf, void *val) +static inline void audio_stream_set_addr(struct audio_stream *buf, void *val) { buf->addr = val; } -static inline void audio_stream_set_size(struct audio_stream __sparse_cache *buf, uint32_t val) +static inline void audio_stream_set_size(struct audio_stream *buf, uint32_t val) { buf->size = val; } -static inline void audio_stream_set_avail(struct audio_stream __sparse_cache *buf, uint32_t val) +static inline void audio_stream_set_avail(struct audio_stream *buf, uint32_t val) { buf->avail = val; } -static inline void audio_stream_set_free(struct audio_stream __sparse_cache *buf, uint32_t val) +static inline void audio_stream_set_free(struct audio_stream *buf, uint32_t val) { buf->free = val; } -static inline void audio_stream_set_frm_fmt(struct audio_stream __sparse_cache *buf, +static inline void audio_stream_set_frm_fmt(struct audio_stream *buf, enum sof_ipc_frame val) { buf->runtime_stream_params.frame_fmt = val; } -static inline void audio_stream_set_valid_fmt(struct audio_stream __sparse_cache *buf, +static inline void audio_stream_set_valid_fmt(struct audio_stream *buf, enum sof_ipc_frame val) { buf->runtime_stream_params.valid_sample_fmt = val; } -static inline void audio_stream_set_rate(struct audio_stream __sparse_cache *buf, uint32_t val) +static inline void audio_stream_set_rate(struct audio_stream *buf, uint32_t val) { buf->runtime_stream_params.rate = val; } -static inline void audio_stream_set_channels(struct audio_stream __sparse_cache *buf, uint16_t val) +static inline void audio_stream_set_channels(struct audio_stream *buf, uint16_t val) { buf->runtime_stream_params.channels = val; } -static inline void audio_stream_set_underrun(struct audio_stream __sparse_cache *buf, +static inline void audio_stream_set_underrun(struct audio_stream *buf, bool underrun_permitted) { buf->runtime_stream_params.underrun_permitted = underrun_permitted; } -static inline void audio_stream_set_overrun(struct audio_stream __sparse_cache *buf, +static inline void audio_stream_set_overrun(struct audio_stream *buf, bool overrun_permitted) { buf->runtime_stream_params.overrun_permitted = overrun_permitted; } -static inline void audio_stream_set_buffer_fmt(struct audio_stream __sparse_cache *buf, +static inline void audio_stream_set_buffer_fmt(struct audio_stream *buf, uint32_t buffer_fmt) { buf->runtime_stream_params.buffer_fmt = buffer_fmt; @@ -350,31 +348,12 @@ static inline void audio_stream_set_buffer_fmt(struct audio_stream __sparse_cach #define audio_stream_get_frag(buffer, ptr, idx, sample_size) \ audio_stream_wrap(buffer, (char *)(ptr) + ((idx) * (sample_size))) -/** - * Applies parameters to the buffer. - * @param buffer Buffer. - * @param params Parameters (frame format, rate, number of channels). - * @return 0 if succeeded, error code otherwise. - */ -static inline int audio_stream_set_params(struct audio_stream __sparse_cache *buffer, - struct sof_ipc_stream_params *params) -{ - if (!params) - return -EINVAL; - - buffer->runtime_stream_params.frame_fmt = params->frame_fmt; - buffer->runtime_stream_params.rate = params->rate; - buffer->runtime_stream_params.channels = params->channels; - - return 0; -} - /** * Calculates period size in bytes based on component stream's parameters. * @param buf Component buffer. * @return Period size in bytes. */ -static inline uint32_t audio_stream_frame_bytes(const struct audio_stream __sparse_cache *buf) +static inline uint32_t audio_stream_frame_bytes(const struct audio_stream *buf) { return get_frame_bytes(buf->runtime_stream_params.frame_fmt, buf->runtime_stream_params.channels); @@ -385,7 +364,7 @@ static inline uint32_t audio_stream_frame_bytes(const struct audio_stream __spar * @param buf Component buffer. * @return Size of sample in bytes. */ -static inline uint32_t audio_stream_sample_bytes(const struct audio_stream __sparse_cache *buf) +static inline uint32_t audio_stream_sample_bytes(const struct audio_stream *buf) { return get_sample_bytes(buf->runtime_stream_params.frame_fmt); } @@ -423,7 +402,7 @@ static inline uint32_t audio_stream_frame_align_get(const uint32_t byte_align, */ static inline void audio_stream_init_alignment_constants(const uint32_t byte_align, const uint32_t frame_align_req, - struct audio_stream __sparse_cache *stream) + struct audio_stream *stream) { uint32_t process_size; uint32_t frame_size = audio_stream_frame_bytes(stream); @@ -435,14 +414,38 @@ static inline void audio_stream_init_alignment_constants(const uint32_t byte_ali (is_power_of_2(process_size) ? 31 : 32) - clz(process_size); } +/** + * Applies parameters to the buffer. + * @param buffer Audio stream buffer. + * @param params Parameters (frame format, rate, number of channels). + * @return 0 if succeeded, error code otherwise. + */ +static inline int audio_stream_set_params(struct audio_stream *buffer, + struct sof_ipc_stream_params *params) +{ + if (!params) + return -EINVAL; + + buffer->runtime_stream_params.frame_fmt = params->frame_fmt; + buffer->runtime_stream_params.rate = params->rate; + buffer->runtime_stream_params.channels = params->channels; + + /* set the default alignment info. + * set byte_align as 1 means no alignment limit on byte. + * set frame_align as 1 means no alignment limit on frame. + */ + audio_stream_init_alignment_constants(1, 1, buffer); + + return 0; +} + /** * Calculates period size in bytes based on component stream's parameters. * @param buf Component buffer. * @param frames Number of processing frames. * @return Period size in bytes. */ -static inline uint32_t audio_stream_period_bytes(const struct audio_stream __sparse_cache *buf, - uint32_t frames) +static inline uint32_t audio_stream_period_bytes(const struct audio_stream *buf, uint32_t frames) { return frames * audio_stream_frame_bytes(buf); } @@ -454,8 +457,7 @@ static inline uint32_t audio_stream_period_bytes(const struct audio_stream __spa * @param ptr Pointer * @return Pointer, adjusted if necessary. */ -static inline void *audio_stream_wrap(const struct audio_stream __sparse_cache *buffer, - void *ptr) +static inline void *audio_stream_wrap(const struct audio_stream *buffer, void *ptr) { if (ptr >= buffer->end_addr) ptr = (char *)buffer->addr + @@ -492,8 +494,7 @@ static inline void *cir_buf_wrap(void *ptr, void *buf_addr, void *buf_end) * @param ptr Pointer * @return Pointer, adjusted if necessary. */ -static inline void *audio_stream_rewind_wrap(const struct audio_stream __sparse_cache *buffer, - void *ptr) +static inline void *audio_stream_rewind_wrap(const struct audio_stream *buffer, void *ptr) { if (ptr < buffer->addr) ptr = (char *)buffer->end_addr - ((char *)buffer->addr - (char *)ptr); @@ -509,7 +510,7 @@ static inline void *audio_stream_rewind_wrap(const struct audio_stream __sparse_ * @return amount of data available for processing in bytes */ static inline uint32_t -audio_stream_get_avail_bytes(const struct audio_stream __sparse_cache *stream) +audio_stream_get_avail_bytes(const struct audio_stream *stream) { /* * In case of underrun-permitted stream, report buffer full instead of @@ -529,7 +530,7 @@ audio_stream_get_avail_bytes(const struct audio_stream __sparse_cache *stream) * @return amount of data available for processing in samples */ static inline uint32_t -audio_stream_get_avail_samples(const struct audio_stream __sparse_cache *stream) +audio_stream_get_avail_samples(const struct audio_stream *stream) { return audio_stream_get_avail_bytes(stream) / audio_stream_sample_bytes(stream); @@ -541,7 +542,7 @@ audio_stream_get_avail_samples(const struct audio_stream __sparse_cache *stream) * @return amount of data available for processing in frames */ static inline uint32_t -audio_stream_get_avail_frames(const struct audio_stream __sparse_cache *stream) +audio_stream_get_avail_frames(const struct audio_stream *stream) { return audio_stream_get_avail_bytes(stream) / audio_stream_frame_bytes(stream); @@ -553,7 +554,7 @@ audio_stream_get_avail_frames(const struct audio_stream __sparse_cache *stream) * @return amount of space free in bytes */ static inline uint32_t -audio_stream_get_free_bytes(const struct audio_stream __sparse_cache *stream) +audio_stream_get_free_bytes(const struct audio_stream *stream) { /* * In case of overrun-permitted stream, report buffer empty instead of @@ -573,7 +574,7 @@ audio_stream_get_free_bytes(const struct audio_stream __sparse_cache *stream) * @return amount of space free in samples */ static inline uint32_t -audio_stream_get_free_samples(const struct audio_stream __sparse_cache *stream) +audio_stream_get_free_samples(const struct audio_stream *stream) { return audio_stream_get_free_bytes(stream) / audio_stream_sample_bytes(stream); @@ -585,7 +586,7 @@ audio_stream_get_free_samples(const struct audio_stream __sparse_cache *stream) * @return amount of space free in frames */ static inline uint32_t -audio_stream_get_free_frames(const struct audio_stream __sparse_cache *stream) +audio_stream_get_free_frames(const struct audio_stream *stream) { return audio_stream_get_free_bytes(stream) / audio_stream_frame_bytes(stream); @@ -601,8 +602,8 @@ audio_stream_get_free_frames(const struct audio_stream __sparse_cache *stream) * @return 1 if there is not enough free space in sink. * @return -1 if there is not enough data in source. */ -static inline int audio_stream_can_copy_bytes(const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, +static inline int audio_stream_can_copy_bytes(const struct audio_stream *source, + const struct audio_stream *sink, uint32_t bytes) { /* check for underrun */ @@ -626,8 +627,8 @@ static inline int audio_stream_can_copy_bytes(const struct audio_stream __sparse * @return Number of bytes. */ static inline uint32_t -audio_stream_get_copy_bytes(const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink) +audio_stream_get_copy_bytes(const struct audio_stream *source, + const struct audio_stream *sink) { uint32_t avail = audio_stream_get_avail_bytes(source); uint32_t free = audio_stream_get_free_bytes(sink); @@ -647,8 +648,8 @@ audio_stream_get_copy_bytes(const struct audio_stream __sparse_cache *source, * @return Number of frames. */ static inline uint32_t -audio_stream_avail_frames(const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink) +audio_stream_avail_frames(const struct audio_stream *source, + const struct audio_stream *sink) { uint32_t src_frames = audio_stream_get_avail_frames(source); uint32_t sink_frames = audio_stream_get_free_frames(sink); @@ -665,8 +666,8 @@ audio_stream_avail_frames(const struct audio_stream __sparse_cache *source, * @return Number of frames. */ static inline uint32_t -audio_stream_avail_frames_aligned(const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink) +audio_stream_avail_frames_aligned(const struct audio_stream *source, + const struct audio_stream *sink) { uint32_t src_frames = (audio_stream_get_avail_bytes(source) >> source->runtime_stream_params.align_shift_idx) * @@ -683,8 +684,7 @@ audio_stream_avail_frames_aligned(const struct audio_stream __sparse_cache *sour * @param buffer Buffer to update. * @param bytes Number of written bytes. */ -static inline void audio_stream_produce(struct audio_stream __sparse_cache *buffer, - uint32_t bytes) +static inline void audio_stream_produce(struct audio_stream *buffer, uint32_t bytes) { buffer->w_ptr = audio_stream_wrap(buffer, (char *)buffer->w_ptr + bytes); @@ -711,8 +711,7 @@ static inline void audio_stream_produce(struct audio_stream __sparse_cache *buff * @param buffer Buffer to update. * @param bytes Number of read bytes. */ -static inline void audio_stream_consume(struct audio_stream __sparse_cache *buffer, - uint32_t bytes) +static inline void audio_stream_consume(struct audio_stream *buffer, uint32_t bytes) { buffer->r_ptr = audio_stream_wrap(buffer, (char *)buffer->r_ptr + bytes); @@ -734,7 +733,7 @@ static inline void audio_stream_consume(struct audio_stream __sparse_cache *buff * Resets the buffer. * @param buffer Buffer to reset. */ -static inline void audio_stream_reset(struct audio_stream __sparse_cache *buffer) +static inline void audio_stream_reset(struct audio_stream *buffer) { /* reset read and write pointer to buffer bas */ buffer->w_ptr = buffer->addr; @@ -753,8 +752,7 @@ static inline void audio_stream_reset(struct audio_stream __sparse_cache *buffer * @param buff_addr Address of the memory block to assign. * @param size Size of the memory block in bytes. */ -void audio_stream_init(struct audio_stream __sparse_cache *audio_stream, - void *buff_addr, uint32_t size); +void audio_stream_init(struct audio_stream *audio_stream, void *buff_addr, uint32_t size); /** * Invalidates (in DSP d-cache) the buffer in range [r_ptr, r_ptr+bytes], @@ -762,8 +760,7 @@ void audio_stream_init(struct audio_stream __sparse_cache *audio_stream, * @param buffer Buffer. * @param bytes Size of the fragment to invalidate. */ -static inline void audio_stream_invalidate(struct audio_stream __sparse_cache *buffer, - uint32_t bytes) +static inline void audio_stream_invalidate(struct audio_stream *buffer, uint32_t bytes) { uint32_t head_size = bytes; uint32_t tail_size = 0; @@ -786,8 +783,7 @@ static inline void audio_stream_invalidate(struct audio_stream __sparse_cache *b * @param buffer Buffer. * @param bytes Size of the fragment to write back. */ -static inline void audio_stream_writeback(struct audio_stream __sparse_cache *buffer, - uint32_t bytes) +static inline void audio_stream_writeback(struct audio_stream *buffer, uint32_t bytes) { uint32_t head_size = bytes; uint32_t tail_size = 0; @@ -811,8 +807,7 @@ static inline void audio_stream_writeback(struct audio_stream __sparse_cache *bu * @return Number of data samples to buffer wrap. */ static inline int -audio_stream_bytes_without_wrap(const struct audio_stream __sparse_cache *source, - const void *ptr) +audio_stream_bytes_without_wrap(const struct audio_stream *source, const void *ptr) { assert((intptr_t)source->end_addr >= (intptr_t)ptr); return (intptr_t)source->end_addr - (intptr_t)ptr; @@ -827,8 +822,7 @@ audio_stream_bytes_without_wrap(const struct audio_stream __sparse_cache *source * need to add size of sample to returned bytes count. */ static inline int -audio_stream_rewind_bytes_without_wrap(const struct audio_stream __sparse_cache *source, - const void *ptr) +audio_stream_rewind_bytes_without_wrap(const struct audio_stream *source, const void *ptr) { assert((intptr_t)ptr >= (intptr_t)source->addr); int to_begin = (intptr_t)ptr - (intptr_t)source->addr; @@ -843,8 +837,7 @@ audio_stream_rewind_bytes_without_wrap(const struct audio_stream __sparse_cache * @return Previous position of the write pointer. */ static inline uint32_t -*audio_stream_rewind_wptr_by_bytes(const struct audio_stream __sparse_cache *source, - const uint32_t bytes) +*audio_stream_rewind_wptr_by_bytes(const struct audio_stream *source, const uint32_t bytes) { void *wptr = audio_stream_get_wptr(source); int to_begin = audio_stream_rewind_bytes_without_wrap(source, wptr); @@ -866,8 +859,7 @@ static inline uint32_t * @return Number of data s16 samples until circular wrap need at end */ static inline int -audio_stream_samples_without_wrap_s16(const struct audio_stream __sparse_cache *source, - const void *ptr) +audio_stream_samples_without_wrap_s16(const struct audio_stream *source, const void *ptr) { int to_end = (int16_t *)source->end_addr - (int16_t *)ptr; @@ -883,8 +875,7 @@ audio_stream_samples_without_wrap_s16(const struct audio_stream __sparse_cache * * @return Number of data s24 samples until circular wrap need at end */ static inline int -audio_stream_samples_without_wrap_s24(const struct audio_stream __sparse_cache *source, - const void *ptr) +audio_stream_samples_without_wrap_s24(const struct audio_stream *source, const void *ptr) { int to_end = (int32_t *)source->end_addr - (int32_t *)ptr; @@ -900,8 +891,7 @@ audio_stream_samples_without_wrap_s24(const struct audio_stream __sparse_cache * * @return Number of data s32 samples until circular wrap need at end */ static inline int -audio_stream_samples_without_wrap_s32(const struct audio_stream __sparse_cache *source, - const void *ptr) +audio_stream_samples_without_wrap_s32(const struct audio_stream *source, const void *ptr) { int to_end = (int32_t *)source->end_addr - (int32_t *)ptr; @@ -947,8 +937,7 @@ static inline int cir_buf_samples_without_wrap_s32(void *ptr, void *buf_end) * @return Number of data frames to buffer wrap. */ static inline uint32_t -audio_stream_frames_without_wrap(const struct audio_stream __sparse_cache *source, - const void *ptr) +audio_stream_frames_without_wrap(const struct audio_stream *source, const void *ptr) { uint32_t bytes = audio_stream_bytes_without_wrap(source, ptr); uint32_t frame_bytes = audio_stream_frame_bytes(source); @@ -965,8 +954,8 @@ audio_stream_frames_without_wrap(const struct audio_stream __sparse_cache *sourc * @param samples Number of samples to copy. * @return number of processed samples. */ -int audio_stream_copy(const struct audio_stream __sparse_cache *source, uint32_t ioffset, - struct audio_stream __sparse_cache *sink, uint32_t ooffset, uint32_t samples); +int audio_stream_copy(const struct audio_stream *source, uint32_t ioffset, + struct audio_stream *sink, uint32_t ooffset, uint32_t samples); /** * Copies data from one circular buffer to another circular buffer. @@ -990,7 +979,7 @@ void cir_buf_copy(void *src, void *src_addr, void *src_end, void *dst, * @param samples Number of samples to copy. */ void audio_stream_copy_from_linear(const void *linear_source, int ioffset, - struct audio_stream __sparse_cache *sink, int ooffset, + struct audio_stream *sink, int ooffset, unsigned int samples); /** @@ -1001,7 +990,7 @@ void audio_stream_copy_from_linear(const void *linear_source, int ioffset, * @param ooffset Offset (in samples) in sink buffer to start writing to. * @param samples Number of samples to copy. */ -void audio_stream_copy_to_linear(const struct audio_stream __sparse_cache *source, int ioffset, +void audio_stream_copy_to_linear(const struct audio_stream *source, int ioffset, void *linear_sink, int ooffset, unsigned int samples); /** @@ -1011,8 +1000,7 @@ void audio_stream_copy_to_linear(const struct audio_stream __sparse_cache *sourc * @return 0 if there is enough free space in buffer. * @return 1 if there is not enough free space in buffer. */ -static inline int audio_stream_set_zero(struct audio_stream __sparse_cache *buffer, - uint32_t bytes) +static inline int audio_stream_set_zero(struct audio_stream *buffer, uint32_t bytes) { uint32_t head_size = bytes; uint32_t tail_size = 0; @@ -1071,16 +1059,15 @@ static inline void audio_stream_fmt_conversion(enum ipc4_bit_depth depth, } /** get a handler to source API - * NOTE! to use the handlers the buffer must be acquired by buffer_acquire */ -static inline struct sof_source __sparse_cache * -audio_stream_get_source(struct audio_stream __sparse_cache *audio_stream) +static inline struct sof_source * +audio_stream_get_source(struct audio_stream *audio_stream) { return &audio_stream->source_api; } -static inline struct sof_sink __sparse_cache * -audio_stream_get_sink(struct audio_stream __sparse_cache *audio_stream) +static inline struct sof_sink * +audio_stream_get_sink(struct audio_stream *audio_stream) { return &audio_stream->sink_api; } diff --git a/src/include/sof/audio/buffer.h b/src/include/sof/audio/buffer.h index 2eeef2d9f80a..568a121db575 100644 --- a/src/include/sof/audio/buffer.h +++ b/src/include/sof/audio/buffer.h @@ -133,9 +133,9 @@ extern struct tr_ctx buffer_tr; * 5) write back cached data and release lock using uncache pointer. */ struct comp_buffer { - struct coherent c; - /* data buffer */ + CORE_CHECK_STRUCT_FIELD; + struct audio_stream stream; /* configuration */ @@ -144,6 +144,7 @@ struct comp_buffer { uint32_t caps; uint32_t core; struct tr_ctx tctx; /* trace settings */ + bool is_shared; /* buffer structure is shared between 2 cores */ /* connected components */ struct comp_dev *source; /* source component */ @@ -162,7 +163,7 @@ struct comp_buffer { /* Only to be used for synchronous same-core notifications! */ struct buffer_cb_transact { - struct comp_buffer __sparse_cache *buffer; + struct comp_buffer *buffer; uint32_t transaction_amount; void *transaction_begin_address; }; @@ -188,54 +189,37 @@ struct buffer_cb_free { } while (0) /* pipeline buffer creation and destruction */ -struct comp_buffer *buffer_alloc(uint32_t size, uint32_t caps, uint32_t flags, uint32_t align); -struct comp_buffer *buffer_new(const struct sof_ipc_buffer *desc); -int buffer_set_size(struct comp_buffer __sparse_cache *buffer, uint32_t size, uint32_t alignment); +struct comp_buffer *buffer_alloc(uint32_t size, uint32_t caps, uint32_t flags, uint32_t align, + bool is_shared); +struct comp_buffer *buffer_new(const struct sof_ipc_buffer *desc, bool is_shared); +int buffer_set_size(struct comp_buffer *buffer, uint32_t size, uint32_t alignment); void buffer_free(struct comp_buffer *buffer); -void buffer_zero(struct comp_buffer __sparse_cache *buffer); +void buffer_zero(struct comp_buffer *buffer); /* called by a component after producing data into this buffer */ -void comp_update_buffer_produce(struct comp_buffer __sparse_cache *buffer, uint32_t bytes); +void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes); /* called by a component after consuming data from this buffer */ -void comp_update_buffer_consume(struct comp_buffer __sparse_cache *buffer, uint32_t bytes); +void comp_update_buffer_consume(struct comp_buffer *buffer, uint32_t bytes); -int buffer_set_params(struct comp_buffer __sparse_cache *buffer, +int buffer_set_params(struct comp_buffer *buffer, struct sof_ipc_stream_params *params, bool force_update); -bool buffer_params_match(struct comp_buffer __sparse_cache *buffer, +bool buffer_params_match(struct comp_buffer *buffer, struct sof_ipc_stream_params *params, uint32_t flag); -static inline void buffer_stream_invalidate(struct comp_buffer __sparse_cache *buffer, - uint32_t bytes) +static inline void buffer_stream_invalidate(struct comp_buffer *buffer, uint32_t bytes) { - if (!is_coherent_shared(buffer, c)) - return; - - audio_stream_invalidate(&buffer->stream, bytes); + if (buffer->is_shared) + audio_stream_invalidate(&buffer->stream, bytes); } -static inline void buffer_stream_writeback(struct comp_buffer __sparse_cache *buffer, - uint32_t bytes) +static inline void buffer_stream_writeback(struct comp_buffer *buffer, uint32_t bytes) { - if (!is_coherent_shared(buffer, c)) - return; - - audio_stream_writeback(&buffer->stream, bytes); + if (buffer->is_shared) + audio_stream_writeback(&buffer->stream, bytes); } -__must_check static inline struct comp_buffer __sparse_cache *buffer_acquire( - struct comp_buffer *buffer) -{ - struct coherent __sparse_cache *c = coherent_acquire_thread(&buffer->c, sizeof(*buffer)); - - return attr_container_of(c, struct comp_buffer __sparse_cache, c, __sparse_cache); -} - -static inline void buffer_release(struct comp_buffer __sparse_cache *buffer) -{ - coherent_release_thread(&buffer->c, sizeof(*buffer)); -} /* * Attach a new buffer at the beginning of the list. Note, that "head" must @@ -255,14 +239,11 @@ void buffer_detach(struct comp_buffer *buffer, struct list_item *head, int dir); static inline struct comp_dev *buffer_get_comp(struct comp_buffer *buffer, int dir) { - struct comp_buffer __sparse_cache *buffer_c = buffer_acquire(buffer); - struct comp_dev *comp = dir == PPL_DIR_DOWNSTREAM ? buffer_c->sink : - buffer_c->source; - buffer_release(buffer_c); + struct comp_dev *comp = dir == PPL_DIR_DOWNSTREAM ? buffer->sink : buffer->source; return comp; } -static inline void buffer_reset_pos(struct comp_buffer __sparse_cache *buffer, void *data) +static inline void buffer_reset_pos(struct comp_buffer *buffer, void *data) { /* reset rw pointers and avail/free bytes counters */ audio_stream_reset(&buffer->stream); @@ -272,7 +253,7 @@ static inline void buffer_reset_pos(struct comp_buffer __sparse_cache *buffer, v } /* Run-time buffer re-configuration calls this too, so it must use cached access */ -static inline void buffer_init(struct comp_buffer __sparse_cache *buffer, +static inline void buffer_init(struct comp_buffer *buffer, uint32_t size, uint32_t caps) { buffer->caps = caps; @@ -281,7 +262,7 @@ static inline void buffer_init(struct comp_buffer __sparse_cache *buffer, audio_stream_init(&buffer->stream, buffer->stream.addr, size); } -static inline void buffer_reset_params(struct comp_buffer __sparse_cache *buffer, void *data) +static inline void buffer_reset_params(struct comp_buffer *buffer, void *data) { buffer->hw_params_configured = false; } diff --git a/src/include/sof/audio/component.h b/src/include/sof/audio/component.h index f860cdcb3d90..148a45995abc 100644 --- a/src/include/sof/audio/component.h +++ b/src/include/sof/audio/component.h @@ -48,6 +48,7 @@ struct comp_dev; struct sof_ipc_stream_posn; struct dai_hw_params; struct timestamp_data; +struct dai_ts_data; /** \addtogroup component_api Component API * @{ @@ -455,8 +456,12 @@ struct comp_ops { * * Mandatory for components that allocate DAI. */ +#if CONFIG_ZEPHYR_NATIVE_DRIVERS + int (*dai_ts_get)(struct comp_dev *dev, struct dai_ts_data *tsd); +#else int (*dai_ts_get)(struct comp_dev *dev, struct timestamp_data *tsd); +#endif /** * Bind, atomic - used to notify component of bind event. @@ -576,7 +581,12 @@ struct comp_dev { * 2) for all DP tasks */ uint32_t size; /**< component's allocated size */ - uint32_t period; /**< component's processing period */ + uint32_t period; /**< component's processing period + * for LL modules is set to LL pipeline's period + * for DP module its meaning is "the time the module MUST + * provide data that allows the following module to perform + * without glitches" + */ uint32_t priority; /**< component's processing priority */ bool is_shared; /**< indicates whether component is shared * across cores @@ -664,9 +674,7 @@ static inline struct comp_dev *comp_alloc(const struct comp_driver *drv, /* * Use uncached address everywhere to access components to rule out - * multi-core failures. In the future we might decide to switch over to - * the latest coherence API for performance. In that case components - * will be acquired for cached access and released afterwards. + * multi-core failures. TODO: verify if cached alias may be used in some cases */ dev = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, bytes); if (!dev) @@ -712,6 +720,7 @@ void sys_comp_module_demux_interface_init(void); void sys_comp_module_drc_interface_init(void); void sys_comp_module_eq_fir_interface_init(void); void sys_comp_module_eq_iir_interface_init(void); +void sys_comp_module_google_rtc_audio_processing_interface_init(void); void sys_comp_module_mfcc_interface_init(void); void sys_comp_module_mixer_interface_init(void); void sys_comp_module_multiband_drc_interface_init(void); @@ -817,7 +826,7 @@ static inline void component_set_nearest_period_frames(struct comp_dev *current, * @param copy_bytes Requested size of data to be available. */ static inline void comp_underrun(struct comp_dev *dev, - struct comp_buffer __sparse_cache *source, + struct comp_buffer *source, uint32_t copy_bytes) { LOG_MODULE_DECLARE(component, CONFIG_SOF_LOG_LEVEL); @@ -839,7 +848,7 @@ static inline void comp_underrun(struct comp_dev *dev, * @param sink Sink buffer. * @param copy_bytes Requested size of free space to be available. */ -static inline void comp_overrun(struct comp_dev *dev, struct comp_buffer __sparse_cache *sink, +static inline void comp_overrun(struct comp_dev *dev, struct comp_buffer *sink, uint32_t copy_bytes) { LOG_MODULE_DECLARE(component, CONFIG_SOF_LOG_LEVEL); @@ -864,8 +873,8 @@ static inline void comp_overrun(struct comp_dev *dev, struct comp_buffer __spars * @param[in] sink Sink buffer. * @param[out] cl Current copy limits. */ -void comp_get_copy_limits(struct comp_buffer __sparse_cache *source, - struct comp_buffer __sparse_cache *sink, +void comp_get_copy_limits(struct comp_buffer *source, + struct comp_buffer *sink, struct comp_copy_limits *cl); /** @@ -877,59 +886,10 @@ void comp_get_copy_limits(struct comp_buffer __sparse_cache *source, * @param[in] sink Buffer of sink. * @param[out] cl Current copy limits. */ -void comp_get_copy_limits_frame_aligned(const struct comp_buffer __sparse_cache *source, - const struct comp_buffer __sparse_cache *sink, +void comp_get_copy_limits_frame_aligned(const struct comp_buffer *source, + const struct comp_buffer *sink, struct comp_copy_limits *cl); -/** - * Version of comp_get_copy_limits that locks both buffers to guarantee - * consistent state readings. - * - * @param[in] source Source buffer. - * @param[in] sink Sink buffer - * @param[out] cl Current copy limits. - */ -static inline -void comp_get_copy_limits_with_lock(struct comp_buffer *source, - struct comp_buffer *sink, - struct comp_copy_limits *cl) -{ - struct comp_buffer __sparse_cache *source_c, *sink_c; - - source_c = buffer_acquire(source); - sink_c = buffer_acquire(sink); - - comp_get_copy_limits(source_c, sink_c, cl); - - buffer_release(sink_c); - buffer_release(source_c); -} - -/** - * Version of comp_get_copy_limits_with_lock_frame_aligned that locks both - * buffers to guarantee consistent state readings and the frames aligned with - * the requirement. - * - * @param[in] source Buffer of source. - * @param[in] sink Buffer of sink - * @param[out] cl Current copy limits. - */ -static inline -void comp_get_copy_limits_with_lock_frame_aligned(struct comp_buffer *source, - struct comp_buffer *sink, - struct comp_copy_limits *cl) -{ - struct comp_buffer __sparse_cache *source_c, *sink_c; - - source_c = buffer_acquire(source); - sink_c = buffer_acquire(sink); - - comp_get_copy_limits_frame_aligned(source_c, sink_c, cl); - - buffer_release(sink_c); - buffer_release(source_c); -} - /** * Get component state. * diff --git a/src/include/sof/audio/component_ext.h b/src/include/sof/audio/component_ext.h index 4aa65bf61fcd..2c51943413c3 100644 --- a/src/include/sof/audio/component_ext.h +++ b/src/include/sof/audio/component_ext.h @@ -55,6 +55,7 @@ static inline void comp_free(struct comp_dev *dev) dev->task) { schedule_task_free(dev->task); rfree(dev->task); + dev->task = NULL; } dev->drv->ops.free(dev); diff --git a/src/include/sof/audio/dai_copier.h b/src/include/sof/audio/dai_copier.h index 6219b92fb5b7..67165cb6d265 100644 --- a/src/include/sof/audio/dai_copier.h +++ b/src/include/sof/audio/dai_copier.h @@ -44,7 +44,11 @@ int dai_common_ts_start(struct dai_data *dd, struct comp_dev *dev); int dai_common_ts_stop(struct dai_data *dd, struct comp_dev *dev); +#if CONFIG_ZEPHYR_NATIVE_DRIVERS +int dai_common_ts_get(struct dai_data *dd, struct comp_dev *dev, struct dai_ts_data *tsd); +#else int dai_common_ts_get(struct dai_data *dd, struct comp_dev *dev, struct timestamp_data *tsd); +#endif int dai_common_get_hw_params(struct dai_data *dd, struct comp_dev *dev, struct sof_ipc_stream_params *params, int dir); diff --git a/src/include/sof/audio/dcblock/dcblock.h b/src/include/sof/audio/dcblock/dcblock.h index 35019364b33f..2d0d46317e5c 100644 --- a/src/include/sof/audio/dcblock/dcblock.h +++ b/src/include/sof/audio/dcblock/dcblock.h @@ -43,8 +43,8 @@ struct dcblock_state { struct comp_data; typedef void (*dcblock_func)(struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + const struct audio_stream *sink, uint32_t frames); /* DC Blocking Filter component private data */ diff --git a/src/include/sof/audio/dp_queue.h b/src/include/sof/audio/dp_queue.h new file mode 100644 index 000000000000..b187eb7a6f86 --- /dev/null +++ b/src/include/sof/audio/dp_queue.h @@ -0,0 +1,224 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + */ + +#ifndef __SOF_DP_QUEUE_H__ +#define __SOF_DP_QUEUE_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * DP queue is a lockless circular buffer + * providing safe consumer/producer cached operations cross cores + * + * prerequisites: + * 1) incoming and outgoing data rate MUST be the same + * 2) Both data consumer and data producer declare max chunk sizes they want to use (IBS/OBS) + * + * required Buffer size is 2*MAX(IBS,OBS) to allow free read/write in various data chunk sizes + * and execution periods (of course in/out data rates must be same) + * example: + * Consumer reads 5bytes each 3 cycles (IBS = 5) + * producer writes 3bytes every 5 cycles (OBS = 3) + * - cycle0 buffer empty, producer starting processing, consumer must wait + * - cycle3 produce 3 bytes (buf occupation = 3) + * - cycle6 produce 3 bytes (buf occupation = 6), consumer becomes ready + * in DP thread will start now - asyn to LL cycles + * in this example assuming it consumes data in next cycle + * - cycle7 consume 5 bytes, (buf occupation = 1) + * - cycle9 produce 3 bytes (buf occupation = 4) + * - cycle12 (producer goes first) produce 3 bytes (buf occupation = 7) + * consume 5 bytes (buf occupation = 2) + * - cycle15 produce 3 bytes (buf occupation = 5) + * consumer has enough data, but is busy processing prev data + * - cycle15 consume 5 bytes (buf occupation = 0) + * + * ===> max buf occupation = 7 + * + * The worst case is when IBS=OBS and equal periods of consumer/producer + * the buffer must be 2*MAX(IBS,OBS) as we do not know who goes first - consumer or producer, + * especially when both are located on separate cores and EDF scheduling is used + * + * Consumer reads 5 bytes every cycle (IBS = 5) + * producer writes 5 bytes every cycle (OBS = 5) + * - cycle0 consumer goes first - must wait (buf occupation = 0) + * producer produce 5 bytes (buf occupation = 5) + * - cycle1 producer goes first - produce 5 bytes (buf occupation = 10) + * consumer consumes 5 bytes (buf occupation = 5) + * ===> max buf occupation = 10 + * + * + * The queue may work in 2 modes + * 1) local mode + * in case both receiver and sender are located on the same core and cache coherency + * does not matter. dp_queue structure is located in cached memory + * In this case DP Queue is a simple ring buffer + * + * 2) shared mode + * In this case we need to writeback cache when new data arrive and invalidate cache on + * secondary core. dp_queue structure is located in shared memory + * + * + * dpQueue is a lockless consumer/producer safe buffer. It is achieved by having only 2 shared + * variables: + * _write_offset - can be modified by data producer only + * _read_offset - can be modified by data consumer only + * + * as 32 bit operations are atomic, it is multi-thread and multi-core save + * + * There some explanation needed how free_space and available_data are calculated + * + * number of avail data in circular buffer may be calculated as: + * data_avail = _write_offset - _read_offset + * and check for wrap around + * if (data_avail < 0) data_avail = buffer_size - data_avail + * + * The problem is when _write_offset == _read_offset, + * !!! it may mean either that the buffer is empty or the buffer is completely filled !!! + * + * To solve the above issue having only 2 variables mentioned before: + * - allow both offsets to point from 0 to DOUBLE buffer_size + * - when calculating pointers to data, use: data_bufer[offset % buffer_size] + * - use double buffer size in wrap around check when calculating available data + * + * And now: + * - _write_offset == _read_offset + * always means "buffer empty" + * - _write_offset == _read_offset + buffer_size + * always means "buffer full" + */ + +struct dp_queue; +struct sof_audio_stream_params; + +/* DP flags */ +#define DP_QUEUE_MODE_LOCAL 0 +#define DP_QUEUE_MODE_SHARED BIT(1) + +/* the dpQueue structure */ +struct dp_queue { + CORE_CHECK_STRUCT_FIELD; + + /* public */ + struct list_item list; /**< fields for connection queues in a list */ + + /* public: read only */ + struct sof_audio_stream_params audio_stream_params; + size_t data_buffer_size; + + /* private: */ + struct sof_source _source_api; /**< src api handler */ + struct sof_sink _sink_api; /**< sink api handler */ + + uint32_t _flags; /* DP_QUEUE_MODE_* */ + + uint8_t __sparse_cache *_data_buffer; + size_t _write_offset; /* private: to be modified by data producer using API */ + size_t _read_offset; /* private: to be modified by data consumer using API */ + + bool _hw_params_configured; +}; + +/** + * + * @param min_available minimum data available in queue required by the module using + * dp_queue's source api + * @param min_free_space minimum buffer space in queue required by the module using + * dp_queue's sink api + * + * @param flags a combinatin of DP_QUEUE_MODE_* flags determining working mode + * + */ +struct dp_queue *dp_queue_create(size_t min_available, size_t min_free_space, uint32_t flags); + +/** + * @brief remove the queue from the list, free dp queue memory + */ +static inline +void dp_queue_free(struct dp_queue *dp_queue) +{ + CORE_CHECK_STRUCT(dp_queue); + list_item_del(&dp_queue->list); + rfree((__sparse_force void *)dp_queue->_data_buffer); + rfree(dp_queue); +} + +/** + * @brief return a handler to sink API of dp_queue. + * the handler may be used by helper functions defined in sink_api.h + */ +static inline +struct sof_sink *dp_queue_get_sink(struct dp_queue *dp_queue) +{ + CORE_CHECK_STRUCT(dp_queue); + return &dp_queue->_sink_api; +} + +/** + * @brief return a handler to source API of dp_queue + * the handler may be used by helper functions defined in source_api.h + */ +static inline +struct sof_source *dp_queue_get_source(struct dp_queue *dp_queue) +{ + CORE_CHECK_STRUCT(dp_queue); + return &dp_queue->_source_api; +} + +/** + * @brief this is a backdoor to get complete audio params structure from dp_queue + * it is needed till pipeline 2.0 is ready + * + */ +static inline +struct sof_audio_stream_params *dp_queue_get_audio_params(struct dp_queue *dp_queue) +{ + CORE_CHECK_STRUCT(dp_queue); + return &dp_queue->audio_stream_params; +} + +/** + * @brief return true if the queue is shared between 2 cores + */ +static inline +bool dp_queue_is_shared(struct dp_queue *dp_queue) +{ + CORE_CHECK_STRUCT(dp_queue); + return !!(dp_queue->_flags & DP_QUEUE_MODE_SHARED); +} + +/** + * @brief append a dp_queue to the list + */ +static inline void dp_queue_append_to_list(struct dp_queue *item, struct list_item *list) +{ + list_item_append(&item->list, list); +} + +/** + * @brief return a pointer to the first dp_queue on the list + */ +static inline struct dp_queue *dp_queue_get_first_item(struct list_item *list) +{ + return list_first_item(list, struct dp_queue, list); +} + +/** + * @brief return a pointer to the next dp_queue on the list + */ +static inline struct dp_queue *dp_queue_get_next_item(struct dp_queue *item) +{ + return list_next_item(item, list); +} + +#endif /* __SOF_DP_QUEUE_H__ */ diff --git a/src/include/sof/audio/drc/drc.h b/src/include/sof/audio/drc/drc.h index ee480e1d8692..e7571096313e 100644 --- a/src/include/sof/audio/drc/drc.h +++ b/src/include/sof/audio/drc/drc.h @@ -60,8 +60,8 @@ struct drc_state { }; typedef void (*drc_func)(struct processing_module *mod, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, uint32_t frames); /* DRC component private data */ @@ -83,8 +83,8 @@ extern const struct drc_proc_fnmap drc_proc_fnmap[]; extern const size_t drc_proc_fncount; void drc_default_pass(struct processing_module *mod, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, uint32_t frames); + const struct audio_stream *source, + struct audio_stream *sink, uint32_t frames); /** * \brief Returns DRC processing function. */ diff --git a/src/include/sof/audio/eq_iir/eq_iir.h b/src/include/sof/audio/eq_iir/eq_iir.h deleted file mode 100644 index bcd4f9d79280..000000000000 --- a/src/include/sof/audio/eq_iir/eq_iir.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2017 Intel Corporation. All rights reserved. - * - * Author: Seppo Ingalsuo - * Liam Girdwood - * Keyon Jie - */ - -#ifndef __SOF_AUDIO_EQ_IIR_EQ_IIR_H__ -#define __SOF_AUDIO_EQ_IIR_EQ_IIR_H__ - -#include -#include -#include - -/** \brief Macros to convert without division bytes count to samples count */ -#define EQ_IIR_BYTES_TO_S16_SAMPLES(b) ((b) >> 1) -#define EQ_IIR_BYTES_TO_S32_SAMPLES(b) ((b) >> 2) - -struct audio_stream; -struct comp_dev; - -/** \brief Type definition for processing function select return value. */ -typedef void (*eq_iir_func)(struct processing_module *mod, struct input_stream_buffer *bsource, - struct output_stream_buffer *bsink, uint32_t frames); - -/** \brief IIR EQ processing functions map item. */ -struct eq_iir_func_map { - uint8_t source; /**< source frame format */ - uint8_t sink; /**< sink frame format */ - eq_iir_func func; /**< processing function */ -}; - -#ifdef UNIT_TEST -void sys_comp_module_eq_iir_interface_init(void); -#endif - -#endif /* __SOF_AUDIO_EQ_IIR_EQ_IIR_H__ */ diff --git a/src/include/sof/audio/format.h b/src/include/sof/audio/format.h index 55b0c8a5debf..a33d3c60fce4 100644 --- a/src/include/sof/audio/format.h +++ b/src/include/sof/audio/format.h @@ -179,6 +179,21 @@ static inline uint32_t get_sample_bytes(enum sof_ipc_frame fmt) } } +static inline uint32_t get_sample_bitdepth(enum sof_ipc_frame fmt) +{ + switch (fmt) { + case SOF_IPC_FRAME_S16_LE: + return 16; + case SOF_IPC_FRAME_S24_4LE: + case SOF_IPC_FRAME_S24_3LE: + return 24; + case SOF_IPC_FRAME_U8: + return 8; + default: + return 32; + } +} + static inline uint32_t get_frame_bytes(enum sof_ipc_frame fmt, uint32_t channels) { diff --git a/src/include/sof/audio/host_copier.h b/src/include/sof/audio/host_copier.h index 60f0dccfdb90..c7ac454bf800 100644 --- a/src/include/sof/audio/host_copier.h +++ b/src/include/sof/audio/host_copier.h @@ -96,6 +96,7 @@ struct host_data { /* stream info */ struct sof_ipc_stream_posn posn; /* TODO: update this */ struct ipc_msg *msg; /**< host notification */ + uint32_t dma_buffer_size; /* dma buffer size */ #if CONFIG_HOST_DMA_STREAM_SYNCHRONIZATION bool is_grouped; uint8_t group_id; diff --git a/src/include/sof/audio/igo_nr/igo_nr_comp.h b/src/include/sof/audio/igo_nr/igo_nr_comp.h index 50159adb1a08..64c663a99944 100644 --- a/src/include/sof/audio/igo_nr/igo_nr_comp.h +++ b/src/include/sof/audio/igo_nr/igo_nr_comp.h @@ -41,8 +41,8 @@ struct comp_data { int32_t sink_frames_max; /* Max # of frames to process at sink */ int32_t frames; /* IO buffer length */ void (*igo_nr_func)(struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, int32_t frames); }; diff --git a/src/include/sof/audio/kpb.h b/src/include/sof/audio/kpb.h index 852659f86c98..dbec1207c467 100644 --- a/src/include/sof/audio/kpb.h +++ b/src/include/sof/audio/kpb.h @@ -43,6 +43,7 @@ struct comp_buffer; (KPB_SAMPLE_CONTAINER_SIZE(sw) / 8) * KPB_MAX_BUFF_TIME * \ (channels_number)) #define KPB_MAX_NO_OF_CLIENTS 2 +#define KPB_MAX_SINK_CNT (1 + KPB_MAX_NO_OF_CLIENTS) #define KPB_NO_OF_HISTORY_BUFFERS 2 /**< no of internal buffers */ #define KPB_ALLOCATION_STEP 0x100 #define KPB_NO_OF_MEM_POOLS 3 @@ -66,6 +67,9 @@ struct comp_buffer; * i.e. number of max supported channels - reference channels) */ #define KPB_MAX_MICSEL_CHANNELS 4 +/* Used in FMT */ +#define FAST_MODE_TASK_MAX_MODULES_COUNT 16 +#define REALTIME_PIN_ID 0 /** All states below as well as relations between them are documented in * the sof-dosc in [kpbm-state-diagram] @@ -159,18 +163,88 @@ struct history_data { struct history_buffer *c_hb; /**< current buffer used for writing */ }; -enum ipc4_kpb_module_config_params { - /* Mic selector for client - sets microphone id for real time sink mic selector - * IPC4-compatible ID - please do not change the number - */ - KP_BUF_CLIENT_MIC_SELECT = 11, -}; +/* moved to ipc4/kpb.h */ +/* enum ipc4_kpb_module_config_params */ /* Stores KPB mic selector config */ struct kpb_micselector_config { /* channel bit set to 1 implies channel selection */ uint32_t mask; }; + +struct kpb_task_params { + /* If largeconfigset is set to KP_POS_IN_BUFFER then number of modules must + * correspond to number of modules between kpb and copier attached to hostdma. + * Once draining path is configured, cannot be reinitialized/changed. + */ + uint32_t number_of_modules; + struct { + uint16_t module_id; + uint16_t instance_id; + } dev_ids[1]; +}; + +/* fmt namespace: */ +#define FAST_MODE_TASK_MAX_LIST_COUNT 5 + +struct fast_mode_task { + /*! Array of pointers to all module lists to be processed. */ + struct device_list *device_list[FAST_MODE_TASK_MAX_LIST_COUNT]; +}; + +/* The +1 is here because we also push the kbp device + * handle in addition to the max number of modules + */ +#define DEVICE_LIST_SIZE (FAST_MODE_TASK_MAX_MODULES_COUNT + 1) + +/* Devicelist type + * In Reference FW KPB used Bi-dir lists to store modules for FMT. It is possible that lists are + * not necessary, but in case it might be wrong, here we use an array + * with a list interface to switch it to a list easily. + */ +struct device_list { + struct comp_dev **devs[DEVICE_LIST_SIZE]; + /* number of items AND index of next empty box */ + size_t count; +}; + +/* + * + * + * KPB FMT config set steps: + * 1. Get dev_ids of module instances from IPC + * 2. Alloc this kpb module instance on kpb_list_item, save address of where it was allocated + * 3. Push the address on dev_list.device_list + * 2. For each dev_id get device handler(module instance) + * 3. Alloc device handler in modules_list_item, save address of where it was allocated + * 4. Register this address in fmt.device_list + * + * Pointer structure: + * + * COMP_DEVS + * ^ + * | + * dev_list.modules_list_item(comp_dev* ) + * ^ + * | + * dev_list.device_list(comp_dev**) + * ^ + * | + * fmt.device_list(device_list*) + * + * + */ + +/* KpbFastModeTaskModulesList Namespace */ +struct kpb_fmt_dev_list { + /*! Array of all module lists to be processed. */ + struct device_list device_list[FAST_MODE_TASK_MAX_LIST_COUNT]; + /* One for each sinkpin. */ + struct comp_dev *kpb_list_item[KPB_MAX_SINK_CNT]; + struct comp_dev *modules_list_item[FAST_MODE_TASK_MAX_MODULES_COUNT]; + struct comp_dev *kpb_mi_ptr; +}; + #ifdef UNIT_TEST void sys_comp_kpb_init(void); #endif diff --git a/src/include/sof/audio/mixer.h b/src/include/sof/audio/mixer.h index 2dd5e3c80885..118aaf1c914f 100644 --- a/src/include/sof/audio/mixer.h +++ b/src/include/sof/audio/mixer.h @@ -34,16 +34,16 @@ void sys_comp_module_mixer_interface_init(void); /* mixer component private data */ struct mixer_data { - void (*mix_func)(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache **sources, uint32_t count, + void (*mix_func)(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream **sources, uint32_t count, uint32_t frames); }; /** * \brief mixer processing function interface */ -typedef void (*mixer_func)(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache **sources, uint32_t num_sources, +typedef void (*mixer_func)(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream **sources, uint32_t num_sources, uint32_t frames); /** \brief Volume processing functions map. */ @@ -64,7 +64,7 @@ extern const size_t mixer_func_count; * \param[in] sinkb Sink buffer to match against */ static inline mixer_func mixer_get_processing_function(struct comp_dev *dev, - struct comp_buffer __sparse_cache *sinkb) + struct comp_buffer *sinkb) { int i; diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index 28f5c0765d0c..90f91ab0cef7 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -15,12 +15,28 @@ #include #include #include +#include +#include +#include #include "module_interface.h" #if CONFIG_INTEL_MODULES #include "modules.h" #endif +/* + * helpers to determine processing type + * Needed till all the modules use PROCESSING_MODE_SINK_SOURCE + */ +#define IS_PROCESSING_MODE_AUDIO_STREAM(mod) \ + (!!((struct module_data *)&(mod)->priv)->ops->process_audio_stream) + +#define IS_PROCESSING_MODE_RAW_DATA(mod) \ + (!!((struct module_data *)&(mod)->priv)->ops->process_raw_data) + +#define IS_PROCESSING_MODE_SINK_SOURCE(mod) \ + (!!((struct module_data *)&(mod)->priv)->ops->process) + #define module_get_private_data(mod) (mod->priv.private) #define MAX_BLOB_SIZE 8192 #define MODULE_MAX_SOURCES 8 @@ -155,23 +171,13 @@ struct module_data { void *private; /**< self object, memory tables etc here */ void *runtime_params; struct module_config cfg; /**< module configuration data */ - struct module_interface *ops; /**< module specific operations */ + const struct module_interface *ops; /**< module specific operations */ struct module_memory memory; /**< memory allocated by module */ struct module_processing_data mpd; /**< shared data comp <-> module */ void *module_adapter; /**ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP + */ + struct list_item dp_queue_ll_to_dp_list; + struct list_item dp_queue_dp_to_ll_list; + }; + }; struct comp_buffer *source_comp_buffer; /**< single source component buffer */ struct comp_buffer *sink_comp_buffer; /**< single sink compoonent buffer */ @@ -224,9 +253,6 @@ struct processing_module { /* pointer to system services for loadable modules */ uint32_t *sys_service; - /* table containing the list of connected sources */ - struct module_source_info *source_info; - /* total processed data after stream started */ uint64_t total_data_consumed; uint64_t total_data_produced; @@ -240,19 +266,19 @@ struct processing_module { /* Module generic interfaces */ /*****************************************************************************/ int module_load_config(struct comp_dev *dev, const void *cfg, size_t size); -int module_init(struct processing_module *mod, struct module_interface *interface); +int module_init(struct processing_module *mod, const struct module_interface *interface); void *module_allocate_memory(struct processing_module *mod, uint32_t size, uint32_t alignment); int module_free_memory(struct processing_module *mod, void *ptr); void module_free_all_memory(struct processing_module *mod); int module_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks); + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks); static inline bool module_is_ready_to_process(struct processing_module *mod, - struct sof_source __sparse_cache **sources, + struct sof_source **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, + struct sof_sink **sinks, int num_of_sinks) { struct module_data *md = &mod->priv; @@ -267,13 +293,13 @@ bool module_is_ready_to_process(struct processing_module *mod, /* default action - the module is ready if there's enough data for processing and enough * space to store result. IBS/OBS as declared in init_instance */ - return (source_get_data_available(sources[0]) >= source_get_ibs(sources[0]) && - sink_get_free_size(sinks[0]) >= sink_get_obs(sinks[0])); + return (source_get_data_available(sources[0]) >= source_get_min_available(sources[0]) && + sink_get_free_size(sinks[0]) >= sink_get_min_free_space(sinks[0])); } int module_process_sink_src(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks); + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks); int module_process_legacy(struct processing_module *mod, struct input_stream_buffer *input_buffers, int num_input_buffers, struct output_stream_buffer *output_buffers, @@ -290,7 +316,7 @@ int module_unbind(struct processing_module *mod, void *data); struct comp_dev *module_adapter_new(const struct comp_driver *drv, const struct comp_ipc_config *config, - struct module_interface *interface, const void *spec); + const struct module_interface *interface, const void *spec); int module_adapter_prepare(struct comp_dev *dev); int module_adapter_params(struct comp_dev *dev, struct sof_ipc_stream_params *params); int module_adapter_copy(struct comp_dev *dev); @@ -298,69 +324,73 @@ int module_adapter_cmd(struct comp_dev *dev, int cmd, void *data, int max_data_s int module_adapter_trigger(struct comp_dev *dev, int cmd); void module_adapter_free(struct comp_dev *dev); int module_adapter_reset(struct comp_dev *dev); -int module_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, - bool last_block, uint32_t data_offset, const char *data); -int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, - bool last_block, uint32_t *data_offset, char *data); -int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *value); -int module_adapter_bind(struct comp_dev *dev, void *data); -int module_adapter_unbind(struct comp_dev *dev, void *data); -uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, - uint32_t stream_no, bool input); -int module_adapter_get_hw_params(struct comp_dev *dev, struct sof_ipc_stream_params *params, - int dir); -int module_adapter_position(struct comp_dev *dev, struct sof_ipc_stream_posn *posn); -int module_adapter_ts_config_op(struct comp_dev *dev); -int module_adapter_ts_start_op(struct comp_dev *dev); -int module_adapter_ts_stop_op(struct comp_dev *dev); -int module_adapter_ts_get_op(struct comp_dev *dev, struct timestamp_data *tsd); -static inline void module_update_buffer_position(struct input_stream_buffer *input_buffers, - struct output_stream_buffer *output_buffers, - uint32_t frames) +#if CONFIG_IPC_MAJOR_3 +static inline +int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *value) { - struct audio_stream __sparse_cache *source = input_buffers->data; - struct audio_stream __sparse_cache *sink = output_buffers->data; - - input_buffers->consumed += audio_stream_frame_bytes(source) * frames; - output_buffers->size += audio_stream_frame_bytes(sink) * frames; + return -EINVAL; } -__must_check static inline -struct module_source_info __sparse_cache *module_source_info_acquire(struct module_source_info *msi) +static inline +int module_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, + bool last_block, uint32_t data_offset, const char *data) { - struct coherent __sparse_cache *c; - - c = coherent_acquire_thread(&msi->c, sizeof(*msi)); + return 0; +} - return attr_container_of(c, struct module_source_info __sparse_cache, c, __sparse_cache); +static inline +int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, + bool last_block, uint32_t *data_offset, char *data) +{ + return 0; } -static inline void module_source_info_release(struct module_source_info __sparse_cache *msi) +static inline +int module_adapter_bind(struct comp_dev *dev, void *data) { - coherent_release_thread(&msi->c, sizeof(*msi)); + return 0; } -/* when source argument is NULL, this function returns the first unused entry */ static inline -int find_module_source_index(struct module_source_info __sparse_cache *msi, - const struct comp_dev *source) +int module_adapter_unbind(struct comp_dev *dev, void *data) { - int i; + return 0; +} - for (i = 0; i < MODULE_MAX_SOURCES; i++) { - if (msi->sources[i] == source) - return i; - } +static inline +uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, + uint32_t stream_no, bool input) +{ + return 0; +} - return -EINVAL; +static inline int module_process_endpoint(struct processing_module *mod, + struct input_stream_buffer *input_buffers, + int num_input_buffers, + struct output_stream_buffer *output_buffers, + int num_output_buffers) +{ + return module_process_legacy(mod, input_buffers, num_input_buffers, + output_buffers, num_output_buffers); } -static inline int module_process_stream(struct processing_module *mod, - struct input_stream_buffer *input_buffers, - int num_input_buffers, - struct output_stream_buffer *output_buffers, - int num_output_buffers) +#else +int module_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, + bool last_block, uint32_t data_offset, const char *data); +int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, + bool last_block, uint32_t *data_offset, char *data); +int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *value); +int module_adapter_bind(struct comp_dev *dev, void *data); +int module_adapter_unbind(struct comp_dev *dev, void *data); +uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, + uint32_t stream_no, bool input); + +static inline int module_process_endpoint(struct processing_module *mod, + struct input_stream_buffer *input_buffers, + int num_input_buffers, + struct output_stream_buffer *output_buffers, + int num_output_buffers) { struct module_data *md = &mod->priv; @@ -368,4 +398,32 @@ static inline int module_process_stream(struct processing_module *mod, output_buffers, num_output_buffers); } +#endif + +int module_adapter_get_hw_params(struct comp_dev *dev, struct sof_ipc_stream_params *params, + int dir); +int module_adapter_position(struct comp_dev *dev, struct sof_ipc_stream_posn *posn); +int module_adapter_ts_config_op(struct comp_dev *dev); +int module_adapter_ts_start_op(struct comp_dev *dev); +int module_adapter_ts_stop_op(struct comp_dev *dev); +#if CONFIG_ZEPHYR_NATIVE_DRIVERS +int module_adapter_ts_get_op(struct comp_dev *dev, struct dai_ts_data *tsd); +#else +int module_adapter_ts_get_op(struct comp_dev *dev, struct timestamp_data *tsd); +#endif + +void module_update_buffer_position(struct input_stream_buffer *input_buffers, + struct output_stream_buffer *output_buffers, + uint32_t frames); + +int module_adapter_init_data(struct comp_dev *dev, + struct module_config *dst, + const struct comp_ipc_config *config, + const void *spec); +void module_adapter_reset_data(struct module_config *dst); +void module_adapter_check_data(struct processing_module *mod, struct comp_dev *dev, + struct comp_buffer *sink); +void module_adapter_set_params(struct processing_module *mod, struct sof_ipc_stream_params *params); +int module_adapter_set_state(struct processing_module *mod, struct comp_dev *dev, + int cmd); #endif /* __SOF_AUDIO_MODULE_GENERIC__ */ diff --git a/src/include/sof/audio/module_adapter/module/module_interface.h b/src/include/sof/audio/module_adapter/module/module_interface.h index e4b7ddcfb7d4..70884e493861 100644 --- a/src/include/sof/audio/module_adapter/module/module_interface.h +++ b/src/include/sof/audio/module_adapter/module/module_interface.h @@ -50,7 +50,7 @@ enum module_processing_mode { * \brief Input stream buffer */ struct input_stream_buffer { - void __sparse_cache *data; /* data stream buffer */ + void *data; /* data stream buffer */ uint32_t size; /* size of data in the buffer */ uint32_t consumed; /* number of bytes consumed by the module */ @@ -63,12 +63,13 @@ struct input_stream_buffer { * \brief Output stream buffer */ struct output_stream_buffer { - void __sparse_cache *data; /* data stream buffer */ + void *data; /* data stream buffer */ uint32_t size; /* size of data in the buffer */ }; struct comp_dev; struct timestamp_data; +struct dai_ts_data; /** * \struct module_endpoint_ops * \brief Ops relevant only for the endpoint devices such as the host copier or DAI copier. @@ -120,7 +121,11 @@ struct module_endpoint_ops { * * Mandatory for components that allocate DAI. */ +#if CONFIG_ZEPHYR_NATIVE_DRIVERS + int (*dai_ts_get)(struct comp_dev *dev, struct dai_ts_data *tsd); +#else int (*dai_ts_get)(struct comp_dev *dev, struct timestamp_data *tsd); +#endif /** * Fetches hardware stream parameters. @@ -158,8 +163,8 @@ struct module_interface { * component preparation in .prepare() */ int (*prepare)(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks); + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks); /** * (optional) return true if the module is ready to process @@ -177,8 +182,8 @@ struct module_interface { * the module */ bool (*is_ready_to_process)(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks); + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks); /** * Module specific processing procedure @@ -200,8 +205,8 @@ struct module_interface { * - sinks are handlers to sink API struct sink*[] */ int (*process)(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks); + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks); /** * process_audio_stream (depreciated) diff --git a/src/include/sof/audio/multiband_drc/multiband_drc.h b/src/include/sof/audio/multiband_drc/multiband_drc.h index a5058bd158dc..2c331215a8ee 100644 --- a/src/include/sof/audio/multiband_drc/multiband_drc.h +++ b/src/include/sof/audio/multiband_drc/multiband_drc.h @@ -28,8 +28,8 @@ struct multiband_drc_state { }; typedef void (*multiband_drc_func)(const struct processing_module *mod, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + struct audio_stream *sink, uint32_t frames); /* Multiband DRC component private data */ diff --git a/src/include/sof/audio/mux.h b/src/include/sof/audio/mux.h index 2c42c2506edd..e8eb9bc9de54 100644 --- a/src/include/sof/audio/mux.h +++ b/src/include/sof/audio/mux.h @@ -65,11 +65,11 @@ struct mux_stream_data { uint8_t reserved2[3]; // padding to ensure proper alignment of following instances } __attribute__((packed, aligned(4))); -typedef void(*demux_func)(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *source, uint32_t frames, +typedef void(*demux_func)(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream *source, uint32_t frames, struct mux_look_up *look_up); -typedef void(*mux_func)(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache **sources, uint32_t frames, +typedef void(*mux_func)(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream **sources, uint32_t frames, struct mux_look_up *look_up); /** diff --git a/src/include/sof/audio/pcm_converter.h b/src/include/sof/audio/pcm_converter.h index 09d20f5568b6..a06dc79f632a 100644 --- a/src/include/sof/audio/pcm_converter.h +++ b/src/include/sof/audio/pcm_converter.h @@ -45,8 +45,8 @@ struct audio_stream; * \param samples number of samples to convert * \return error code or number of processed samples. */ -typedef int (*pcm_converter_func)(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +typedef int (*pcm_converter_func)(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples); /** @@ -156,8 +156,8 @@ pcm_get_conversion_vc_function(enum sof_ipc_frame in_bits, * \param converter core conversion function working on linear memory regions * \return error code or number of processed samples */ -int pcm_convert_as_linear(const struct audio_stream __sparse_cache *source, uint32_t ioffset, - struct audio_stream __sparse_cache *sink, uint32_t ooffset, +int pcm_convert_as_linear(const struct audio_stream *source, uint32_t ioffset, + struct audio_stream *sink, uint32_t ooffset, uint32_t samples, pcm_converter_lin_func converter); #endif /* __SOF_AUDIO_PCM_CONVERTER_H__ */ diff --git a/src/include/sof/audio/pipeline.h b/src/include/sof/audio/pipeline.h index d80e4380aa82..8dc5ea16d51d 100644 --- a/src/include/sof/audio/pipeline.h +++ b/src/include/sof/audio/pipeline.h @@ -100,7 +100,7 @@ struct pipeline_walk_context { int (*comp_func)(struct comp_dev *cd, struct comp_buffer *buffer, struct pipeline_walk_context *ctx, int dir); void *comp_data; - void (*buff_func)(struct comp_buffer __sparse_cache *buffer, void *data); + void (*buff_func)(struct comp_buffer *buffer, void *data); void *buff_data; struct comp_buffer *incoming; /**< pipelines to be scheduled after trigger walk */ diff --git a/src/include/sof/audio/selector.h b/src/include/sof/audio/selector.h index e07576430322..cd4aa926c7f4 100644 --- a/src/include/sof/audio/selector.h +++ b/src/include/sof/audio/selector.h @@ -100,8 +100,8 @@ struct sof_selector_avs_ipc4_config { }; #else -typedef void (*sel_func)(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *source, uint32_t frames); +typedef void (*sel_func)(struct comp_dev *dev, struct audio_stream *sink, + const struct audio_stream *source, uint32_t frames); #endif /** \brief Selector component private data. */ diff --git a/src/include/sof/audio/sink_api.h b/src/include/sof/audio/sink_api.h index 07172f332555..bb279166c167 100644 --- a/src/include/sof/audio/sink_api.h +++ b/src/include/sof/audio/sink_api.h @@ -54,13 +54,13 @@ struct sof_ipc_stream_params; * Retrieves size of free space available in sink (in bytes) * return number of free bytes in buffer available to immediate filling */ -size_t sink_get_free_size(struct sof_sink __sparse_cache *sink); +size_t sink_get_free_size(struct sof_sink *sink); /** * Retrieves size of free space available in sink (in frames) * return number of free bytes in buffer available to immediate filling */ -size_t sink_get_free_frames(struct sof_sink __sparse_cache *sink); +size_t sink_get_free_frames(struct sof_sink *sink); /** * Get a circular buffer to operate on (to write). @@ -81,7 +81,7 @@ size_t sink_get_free_frames(struct sof_sink __sparse_cache *sink); * @retval -ENODATA if req_size is bigger than free space * */ -int sink_get_buffer(struct sof_sink __sparse_cache *sink, size_t req_size, +int sink_get_buffer(struct sof_sink *sink, size_t req_size, void **data_ptr, void **buffer_start, size_t *buffer_size); /** @@ -96,7 +96,7 @@ int sink_get_buffer(struct sof_sink __sparse_cache *sink, size_t req_size, * commit_buffer with commit_size==MAXINT * @return proper error code (0 on success) */ -int sink_commit_buffer(struct sof_sink __sparse_cache *sink, size_t commit_size); +int sink_commit_buffer(struct sof_sink *sink, size_t commit_size); /** * Get total number of bytes processed by the sink (meaning - committed by sink_commit_buffer()) @@ -104,33 +104,33 @@ int sink_commit_buffer(struct sof_sink __sparse_cache *sink, size_t commit_size) * @param sink a handler to sink * @return total number of processed data */ -size_t sink_get_num_of_processed_bytes(struct sof_sink __sparse_cache *sink); +size_t sink_get_num_of_processed_bytes(struct sof_sink *sink); /** * sets counter of total number of bytes processed to zero */ -void sink_reset_num_of_processed_bytes(struct sof_sink __sparse_cache *sink); +void sink_reset_num_of_processed_bytes(struct sof_sink *sink); /** get size of a single audio frame (in bytes) */ -size_t sink_get_frame_bytes(struct sof_sink __sparse_cache *sink); +size_t sink_get_frame_bytes(struct sof_sink *sink); /** set of functions for retrieve audio parameters */ -enum sof_ipc_frame sink_get_frm_fmt(struct sof_sink __sparse_cache *sink); -enum sof_ipc_frame sink_get_valid_fmt(struct sof_sink __sparse_cache *sink); -uint32_t sink_get_rate(struct sof_sink __sparse_cache *sink); -uint32_t sink_get_channels(struct sof_sink __sparse_cache *sink); -uint32_t sink_get_buffer_fmt(struct sof_sink __sparse_cache *sink); -bool sink_get_overrun(struct sof_sink __sparse_cache *sink); +enum sof_ipc_frame sink_get_frm_fmt(struct sof_sink *sink); +enum sof_ipc_frame sink_get_valid_fmt(struct sof_sink *sink); +uint32_t sink_get_rate(struct sof_sink *sink); +uint32_t sink_get_channels(struct sof_sink *sink); +uint32_t sink_get_buffer_fmt(struct sof_sink *sink); +bool sink_get_overrun(struct sof_sink *sink); /** set of functions for setting audio parameters */ -int sink_set_frm_fmt(struct sof_sink __sparse_cache *sink, enum sof_ipc_frame frame_fmt); -int sink_set_valid_fmt(struct sof_sink __sparse_cache *sink, enum sof_ipc_frame valid_sample_fmt); -int sink_set_rate(struct sof_sink __sparse_cache *sink, unsigned int rate); -int sink_set_channels(struct sof_sink __sparse_cache *sink, unsigned int channels); -int sink_set_overrun(struct sof_sink __sparse_cache *sink, bool overrun_permitted); -int sink_set_buffer_fmt(struct sof_sink __sparse_cache *sink, uint32_t buffer_fmt); -void sink_set_obs(struct sof_sink __sparse_cache *sink, size_t obs); -size_t sink_get_obs(struct sof_sink __sparse_cache *sink); +int sink_set_frm_fmt(struct sof_sink *sink, enum sof_ipc_frame frame_fmt); +int sink_set_valid_fmt(struct sof_sink *sink, enum sof_ipc_frame valid_sample_fmt); +int sink_set_rate(struct sof_sink *sink, unsigned int rate); +int sink_set_channels(struct sof_sink *sink, unsigned int channels); +int sink_set_overrun(struct sof_sink *sink, bool overrun_permitted); +int sink_set_buffer_fmt(struct sof_sink *sink, uint32_t buffer_fmt); +void sink_set_min_free_space(struct sof_sink *sink, size_t min_free_space); +size_t sink_get_min_free_space(struct sof_sink *sink); /** * initial set of audio parameters, provided in sof_ipc_stream_params @@ -140,7 +140,7 @@ size_t sink_get_obs(struct sof_sink __sparse_cache *sink); * @param force_update tells the implementation that the params should override actual settings * @return 0 if success */ -int sink_set_params(struct sof_sink __sparse_cache *sink, +int sink_set_params(struct sof_sink *sink, struct sof_ipc_stream_params *params, bool force_update); /** @@ -158,7 +158,7 @@ int sink_set_params(struct sof_sink __sparse_cache *sink, * * @return 0 if success */ -int sink_set_alignment_constants(struct sof_sink __sparse_cache *sink, +int sink_set_alignment_constants(struct sof_sink *sink, const uint32_t byte_align, const uint32_t frame_align_req); diff --git a/src/include/sof/audio/sink_api_implementation.h b/src/include/sof/audio/sink_api_implementation.h index 15db32152039..23cec8dbb30e 100644 --- a/src/include/sof/audio/sink_api_implementation.h +++ b/src/include/sof/audio/sink_api_implementation.h @@ -27,18 +27,18 @@ struct sink_ops { /** * see comment of sink_get_free_size() */ - size_t (*get_free_size)(struct sof_sink __sparse_cache *sink); + size_t (*get_free_size)(struct sof_sink *sink); /** * see comment of sink_get_buffer() */ - int (*get_buffer)(struct sof_sink __sparse_cache *sink, size_t req_size, + int (*get_buffer)(struct sof_sink *sink, size_t req_size, void **data_ptr, void **buffer_start, size_t *buffer_size); /** * see comment of sink_commit_buffer() */ - int (*commit_buffer)(struct sof_sink __sparse_cache *sink, size_t commit_size); + int (*commit_buffer)(struct sof_sink *sink, size_t commit_size); /** * OPTIONAL: Notification to the sink implementation about changes in audio format @@ -49,20 +49,20 @@ struct sink_ops { * * @retval 0 if success, negative if new parameters are not supported */ - int (*on_audio_format_set)(struct sof_sink __sparse_cache *sink); + int (*on_audio_format_set)(struct sof_sink *sink); /** * OPTIONAL * see sink_set_params comments */ - int (*audio_set_ipc_params)(struct sof_sink __sparse_cache *sink, + int (*audio_set_ipc_params)(struct sof_sink *sink, struct sof_ipc_stream_params *params, bool force_update); /** * OPTIONAL * see comment for sink_set_alignment_constants */ - int (*set_alignment_constants)(struct sof_sink __sparse_cache *sink, + int (*set_alignment_constants)(struct sof_sink *sink, const uint32_t byte_align, const uint32_t frame_align_req); }; @@ -72,7 +72,9 @@ struct sof_sink { const struct sink_ops *ops; /** operations interface */ size_t requested_write_frag_size; /** keeps number of bytes requested by get_buffer() */ size_t num_of_bytes_processed; /** processed bytes counter */ - size_t obs; /** output buffer size as declared in module bind IPC */ + size_t min_free_space; /** minimum buffer space required by the module using sink + * it is module's OBS as declared in module bind IPC + */ struct sof_audio_stream_params *audio_stream_params; /** pointer to audio params */ }; @@ -86,7 +88,7 @@ struct sof_sink { * the implementation must ensure coherent access to the parameteres * in case of i.e. cross core shared queue, it must be located in non-cached memory */ -void sink_init(struct sof_sink __sparse_cache *sink, const struct sink_ops *ops, +void sink_init(struct sof_sink *sink, const struct sink_ops *ops, struct sof_audio_stream_params *audio_stream_params); #endif /* __SOF_SINK_API_IMPLEMENTATION_H__ */ diff --git a/src/include/sof/audio/sink_source_utils.h b/src/include/sof/audio/sink_source_utils.h index 8f550b1d2276..ca8752f07294 100644 --- a/src/include/sof/audio/sink_source_utils.h +++ b/src/include/sof/audio/sink_source_utils.h @@ -19,7 +19,7 @@ * if false, data will remain in the source * @param size number of bytes to be copied */ -int source_to_sink_copy(struct sof_source __sparse_cache *source, - struct sof_sink __sparse_cache *sink, bool free, size_t size); +int source_to_sink_copy(struct sof_source *source, + struct sof_sink *sink, bool free, size_t size); #endif /* SINK_SOURCE_UTILS_H */ diff --git a/src/include/sof/audio/smart_amp/smart_amp.h b/src/include/sof/audio/smart_amp/smart_amp.h index 6438d7f082bc..6417d17726a0 100644 --- a/src/include/sof/audio/smart_amp/smart_amp.h +++ b/src/include/sof/audio/smart_amp/smart_amp.h @@ -1,8 +1,12 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2020 Maxim Integrated. All rights reserved. + * Copyright(c) 2020 Maxim Integrated All rights reserved. * * Author: Ryan Lee + * + * Copyright(c) 2023 Google LLC. + * + * Author: Pin-chih Lin */ #ifndef __SOF_AUDIO_DSM_H__ @@ -11,6 +15,46 @@ #include #include +/* Smart Amplifier component is a two-layer structured design, i.e. generic + * layer and inner model layer. The latter can have various implementations + * respectively for Amplifier solution suppliers, while the former is the common + * part of Smart Amp process adaptable for all solutions. + * + * In structural aspect, one can regard generic layer as the glue code that + * wraps inner model in a SOF component. Ops are defined for interaction between + * two layers. Inner model is the solution-specific modular code, which may have + * static libraries linked as needed. The structure is figured below: + * + * SRC(FF) SINK(OUT) +-SRC(FB) bytectl + * +- SMART_AMP |^ comp ops | ^ | ^| + * | +------------------v|-------------v---------|------v-----------|v---------+ + * | | Generic Layer (chan remap/fmt conv) || | + * | | (memory mgr)--+------> :::::::::BUFFERS::::::::::::: |+> CONFIG | + * | +------------------|-|^-----------|---------^------|-----------^|---------+ + * | | || mod ops | | | || + * | +------------------v-v|-----------v---------|------v-----------|v---------+ + * | | Inner Model :::::::::::::::::::::BUFFERS::::::::::::::::::::::: | + * | | (solution-specific impl/wrapper) |+> MODEL | + * | +------------------------------|^------------------------------^----------+ + * +--- v| lib ops | CALDATA + * Static Libs (as needed) ----------+ + * Note: + * - FF(Feed-Forward): un-processed playback frame source + * - FB(Feedback): feedback reference frame source (from the capture pipeline) + * + * As illustrated above, generic layer handles the cross-communication for inner + * model and SOF pipeline flow, as well as the smart-amp common tasks including: + * 1. Channel remapping for input/output frames + * 2. Frame format conversion for input/output frames. It allows inner model to + * work with different format from SOF audio stream. + * (Now it only allows the bitdepth of inner model format >= SOF stream, + * e.g. inner model: S32_LE, SOF stream: S16_LE) + * 3. Full-management of runtime memory. That is, dynamic memory buffers either + * required by generic layer or inner model will be allocated/owned/released + * by generic layer. + * More details are stated in the comment of each struct/function later. + */ + /* Maximum number of channels for algorithm in */ #define SMART_AMP_FF_MAX_CH_NUM 2 /* Maximum number of channels for algorithm out */ @@ -18,173 +62,261 @@ /* Maximum number of channels for feedback */ #define SMART_AMP_FB_MAX_CH_NUM 4 -#define SMART_AMP_FRM_SZ 48 /* samples per 1ms */ +#define SMART_AMP_FRM_SZ 48 /* frames per 1ms */ #define SMART_AMP_FF_BUF_SZ (SMART_AMP_FRM_SZ * SMART_AMP_FF_MAX_CH_NUM) #define SMART_AMP_FB_BUF_SZ (SMART_AMP_FRM_SZ * SMART_AMP_FB_MAX_CH_NUM) -/* Maxim DSM(Dynamic Speaker Manangement) process buffer size */ -#define DSM_FRM_SZ 48 -#define DSM_FF_BUF_SZ (DSM_FRM_SZ * SMART_AMP_FF_MAX_CH_NUM) -#define DSM_FB_BUF_SZ (DSM_FRM_SZ * SMART_AMP_FB_MAX_CH_NUM) - #define SMART_AMP_FF_BUF_DB_SZ\ (SMART_AMP_FF_BUF_SZ * SMART_AMP_FF_MAX_CH_NUM) #define SMART_AMP_FB_BUF_DB_SZ\ (SMART_AMP_FB_BUF_SZ * SMART_AMP_FB_MAX_CH_NUM) -#define DSM_FF_BUF_DB_SZ (DSM_FF_BUF_SZ * SMART_AMP_FF_MAX_CH_NUM) -#define DSM_FB_BUF_DB_SZ (DSM_FB_BUF_SZ * SMART_AMP_FB_MAX_CH_NUM) - -/* DSM parameter table structure - * +--------------+-----------------+---------------------------------+ - * | ID (4 bytes) | VALUE (4 bytes) | 1st channel : | - * | | | 8 bytes per single parameter | - * +--------------+-----------------+---------------------------------+ - * | ... | ... | Repeat N times for N parameters | - * +--------------+-----------------+---------------------------------+ - * | ID (4 bytes) | VALUE (4 bytes) | 2nd channel : | - * | | | 8 bytes per single parameter | - * +--------------+-----------------+---------------------------------+ - * | ... | ... | Repeat N times for N parameters | - * +--------------+-----------------+---------------------------------+ - */ -enum dsm_param { - DSM_PARAM_ID = 0, - DSM_PARAM_VALUE, - DSM_PARAM_MAX -}; -#define DSM_SINGLE_PARAM_SZ (DSM_PARAM_MAX * SMART_AMP_FF_MAX_CH_NUM) +struct inner_model_ops; -union smart_amp_buf { - int16_t *buf16; - int32_t *buf32; +/* The common base for inner model data structs. Inner model should declare its + * model data struct while putting this base as the leading member of struct, e.g. + * struct solution_foo_mod_data { + * struct smart_amp_mod_data_base base; + * uint32_t foo_version; + * struct foo_parameter_set; + * ... + * }; + * + * Then implement mod_data_create() in its own C file, e.g. + * struct smart_amp_mod_data_base *mod_data_create(const struct comp_dev *dev) + * { + * struct solution_foo_mod_data *foo; + * foo = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*foo)); + * assert(foo); + * foo->base.dev = dev; + * foo->base.mod_ops = foo_ops; // declared somewhere as static const + * ... + * return &foo->base; + * } + */ +struct smart_amp_mod_data_base { + const struct comp_dev *dev; /* for logger tracing use only */ + const struct inner_model_ops *mod_ops; }; -struct smart_amp_ff_buf_struct_t { - int32_t *buf; - int avail; +/* The struct of memory buffer managed by generic layer. */ +struct smart_amp_buf { + void *data; + uint32_t size; }; -struct smart_amp_fb_buf_struct_t { - int32_t *buf; - int avail; - int rdy; +/* For memory allocation, generic layer plays the active role that queries the + * required memory size for inner model (then allocate and assign back) in + * some specific moments, i.e. once before and after model initialized. Inner + * model should consider buffers located and allocated onto 3 memory blocks in + * terms of usage: + * PRIVATE - allocated before model init - for libraries internal usage + * FRAME - allocated after model init - for audio frame buffer usage + * PARAM - allocated after model init - for parameter blob usage + */ +enum smart_amp_mod_memblk { + MOD_MEMBLK_PRIVATE = 0, + MOD_MEMBLK_FRAME, + MOD_MEMBLK_PARAM, + MOD_MEMBLK_MAX }; -struct smart_amp_buf_struct_t { - /* buffer : sof -> spk protection feed forward process */ - int32_t *frame_in; - /* buffer : sof <- spk protection feed forward process */ - int32_t *frame_out; - /* buffer : sof -> spk protection feedback process */ - int32_t *frame_iv; - /* buffer : feed forward process input */ - int32_t *input; - /* buffer : feed forward process output */ - int32_t *output; - /* buffer : feedback voltage */ - int32_t *voltage; - /* buffer : feedback current */ - int32_t *current; - /* buffer : feed forward variable length -> fixed length */ - struct smart_amp_ff_buf_struct_t ff; - /* buffer : feed forward variable length <- fixed length */ - struct smart_amp_ff_buf_struct_t ff_out; - /* buffer : feedback variable length -> fixed length */ - struct smart_amp_fb_buf_struct_t fb; +/* The intermediate audio data buffer in generic layer. */ +struct smart_amp_mod_stream { + struct smart_amp_buf buf; + uint32_t channels; + uint16_t frame_fmt; + union { + uint32_t consumed; /* for source (in frames) */ + uint32_t produced; /* for sink (in frames) */ + }; }; -struct param_buf_struct_t { - int id; - int value; -}; +/****************************************************************************** + * Generic functions: * + * The implementation is placed in smart_amp_generic.c * + ******************************************************************************/ -struct smart_amp_caldata { - uint32_t data_size; /* size of component's model data */ - void *data; /* model data pointer */ - uint32_t data_pos; /* data position for read/write */ -}; +typedef void (*smart_amp_src_func)(struct smart_amp_mod_stream *src_mod, + uint32_t frames, + const struct audio_stream __sparse_cache *src, + const int8_t *chan_map); -struct smart_amp_param_struct_t { - struct param_buf_struct_t param; /* variable to keep last parameter ID/value */ - struct smart_amp_caldata caldata; /* model data buffer */ - int pos; /* data position for read/write */ - int max_param; /* keep max number of DSM parameters */ -}; +typedef void (*smart_amp_sink_func)(const struct smart_amp_mod_stream *sink_mod, + uint32_t frames, + const struct audio_stream __sparse_cache *sink); -struct smart_amp_mod_struct_t { - struct smart_amp_buf_struct_t buf; - void *dsmhandle; - /* DSM variables for the initialization */ - int delayedsamples[SMART_AMP_FF_MAX_CH_NUM << 2]; - int circularbuffersize[SMART_AMP_FF_MAX_CH_NUM << 2]; - /* Number of samples of feed forward and feedback frame */ - int ff_fr_sz_samples; - int fb_fr_sz_samples; - int channelmask; - /* Number of channels of DSM */ - int nchannels; - /* Number of samples of feed forward channel */ - int ifsamples; - /* Number of samples of feedback channel */ - int ibsamples; - /* Number of processed samples */ - int ofsamples; - /* Channel bit dempth */ - int bitwidth; - struct smart_amp_param_struct_t param; +struct smart_amp_func_map { + uint16_t comp_fmt; + uint16_t mod_fmt; + smart_amp_src_func src_func; + smart_amp_sink_func sink_func; }; -typedef void (*smart_amp_func)(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, - const struct audio_stream __sparse_cache *feedback, - uint32_t frames); -struct smart_amp_func_map { - uint16_t frame_fmt; - smart_amp_func func; +extern const struct smart_amp_func_map src_sink_func_map[]; + +smart_amp_src_func smart_amp_get_src_func(uint16_t comp_fmt, uint16_t mod_fmt); +smart_amp_sink_func smart_amp_get_sink_func(uint16_t comp_fmt, uint16_t mod_fmt); + +/****************************************************************************** + * Inner model operations (mod ops): * + * Model implementations are mutual exclusive (separated by Kconfig). It * + * must be only one solution applicable per build. The solution-specific * + * implementation is placed in its own C file smart_amp_${SOLUTION}.c * + ******************************************************************************/ + +/** + * Creates the self-declared model data struct. + * Refer to "struct smart_amp_mod_data_base" for details of declaration. + * Args: + * dev - the comp_dev object for logger tracing use only. + * Returns: + * The pointer of "smart_amp_mod_data_base" which is the leading member in + * the created model data struct. + */ +struct smart_amp_mod_data_base *mod_data_create(const struct comp_dev *dev); + +/* All ops are mandatory. */ +struct inner_model_ops { + /** + * Initializes model. + * It will be called on comp_ops.create() by generic layer. + * Args: + * mod - the pointer of model data struct object. + * Returns: + * 0 or negative error code. + */ + int (*init)(struct smart_amp_mod_data_base *mod); + + /** + * Returns the required bytesize for the specific memblk. + * It will be called on comp_ops.create() by generic layer, before or after + * mod_ops.init() according to the memblk usage. + * Args: + * mod - the pointer of model data struct object. + * blk - the memblk usage type. + * Returns: + * The bytesize or negative error code. + */ + int (*query_memblk_size)(struct smart_amp_mod_data_base *mod, + enum smart_amp_mod_memblk blk); + + /** + * Sets the allocated memblk info. + * It should be called in sequence after mod_ops.query_memblk_size(). + * Args: + * mod - the pointer of model data struct object. + * blk - the memblk usage type. + * buf - the pointer of smart_amp_buf object including allocated memory. + * Returns: + * 0 or negative error code. + */ + int (*set_memblk)(struct smart_amp_mod_data_base *mod, + enum smart_amp_mod_memblk blk, + struct smart_amp_buf *buf); + + /** + * Returns the list of supported frame formats. + * It will be called on comp_ops.prepare() by generic layer. + * + * Inner model should report all supported formats in the list at once. + * Generic layer will resolve the applicable format according to this list and + * the formats requested from external source/sink stream buffers. If it turns + * out to be no format applicable, generic layer will report errors which will + * force the early-termination of the starting process for the whole pipeline. + * Args: + * mod - the pointer of model data struct object. + * mod_fmts - the pointer for returning the supported format list. + * Format values should be aligned to "enum sof_ipc_frame" and + * put in ascending order. + * num_mod_fmts - the pointer for returning the length of mod_fmts. + * Returns: + * 0 or negative error code. + */ + int (*get_supported_fmts)(struct smart_amp_mod_data_base *mod, + const uint16_t **mod_fmts, int *num_mod_fmts); + + /** + * Sets the frame format after resolved. + * It will be called on comp_ops.prepare() by generic layer, in sequence after + * mod_ops.get_supported_fmts() if the format is resolvable. + * + * Inner model should honor the received format on processing. The FF and FB + * frames (if available) will be put to the input buffers in the same format. + * It will be the last function called before audio stream starts processing. + * needed, inner model should execute the preparing tasks as soon as it is + * called. + * Args: + * mod - the pointer of model data struct object. + * mod_fmt - the frame format to be applied.. + * Returns: + * 0 or negative error code. + */ + int (*set_fmt)(struct smart_amp_mod_data_base *mod, uint16_t mod_fmt); + + /** + * Runs the feed-forward process. + * Args: + * mod - the pointer of model data struct object. + * frames - the number of frames to be processed. + * in - the pointer of input stream buffer object. Inner model should set + * "consumed" to the number of conusmed frames. + * out - the pointer of output stream buffer object. Inner model should set + * "produced" to the number of produced frames. + * Returns: + * 0 or negative error code. + */ + int (*ff_proc)(struct smart_amp_mod_data_base *mod, + uint32_t frames, + struct smart_amp_mod_stream *in, + struct smart_amp_mod_stream *out); + + /** + * Runs the feedback process. + * Args: + * mod - the pointer of model data struct object. + * frames - the number of frames to be processed. + * in - the pointer of input stream buffer object. Inner model should set + * "consumed" to the number of conusmed frames. + * Returns: + * 0 or negative error code. + */ + int (*fb_proc)(struct smart_amp_mod_data_base *mod, + uint32_t frames, + struct smart_amp_mod_stream *in); + + /** + * Gets config data from model. + * Args: + * mod - the pointer of model data struct object. + * cdata - the pointer of sof_ipc_ctrl_data object. + * size - the maximal size for config data to read. + * Returns: + * 0 or negative error code. + */ + int (*get_config)(struct smart_amp_mod_data_base *mod, + struct sof_ipc_ctrl_data *cdata, uint32_t size); + + /** + * Sets config data to model. + * Args: + * mod - the pointer of model data struct object. + * cdata - the pointer of sof_ipc_ctrl_data object. + * Returns: + * 0 or negative error code. + */ + int (*set_config)(struct smart_amp_mod_data_base *mod, + struct sof_ipc_ctrl_data *cdata); + + /** + * Resets model. + * It will be called on comp_ops.reset() by generic layer. + * Args: + * mod - the pointer of model data struct object. + * Returns: + * 0 or negative error code. + */ + int (*reset)(struct smart_amp_mod_data_base *mod); }; -/* Component initialization */ -int smart_amp_init(struct smart_amp_mod_struct_t *hspk, struct comp_dev *dev); -/* Component memory flush */ -int smart_amp_flush(struct smart_amp_mod_struct_t *hspk, struct comp_dev *dev); -/* Feed forward processing function */ -int smart_amp_ff_copy(struct comp_dev *dev, uint32_t frames, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, int8_t *chan_map, - struct smart_amp_mod_struct_t *hspk, - uint32_t num_ch_in, uint32_t num_ch_out); -/* Feedback processing function */ -int smart_amp_fb_copy(struct comp_dev *dev, uint32_t frames, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, int8_t *chan_map, - struct smart_amp_mod_struct_t *hspk, - uint32_t num_ch); -/* memory usage calculation for the component */ -int smart_amp_get_memory_size(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev); -/* supported audio format check */ -int smart_amp_check_audio_fmt(int sample_rate, int ch_num); - -/* this function return number of parameters supported */ -int smart_amp_get_num_param(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev); -/* this function update whole parameter table */ -int smart_amp_get_all_param(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev); -/* parameter read function */ -int maxim_dsm_get_param(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev, - struct sof_ipc_ctrl_data *cdata, int size); -/* parameter write function */ -int maxim_dsm_set_param(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev, - struct sof_ipc_ctrl_data *cdata); -/* parameter restoration */ -int maxim_dsm_restore_param(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev); -/* parameter forced read, ignore cache */ -int maxim_dsm_get_param_forced(struct smart_amp_mod_struct_t *hspk, - struct comp_dev *dev); #endif diff --git a/src/include/sof/audio/source_api.h b/src/include/sof/audio/source_api.h index bfbcf530a81b..70b3ce38c909 100644 --- a/src/include/sof/audio/source_api.h +++ b/src/include/sof/audio/source_api.h @@ -54,13 +54,13 @@ struct sof_ipc_stream_params; * Retrieves size of available data (in bytes) * return number of bytes that are available for immediate use */ -size_t source_get_data_available(struct sof_source __sparse_cache *source); +size_t source_get_data_available(struct sof_source *source); /** * Retrieves size of available data (in frames) * return number of bytes that are available for immediate use */ -size_t source_get_data_frames_available(struct sof_source __sparse_cache *source); +size_t source_get_data_frames_available(struct sof_source *source); /** * Retrieves a fragment of circular data to be used by the caller (to read) @@ -93,8 +93,8 @@ size_t source_get_data_frames_available(struct sof_source __sparse_cache *source * * @retval -ENODATA if req_size is bigger than available data */ -int source_get_data(struct sof_source __sparse_cache *source, size_t req_size, - void **data_ptr, void **buffer_start, size_t *buffer_size); +int source_get_data(struct sof_source *source, size_t req_size, + void const **data_ptr, void const **buffer_start, size_t *buffer_size); /** * Releases fragment previously obtained by source_get_data() @@ -110,38 +110,38 @@ int source_get_data(struct sof_source __sparse_cache *source, size_t req_size, * * @return proper error code (0 on success) */ -int source_release_data(struct sof_source __sparse_cache *source, size_t free_size); +int source_release_data(struct sof_source *source, size_t free_size); /** * Get total number of bytes processed by the source (meaning - freed by source_release_data()) */ -size_t source_get_num_of_processed_bytes(struct sof_source __sparse_cache *source); +size_t source_get_num_of_processed_bytes(struct sof_source *source); /** * sets counter of total number of bytes processed to zero */ -void source_reset_num_of_processed_bytes(struct sof_source __sparse_cache *source); +void source_reset_num_of_processed_bytes(struct sof_source *source); /** get size of a single audio frame (in bytes) */ -size_t source_get_frame_bytes(struct sof_source __sparse_cache *source); +size_t source_get_frame_bytes(struct sof_source *source); /** set of functions for retrieve audio parameters */ -enum sof_ipc_frame source_get_frm_fmt(struct sof_source __sparse_cache *source); -enum sof_ipc_frame source_get_valid_fmt(struct sof_source __sparse_cache *source); -unsigned int source_get_rate(struct sof_source __sparse_cache *source); -unsigned int source_get_channels(struct sof_source __sparse_cache *source); -uint32_t source_get_buffer_fmt(struct sof_source __sparse_cache *source); -bool source_get_underrun(struct sof_source __sparse_cache *source); +enum sof_ipc_frame source_get_frm_fmt(struct sof_source *source); +enum sof_ipc_frame source_get_valid_fmt(struct sof_source *source); +unsigned int source_get_rate(struct sof_source *source); +unsigned int source_get_channels(struct sof_source *source); +uint32_t source_get_buffer_fmt(struct sof_source *source); +bool source_get_underrun(struct sof_source *source); /** set of functions for setting audio parameters */ -int source_set_valid_fmt(struct sof_source __sparse_cache *source, +int source_set_valid_fmt(struct sof_source *source, enum sof_ipc_frame valid_sample_fmt); -int source_set_rate(struct sof_source __sparse_cache *source, unsigned int rate); -int source_set_channels(struct sof_source __sparse_cache *source, unsigned int channels); -int source_set_underrun(struct sof_source __sparse_cache *source, bool underrun_permitted); -int source_set_buffer_fmt(struct sof_source __sparse_cache *source, uint32_t buffer_fmt); -void source_set_ibs(struct sof_source __sparse_cache *source, size_t ibs); -size_t source_get_ibs(struct sof_source __sparse_cache *source); +int source_set_rate(struct sof_source *source, unsigned int rate); +int source_set_channels(struct sof_source *source, unsigned int channels); +int source_set_underrun(struct sof_source *source, bool underrun_permitted); +int source_set_buffer_fmt(struct sof_source *source, uint32_t buffer_fmt); +void source_set_min_available(struct sof_source *source, size_t min_available); +size_t source_get_min_available(struct sof_source *source); /** * initial set of audio parameters, provided in sof_ipc_stream_params @@ -151,7 +151,7 @@ size_t source_get_ibs(struct sof_source __sparse_cache *source); * @param force_update tells the implementation that the params should override actual settings * @return 0 if success */ -int source_set_params(struct sof_source __sparse_cache *source, +int source_set_params(struct sof_source *source, struct sof_ipc_stream_params *params, bool force_update); /** @@ -169,7 +169,7 @@ int source_set_params(struct sof_source __sparse_cache *source, * * @return 0 if success */ -int source_set_alignment_constants(struct sof_source __sparse_cache *source, +int source_set_alignment_constants(struct sof_source *source, const uint32_t byte_align, const uint32_t frame_align_req); diff --git a/src/include/sof/audio/source_api_implementation.h b/src/include/sof/audio/source_api_implementation.h index c75330cde019..606141c92dfb 100644 --- a/src/include/sof/audio/source_api_implementation.h +++ b/src/include/sof/audio/source_api_implementation.h @@ -27,18 +27,18 @@ struct source_ops { /** * see comment of source_get_data_available() */ - size_t (*get_data_available)(struct sof_source __sparse_cache *source); + size_t (*get_data_available)(struct sof_source *source); /** * see comment of source_get_data_available() */ - int (*get_data)(struct sof_source __sparse_cache *source, size_t req_size, - void **data_ptr, void **buffer_start, size_t *buffer_size); + int (*get_data)(struct sof_source *source, size_t req_size, + void const **data_ptr, void const **buffer_start, size_t *buffer_size); /** * see comment of source_release_data() */ - int (*release_data)(struct sof_source __sparse_cache *source, size_t free_size); + int (*release_data)(struct sof_source *source, size_t free_size); /** * OPTIONAL: Notification to the source implementation about changes in audio format @@ -49,20 +49,20 @@ struct source_ops { * * @retval 0 if success, negative if new parameteres are not supported */ - int (*on_audio_format_set)(struct sof_source __sparse_cache *source); + int (*on_audio_format_set)(struct sof_source *source); /** * OPTIONAL * see source_set_params comments */ - int (*audio_set_ipc_params)(struct sof_source __sparse_cache *source, + int (*audio_set_ipc_params)(struct sof_source *source, struct sof_ipc_stream_params *params, bool force_update); /** * OPTIONAL * see comment for source_set_alignment_constants */ - int (*set_alignment_constants)(struct sof_source __sparse_cache *source, + int (*set_alignment_constants)(struct sof_source *source, const uint32_t byte_align, const uint32_t frame_align_req); }; @@ -72,7 +72,11 @@ struct sof_source { const struct source_ops *ops; size_t requested_read_frag_size; /** keeps size of data obtained by get_data() */ size_t num_of_bytes_processed; /** processed bytes counter */ - size_t ibs; /** input buffer size as declared in module bind IPC */ + size_t min_available; /** minimum data available required by the module using + * source + * it is module's IBS as declared in module bind IPC + */ + struct sof_audio_stream_params *audio_stream_params; }; @@ -86,7 +90,7 @@ struct sof_source { * the implementation must ensure coherent access to the parameteres * in case of i.e. cross core shared queue, it must be located in non-cached memory */ -void source_init(struct sof_source __sparse_cache *source, const struct source_ops *ops, +void source_init(struct sof_source *source, const struct source_ops *ops, struct sof_audio_stream_params *audio_stream_params); #endif /* __SOF_SOURCE_API_IMPLEMENTATION_H__ */ diff --git a/src/include/sof/audio/src/src.h b/src/include/sof/audio/src/src.h deleted file mode 100644 index 6fa936fc74eb..000000000000 --- a/src/include/sof/audio/src/src.h +++ /dev/null @@ -1,122 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2017 Intel Corporation. All rights reserved. - * - * Author: Seppo Ingalsuo - */ - -#ifndef __SOF_AUDIO_SRC_SRC_H__ -#define __SOF_AUDIO_SRC_SRC_H__ - -#include -#include - -struct src_param { - int fir_s1; - int fir_s2; - int out_s1; - int out_s2; - int sbuf_length; - int src_multich; - int total; - int blk_in; - int blk_out; - int stage1_times; - int stage2_times; - int idx_in; - int idx_out; - int nch; -}; - -struct src_stage { - const int idm; - const int odm; - const int num_of_subfilters; - const int subfilter_length; - const int filter_length; - const int blk_in; - const int blk_out; - const int halfband; - const int shift; - const void *coefs; /* Can be int16_t or int32_t depending on config */ -}; - -struct src_state { - int fir_delay_size; /* samples */ - int out_delay_size; /* samples */ - int32_t *fir_delay; - int32_t *out_delay; - int32_t *fir_wp; - int32_t *out_rp; -}; - -struct polyphase_src { - int number_of_stages; - struct src_stage *stage1; - struct src_stage *stage2; - struct src_state state1; - struct src_state state2; -}; - -struct src_stage_prm { - int nch; - int times; - void *x_rptr; - void *x_end_addr; - size_t x_size; - void *y_wptr; - void *y_addr; - void *y_end_addr; - size_t y_size; - int shift; - struct src_state *state; - struct src_stage *stage; -}; - -static inline void src_inc_wrap(int32_t **ptr, int32_t *end, size_t size) -{ - if (*ptr >= end) - *ptr = (int32_t *)((uint8_t *)*ptr - size); -} - -static inline void src_dec_wrap(int32_t **ptr, int32_t *addr, size_t size) -{ - if (*ptr < addr) - *ptr = (int32_t *)((uint8_t *)*ptr + size); -} - -#if CONFIG_FORMAT_S16LE -static inline void src_inc_wrap_s16(int16_t **ptr, int16_t *end, size_t size) -{ - if (*ptr >= end) - *ptr = (int16_t *)((uint8_t *)*ptr - size); -} - -static inline void src_dec_wrap_s16(int16_t **ptr, int16_t *addr, size_t size) -{ - if (*ptr < addr) - *ptr = (int16_t *)((uint8_t *)*ptr + size); -} -#endif /* CONFIG_FORMAT_S16LE */ - -void src_polyphase_reset(struct polyphase_src *src); - -int src_polyphase_init(struct polyphase_src *src, struct src_param *p, - int32_t *delay_lines_start); - -int src_polyphase(struct polyphase_src *src, int32_t x[], int32_t y[], - int n_in); - -#if CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE -void src_polyphase_stage_cir(struct src_stage_prm *s); -#endif /* CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE */ - -#if CONFIG_FORMAT_S16LE -void src_polyphase_stage_cir_s16(struct src_stage_prm *s); -#endif /* CONFIG_FORMAT_S16LE */ - -int32_t src_input_rates(void); - -int32_t src_output_rates(void); - -#endif /* __SOF_AUDIO_SRC_SRC_H__ */ diff --git a/src/include/sof/audio/tdfb/tdfb_comp.h b/src/include/sof/audio/tdfb/tdfb_comp.h index ce48760e22a6..bd229c80f211 100644 --- a/src/include/sof/audio/tdfb/tdfb_comp.h +++ b/src/include/sof/audio/tdfb/tdfb_comp.h @@ -17,6 +17,10 @@ #include #include +#if CONFIG_IPC_MAJOR_4 +#include +#endif + /* Select optimized code variant when xt-xcc compiler is used */ #if defined __XCC__ #include @@ -110,6 +114,14 @@ struct tdfb_comp_data { int frames); }; +#if CONFIG_IPC_MAJOR_4 +struct tdfb_notification_payload { + struct sof_ipc4_notify_module_data module_data; + struct sof_ipc4_control_msg_payload control_msg; + struct sof_ipc4_ctrl_value_chan control_value; /* One channel value */ +}; +#endif + #if CONFIG_FORMAT_S16LE void tdfb_fir_s16(struct tdfb_comp_data *cd, struct input_stream_buffer *bsource, diff --git a/src/include/sof/coherent.h b/src/include/sof/coherent.h index 4ca5120cfee9..8e06fb466a66 100644 --- a/src/include/sof/coherent.h +++ b/src/include/sof/coherent.h @@ -80,9 +80,23 @@ struct coherent { /* debug sharing amongst cores */ #ifdef COHERENT_CHECK_NONSHARED_CORES + +#define CORE_CHECK_STRUCT_FIELD uint32_t __core; bool __is_shared +#define CORE_CHECK_STRUCT_INIT(_c, is_shared) { (_c)->__core = cpu_get_id(); \ + (_c)->__is_shared = is_shared; } +#define CORE_CHECK_STRUCT(_c) { assert(!!(_c)->__is_shared == !!is_uncached(_c)); \ + assert(cpu_get_id() == (_c)->__core || (_c)->__is_shared); } + #define CHECK_COHERENT_CORE(_c) assert((_c)->core == cpu_get_id()) + #else + +#define CORE_CHECK_STRUCT_FIELD +#define CORE_CHECK_STRUCT_INIT(_c, is_shared) +#define CORE_CHECK_STRUCT(_c) + #define CHECK_COHERENT_CORE(_c) + #endif #ifdef __ZEPHYR__ diff --git a/src/include/sof/drivers/micfil.h b/src/include/sof/drivers/micfil.h new file mode 100644 index 000000000000..5d6828102c97 --- /dev/null +++ b/src/include/sof/drivers/micfil.h @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright 2023 NXP + * + * Author: Daniel Baluta + */ + +#ifndef __SOF_DRIVERS_MICFIL_H__ +#define __SOF_DRIVERS_MICFIL_H__ + +#include +#include +#include +#include +#include +#include + +extern const struct dai_driver micfil_driver; + +/* MICFIL private data */ +struct micfil_pdata { + int quality; + struct sof_ipc_dai_config config; + struct sof_ipc_dai_micfil_params params; +}; + +/* MICFIL Register Map */ +#define REG_MICFIL_CTRL1 0x00 +#define REG_MICFIL_CTRL2 0x04 +#define REG_MICFIL_STAT 0x08 +#define REG_MICFIL_FIFO_CTRL 0x10 +#define REG_MICFIL_FIFO_STAT 0x14 +#define REG_MICFIL_DATACH0 0x24 +#define REG_MICFIL_DATACH1 0x28 +#define REG_MICFIL_DATACH2 0x2C +#define REG_MICFIL_DATACH3 0x30 +#define REG_MICFIL_DATACH4 0x34 +#define REG_MICFIL_DATACH5 0x38 +#define REG_MICFIL_DATACH6 0x3C +#define REG_MICFIL_DATACH7 0x40 +#define REG_MICFIL_DC_CTRL 0x64 +#define REG_MICFIL_OUT_CTRL 0x74 +#define REG_MICFIL_OUT_STAT 0x7C +#define REG_MICFIL_VAD0_CTRL1 0x90 +#define REG_MICFIL_VAD0_CTRL2 0x94 + +#define REG_MICFIL_VAD0_STAT 0x98 +#define REG_MICFIL_VAD0_SCONFIG 0x9C +#define REG_MICFIL_VAD0_NCONFIG 0xA0 +#define REG_MICFIL_VAD0_NDATA 0xA4 +#define REG_MICFIL_VAD0_ZCD 0xA8 + +/* MICFIL Control Register 1 -- REG_MICFILL_CTRL1 0x00 */ +#define MICFIL_CTRL1_MDIS BIT(31) +#define MICFIL_CTRL1_DOZEN BIT(30) +#define MICFIL_CTRL1_PDMIEN BIT(29) +#define MICFIL_CTRL1_DBG BIT(28) +#define MICFIL_CTRL1_SRES BIT(27) +#define MICFIL_CTRL1_DBGE BIT(26) +#define MICFIL_CTRL1_CHNEN MASK(7, 0) + +#define MICFIL_CTRL1_DISEL_DISABLE 0 +#define MICFIL_CTRL1_DISEL_DMA 1 +#define MICFIL_CTRL1_DISEL_IRQ 2 +#define MICFIL_CTRL1_DISEL_BITS(x) SET_BITS(25, 24, x) +#define MICFIL_CTRL1_DISEL MASK(25, 24) +#define MICFIL_CTRL1_ERREN BIT(23) +#define MICFIL_CTRL1_CHEN(ch) BIT(ch) + +/* MICFIL Control Register 2 -- REG_MICFILL_CTRL2 0x04 */ +#define MICFIL_CTRL2_QSEL_SHIFT 25 +#define MICFIL_CTRL2_QSEL MASK(27, 25) +#define MICFIL_CTRL2_QSEL_BITS(x) SET_BITS(27, 25, x) +#define MICFIL_QSEL_MEDIUM_QUALITY 0 +#define MICFIL_QSEL_HIGH_QUALITY 1 +#define MICFIL_QSEL_LOW_QUALITY 7 +#define MICFIL_QSEL_VLOW0_QUALITY 6 +#define MICFIL_QSEL_VLOW1_QUALITY 5 +#define MICFIL_QSEL_VLOW2_QUALITY 4 + +#define MICFIL_CTRL2_CICOSR MASK(19, 16) +#define MICFIL_CTRL2_CICOSR_SHIFT 16 +#define MICFIL_CTRL2_CICOSR_BITS(x) SET_BITS(19, 16, x) +#define MICFIL_CTRL2_CLKDIV MASK(7, 0) +#define MICFIL_CTRL2_CLKDIV_BITS(x) SET_BITS(7, 0, x) + +/* MICFIL Status Register -- REG_MICFIL_STAT 0x08 */ +#define MICFIL_STAT_BSY_FIL BIT(31) +#define MICFIL_STAT_FIR_RDY BIT(30) +#define MICFIL_STAT_LOWFREQF BIT(29) +#define MICFIL_STAT_CHXF(ch) BIT(ch) + +/* MICFIL FIFO Control Register -- REG_MICFIL_FIFO_CTRL 0x10 */ +#define MICFIL_FIFO_CTRL_FIFOWMK MASK(2, 0) +#define MICFIL_FIFO_CTRL_FIFOWMK_BITS(x) SET_BITS(2, 0, x) + +/* MICFIL FIFO Status Register -- REG_MICFIL_FIFO_STAT 0x14 */ +#define MICFIL_FIFO_STAT_FIFOX_OVER(ch) BIT(ch) +#define MICFIL_FIFO_STAT_FIFOX_UNDER(ch) BIT((ch) + 8) + +/* MICFIL DC Remover Control Register -- REG_MICFIL_DC_CTRL */ +#define MICFIL_DC_CTRL_CONFIG MASK(15, 0) +#define MICFIL_DC_CHX_SHIFT(ch) ((ch) << 1) +#define MICFIL_DC_CHX(ch) MASK((((ch) << 1) + 1), ((ch) << 1)) +#define MICFIL_DC_CUTOFF_21HZ 0 +#define MICFIL_DC_CUTOFF_83HZ 1 +#define MICFIL_DC_CUTOFF_152Hz 2 +#define MICFIL_DC_BYPASS 3 + +/* MICFIL HWVAD0 Control 1 Register -- REG_MICFIL_VAD0_CTRL1*/ +#define MICFIL_VAD0_CTRL1_CHSEL MASK(26, 24) +#define MICFIL_VAD0_CTRL1_CICOSR MASK(19, 16) +#define MICFIL_VAD0_CTRL1_INITT MASK(12, 8) +#define MICFIL_VAD0_CTRL1_ST10 BIT(4) +#define MICFIL_VAD0_CTRL1_ERIE BIT(3) +#define MICFIL_VAD0_CTRL1_IE BIT(2) +#define MICFIL_VAD0_CTRL1_RST BIT(1) +#define MICFIL_VAD0_CTRL1_EN BIT(0) + +/* MICFIL HWVAD0 Control 2 Register -- REG_MICFIL_VAD0_CTRL2*/ +#define MICFIL_VAD0_CTRL2_FRENDIS BIT(31) +#define MICFIL_VAD0_CTRL2_PREFEN BIT(30) +#define MICFIL_VAD0_CTRL2_FOUTDIS BIT(28) +#define MICFIL_VAD0_CTRL2_FRAMET MASK(21, 16) +#define MICFIL_VAD0_CTRL2_INPGAIN MASK(11, 8) +#define MICFIL_VAD0_CTRL2_HPF MASK(1, 0) + +/* MICFIL HWVAD0 Signal CONFIG Register -- REG_MICFIL_VAD0_SCONFIG */ +#define MICFIL_VAD0_SCONFIG_SFILEN BIT(31) +#define MICFIL_VAD0_SCONFIG_SMAXEN BIT(30) +#define MICFIL_VAD0_SCONFIG_SGAIN MASK(3, 0) + +/* MICFIL HWVAD0 Noise CONFIG Register -- REG_MICFIL_VAD0_NCONFIG */ +#define MICFIL_VAD0_NCONFIG_NFILAUT BIT(31) +#define MICFIL_VAD0_NCONFIG_NMINEN BIT(30) +#define MICFIL_VAD0_NCONFIG_NDECEN BIT(29) +#define MICFIL_VAD0_NCONFIG_NOREN BIT(28) +#define MICFIL_VAD0_NCONFIG_NFILADJ MASK(12, 8) +#define MICFIL_VAD0_NCONFIG_NGAIN MASK(3, 0) + +/* MICFIL HWVAD0 Zero-Crossing Detector - REG_MICFIL_VAD0_ZCD */ +#define MICFIL_VAD0_ZCD_ZCDTH MASK(25, 16) +#define MICFIL_VAD0_ZCD_ZCDADJ MASK(11, 8) +#define MICFIL_VAD0_ZCD_ZCDAND BIT(4) +#define MICFIL_VAD0_ZCD_ZCDAUT BIT(2) +#define MICFIL_VAD0_ZCD_ZCDEN BIT(0) + +/* MICFIL HWVAD0 Status Register - REG_MICFIL_VAD0_STAT */ +#define MICFIL_VAD0_STAT_INITF BIT(31) +#define MICFIL_VAD0_STAT_INSATF BIT(16) +#define MICFIL_VAD0_STAT_EF BIT(15) +#define MICFIL_VAD0_STAT_IF BIT(0) + +/* MICFIL Output Control Register */ +#define MICFIL_OUTGAIN_CHX_SHIFT(v) (4 * (v)) + +/* Constants */ +#define MICFIL_OUTPUT_CHANNELS 8 +#define MICFIL_FIFO_NUM 8 + +#define FIFO_PTRWID 3 +#define FIFO_LEN BIT(FIFO_PTRWID) + +#define MICFIL_IRQ_LINES 4 +#define MICFIL_MAX_RETRY 25 +#define MICFIL_SLEEP_MIN 90000 /* in us */ +#define MICFIL_SLEEP_MAX 100000 /* in us */ +#define MICFIL_DMA_MAXBURST_RX 6 + +/* HWVAD Constants */ +#define MICFIL_HWVAD_ENVELOPE_MODE 0 +#define MICFIL_HWVAD_ENERGY_MODE 1 + +#endif /* __SOF_DRIVERS_MICFIL_H__ */ diff --git a/src/include/sof/drivers/sdma.h b/src/include/sof/drivers/sdma.h index d3c9668157a8..62f1f1c4101d 100644 --- a/src/include/sof/drivers/sdma.h +++ b/src/include/sof/drivers/sdma.h @@ -89,6 +89,15 @@ #define SDMA_DONE0_CONFIG 0x1000 #define SDMA_DONE1_CONFIG 0x1004 +#define SDMA_DONE0_CONFIG_DONE_SEL BIT(7) +#define SDMA_DONE0_CONFIG_DONE_DIS BIT(6) + +#define SDMA_WATERMARK_LEVEL_N_FIFOS(x) SET_BITS(15, 12, x) +#define SDMA_WATERMARK_LEVEL_OFF_FIFOS(x) SET_BITS(19, 16, x) +#define SDMA_WATERMARK_LEVEL_WORDS_PER_FIFO(x) SET_BITS(31, 28, x) +#define SDMA_WATERMARK_LEVEL_SW_DONE BIT(23) +#define SDMA_WATERMARK_LEVEL_SW_DONE_SEL_OFF 24 + /* Buffer descriptor first word */ /* Count: Data buffer size, in words */ #define SDMA_BD_COUNT_MASK MASK(15, 0) @@ -143,6 +152,8 @@ /* SHP2MCU is host to DAI, faster but only works with SDRAM */ #define SDMA_CHAN_TYPE_SHP2MCU 3 #define SDMA_CHAN_TYPE_MCU2SHP 4 +/* used for multi-fifo script */ +#define SDMA_CHAN_TYPE_SAI2MCU 5 /* TODO check and move these to platform data */ #define SDMA_SCRIPT_AP2AP_OFF 644 @@ -150,9 +161,186 @@ #define SDMA_SCRIPT_MCU2AP_OFF 749 #define SDMA_SCRIPT_SHP2MCU_OFF 893 #define SDMA_SCRIPT_MCU2SHP_OFF 962 +#define SDMA_SCRIPT_SAI2MCU_OFF 6710 + +#if CONFIG_HAVE_SDMA_FIRMWARE + +/* + * From "sdma_script_code_imx7d_4_5.h" + */ + +/* SDMA RAM image start address and size */ +#define RAM_CODE_START_ADDR 6144 +#define RAM_CODE_SIZE 1315 -#ifdef CONFIG_SDMA_SCRIPT_CODE -#include "sdma_script_code_imx7d_4_5.h" +/* buffer that holds the SDMA RAM image */ +static const short sdma_code[] = { +0xc1e5, 0x57db, 0x52f3, 0x6a01, 0x52fb, 0x6ad3, 0x52fb, 0x1a1c, +0x6ac3, 0x62e8, 0x0211, 0x3aff, 0x0830, 0x02d0, 0x7c3f, 0x008f, +0x003f, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5deb, 0x0478, 0x7d03, +0x0479, 0x7d1c, 0x7c20, 0x0479, 0x7c15, 0x56ee, 0x0660, 0x7d05, +0x6509, 0x7e33, 0x620a, 0x7e31, 0x9829, 0x620a, 0x7e2e, 0x6509, +0x7e2c, 0x0512, 0x0512, 0x02ad, 0x6ac8, 0x7f27, 0x2003, 0x4800, +0x7ced, 0x9841, 0x7802, 0x6209, 0x6ac8, 0x9840, 0x0015, 0x7802, +0x620a, 0x6ac8, 0x9840, 0x0015, 0x0015, 0x7802, 0x620b, 0x6ac8, +0x7c14, 0x6ddf, 0x7f12, 0x077f, 0x7d09, 0x52fb, 0x1a04, 0x6ac3, +0x6ad3, 0x62c8, 0x2a04, 0x6ac8, 0x52fb, 0x6ad3, 0x0000, 0x55eb, +0x4d00, 0x7d07, 0xc1fc, 0x57db, 0x9806, 0x0007, 0x68cc, 0x680c, +0xc215, 0xc20c, 0x9801, 0xc1d9, 0xc1e5, 0x57db, 0x52f3, 0x6a01, +0x080f, 0x0011, 0x18ff, 0x00bf, 0x5ce3, 0x00d5, 0x7d01, 0x008d, +0x05a0, 0x5deb, 0x56fb, 0x0478, 0x7d03, 0x0479, 0x7d28, 0x7c33, +0x0479, 0x7c1a, 0x0b70, 0x0311, 0x53eb, 0x0360, 0x7d05, 0x6509, +0x7e5f, 0x620a, 0x7e5d, 0x9880, 0x620a, 0x7e5a, 0x6509, 0x7e58, +0x0512, 0x0512, 0x02ad, 0x5a06, 0x7f53, 0x2003, 0x4800, 0x7ced, +0x0b70, 0x0311, 0x5313, 0x98b0, 0xd8c8, 0x6209, 0x5a06, 0x069c, +0x2701, 0x2001, 0x4f00, 0x7cf9, 0x4800, 0x7cf6, 0x98af, 0x0015, +0xd8c8, 0x620a, 0x5a06, 0x069c, 0x2701, 0x2001, 0x4f00, 0x7cf9, +0x4800, 0x7cf6, 0x98af, 0x0015, 0x0015, 0xd8c8, 0x620b, 0x5a06, +0x069c, 0x2701, 0x2001, 0x4f00, 0x7cf9, 0x4800, 0x7cf6, 0x7c28, +0x57db, 0x0777, 0x7c0c, 0x0710, 0x3f0f, 0x0717, 0x0717, 0x0e70, +0x0611, 0x0c70, 0x0411, 0x069c, 0x069f, 0x0c01, 0x5c06, 0x0000, +0x54e3, 0x57db, 0x55eb, 0x4d00, 0x7d16, 0xc1fc, 0x57db, 0x9860, +0x56fb, 0x57db, 0x048f, 0x0711, 0x3ff0, 0x0715, 0x0715, 0x0715, +0x0715, 0x0410, 0x0411, 0x3c0f, 0x1c01, 0x0417, 0x0417, 0x0006, +0x0007, 0x680c, 0xc215, 0xc20c, 0x985d, 0xc1d9, 0xc1e5, 0x57db, +0x5fe3, 0x57e3, 0x52f3, 0x6a21, 0x008f, 0x00d5, 0x7d01, 0x008d, +0x05a0, 0x5deb, 0x56fb, 0x0478, 0x7d03, 0x0479, 0x7d2a, 0x7c31, +0x0479, 0x7c20, 0x0b70, 0x0311, 0x53eb, 0x0f00, 0x0360, 0x7d05, +0x6509, 0x7e37, 0x620a, 0x7e35, 0x9901, 0x620a, 0x7e32, 0x6509, +0x7e30, 0x0512, 0x0512, 0x02ad, 0x0760, 0x7c02, 0x5a06, 0x9909, +0x5a26, 0x7f27, 0x1f01, 0x2003, 0x4800, 0x7ce8, 0x0b70, 0x0311, +0x5313, 0x992a, 0x0015, 0x7804, 0x6209, 0x5a06, 0x6209, 0x5a26, +0x9929, 0x0015, 0x0015, 0x7804, 0x620a, 0x5a06, 0x620a, 0x5a26, +0x9929, 0x0015, 0x0015, 0x0015, 0x7804, 0x620b, 0x5a06, 0x620b, +0x5a26, 0x7c07, 0x0000, 0x55eb, 0x4d00, 0x7d06, 0xc1fc, 0x57e3, +0x98e4, 0x0007, 0x680c, 0xc215, 0xc20c, 0x98e1, 0x0b70, 0x0311, +0x5313, 0x076c, 0x7c01, 0xc1d9, 0x5efb, 0x068a, 0x076b, 0x7c01, +0xc1d9, 0x5ef3, 0x59db, 0x58d3, 0x018f, 0x0110, 0x390f, 0x008b, +0xc13c, 0x7d2b, 0x5ac0, 0x5bc8, 0xc14e, 0x7c27, 0x0388, 0x0689, +0x5ce3, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x073e, 0x4d00, 0x7d18, +0x0870, 0x0011, 0x077e, 0x7d09, 0x077d, 0x7d02, 0x5228, 0x9961, +0x52f8, 0x54db, 0x02bc, 0x02cc, 0x7c09, 0x077c, 0x7d02, 0x5228, +0x996a, 0x52f8, 0x54d3, 0x02bc, 0x02cc, 0x7d09, 0x0400, 0x9958, +0x008b, 0x52c0, 0x53c8, 0xc159, 0x7dd6, 0x0200, 0x9948, 0x08ff, +0x00bf, 0x077f, 0x7d15, 0x0488, 0x00d5, 0x7d01, 0x008d, 0x05a0, +0x5deb, 0x028f, 0x0212, 0x0212, 0x3aff, 0x05da, 0x7c02, 0x073e, +0x9995, 0x02a4, 0x02dd, 0x7d02, 0x073e, 0x9995, 0x075e, 0x9995, +0x55eb, 0x4d00, 0x7c02, 0x0598, 0x5deb, 0x52f3, 0x54fb, 0x076a, +0x7d26, 0x076c, 0x7d01, 0x99d2, 0x076b, 0x7c57, 0x0769, 0x7d04, +0x0768, 0x7d02, 0x0e01, 0x99ac, 0x5893, 0x00d6, 0x7d01, 0x008e, +0x5593, 0x05a0, 0x5d93, 0x06a0, 0x7802, 0x5502, 0x5d04, 0x7c1d, +0x4e00, 0x7c08, 0x0769, 0x7d03, 0x5502, 0x7e17, 0x99b9, 0x5d04, +0x7f14, 0x0689, 0x5093, 0x4800, 0x7d01, 0x99a4, 0x9a1d, 0x0015, +0x7806, 0x5502, 0x5d04, 0x074f, 0x5502, 0x5d24, 0x072f, 0x7c01, +0x9a1d, 0x0017, 0x076f, 0x7c01, 0x2001, 0x5593, 0x009d, 0x0007, +0xda24, 0x9970, 0x6cd3, 0x0769, 0x7d04, 0x0768, 0x7d02, 0x0e01, +0x99e1, 0x5893, 0x00d6, 0x7d01, 0x008e, 0x5593, 0x05a0, 0x5d93, +0x06a0, 0x7802, 0x5502, 0x6dc8, 0x7c0f, 0x4e00, 0x7c08, 0x0769, +0x7d03, 0x5502, 0x7e09, 0x99ee, 0x6dc8, 0x7f06, 0x0689, 0x5093, +0x4800, 0x7d01, 0x99d9, 0x9a1d, 0x9a17, 0x6ac3, 0x0769, 0x7d04, +0x0768, 0x7d02, 0x0e01, 0x9a04, 0x5893, 0x00d6, 0x7d01, 0x008e, +0x5593, 0x05a0, 0x5d93, 0x06a0, 0x7802, 0x65c8, 0x5d04, 0x7c0f, +0x4e00, 0x7c08, 0x0769, 0x7d03, 0x65c8, 0x7e09, 0x9a11, 0x5d04, +0x7f06, 0x0689, 0x5093, 0x4800, 0x7d01, 0x99fc, 0x9a1d, 0x5593, +0x009d, 0x0007, 0x6cff, 0xda24, 0x9970, 0x0000, 0x54e3, 0x55eb, +0x4d00, 0x7c01, 0x9970, 0x9958, 0x54e3, 0x55eb, 0x0aff, 0x0211, +0x1aff, 0x077f, 0x7c02, 0x05a0, 0x9a31, 0x009d, 0x058c, 0x05ba, +0x05a0, 0x0210, 0x04ba, 0x04ad, 0x0454, 0x0006, 0xc1d9, 0xc1e5, +0x57db, 0x52f3, 0x6a05, 0x5ce3, 0x080f, 0x0011, 0x18ff, 0x00bf, +0x00d5, 0x7d01, 0x008d, 0x05a0, 0x56fb, 0x0478, 0x7d03, 0x0479, +0x7d28, 0x7c1a, 0x0479, 0x7c31, 0x0b70, 0x0311, 0x53eb, 0x5206, +0x7e60, 0x0360, 0x7d02, 0x0210, 0x0212, 0x6a09, 0x7f5a, 0x0212, +0x6a09, 0x7f57, 0x0212, 0x6a09, 0x7f54, 0x2003, 0x4800, 0x7cef, +0x0b70, 0x0311, 0x5313, 0x9a88, 0x0015, 0x0015, 0xdaa1, 0x5206, +0x6a0b, 0x069c, 0x2001, 0x2701, 0x4f00, 0x7cf9, 0x4800, 0x7cf6, +0x9a87, 0x0015, 0xdaa1, 0x5206, 0x6a0a, 0x069c, 0x2001, 0x2701, +0x4f00, 0x7cf9, 0x4800, 0x7cf6, 0x9a87, 0xdaa1, 0x5206, 0x6a09, +0x069c, 0x2001, 0x2701, 0x4f00, 0x7cf9, 0x4800, 0x7cf6, 0x7c29, +0x6a28, 0x7f27, 0x57db, 0x0777, 0x7c0c, 0x0710, 0x3f0f, 0x0717, +0x0717, 0x0e70, 0x0611, 0x0c70, 0x0411, 0x069c, 0x069f, 0x0c01, +0x5c06, 0x0000, 0x54e3, 0x57db, 0x4d00, 0x7d15, 0xc1fc, 0x57db, +0x9a3b, 0x56fb, 0x57db, 0x048f, 0x0711, 0x3ff0, 0x0715, 0x0715, +0x0715, 0x0715, 0x0410, 0x0411, 0x3c0f, 0x1c01, 0x0417, 0x0417, +0x0006, 0xc279, 0x0454, 0xc20c, 0x9a38, 0xc1d9, 0xc1e5, 0x57db, +0x52f3, 0x6a05, 0x008f, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x56fb, +0x0478, 0x7d03, 0x0479, 0x7d29, 0x7c1f, 0x0479, 0x7c2e, 0x5de3, +0x0d70, 0x0511, 0x55ed, 0x0f00, 0x0760, 0x7d02, 0x5206, 0x9ad1, +0x5226, 0x7e33, 0x0560, 0x7d02, 0x0210, 0x0212, 0x6a09, 0x7f2d, +0x0212, 0x6a09, 0x7f2a, 0x0212, 0x6a09, 0x7f27, 0x1f01, 0x2003, +0x4800, 0x7cea, 0x55e3, 0x9afc, 0x0015, 0x0015, 0x0015, 0x7804, +0x5206, 0x6a0b, 0x5226, 0x6a0b, 0x9afb, 0x0015, 0x0015, 0x7804, +0x5206, 0x6a0a, 0x5226, 0x6a0a, 0x9afb, 0x0015, 0x7804, 0x5206, +0x6a09, 0x5226, 0x6a09, 0x7c09, 0x6a28, 0x7f07, 0x0000, 0x57db, +0x4d00, 0x7d05, 0xc1fc, 0x57db, 0x9aba, 0xc279, 0x0454, 0xc20c, +0x9ab7, 0xc1e5, 0x57db, 0x52f3, 0x6a05, 0x56fb, 0x028e, 0x1a94, +0x6ac3, 0x62c8, 0x0269, 0x7d26, 0x1e94, 0x6ec3, 0x6ed3, 0x62c8, +0x0a01, 0x0211, 0x6ac8, 0x2694, 0x1e98, 0x6ec3, 0x62c8, 0x2698, +0x6ec3, 0x0260, 0x7d0f, 0x1e98, 0x6ec3, 0x62c8, 0x026c, 0x7d03, +0x2698, 0x6ec3, 0x9b48, 0x0a10, 0x0211, 0x6ed3, 0x6ac8, 0x2698, +0x6ec3, 0x9b58, 0x62c8, 0x9b34, 0x6a09, 0x7f18, 0x2501, 0x4d00, +0x7d1f, 0x9b1c, 0x6ee3, 0x008f, 0x05d8, 0x7d01, 0x008d, 0x62c8, +0x6a09, 0x7f0c, 0x2501, 0x2001, 0x7cfa, 0x57db, 0x4d00, 0x7d10, +0x6a28, 0x7f04, 0x0000, 0xc1fc, 0x57db, 0x9b0d, 0x0007, 0x6204, +0x6a0c, 0x9b55, 0x6a28, 0x7ffa, 0x6204, 0xc27c, 0x0458, 0x0454, +0x08ff, 0x0011, 0x18ff, 0x00bc, 0x00cd, 0x7c01, 0x9b48, 0x6a28, +0x7fed, 0x6204, 0xc27c, 0xc20c, 0x9b0a, 0xc1d9, 0xc1e5, 0x57db, +0x52f3, 0x6a05, 0x56fb, 0x028e, 0x1a94, 0x5202, 0x0269, 0x7d1d, +0x1e94, 0x5206, 0x0248, 0x5a06, 0x2694, 0x1e98, 0x5206, 0x024c, +0x5a06, 0x2698, 0x1e98, 0x5206, 0x0260, 0x7c0a, 0x2698, 0x5206, +0x026e, 0x7d23, 0x6a09, 0x7f1d, 0x2501, 0x4d00, 0x7d24, 0x9b7a, +0x6a28, 0x7f17, 0x6204, 0xc27c, 0x9bab, 0x008f, 0x05d8, 0x7d01, +0x008d, 0x05a0, 0x5206, 0x026e, 0x7d10, 0x6a09, 0x7f0a, 0x2001, +0x7cf9, 0x6a28, 0x7f06, 0x0000, 0x4d00, 0x7d0d, 0xc1fc, 0x57db, +0x9b6a, 0x0007, 0x6204, 0x6a0c, 0x9ba8, 0x6a28, 0x7ffa, 0x6204, +0xc27c, 0x0458, 0x0454, 0x6a28, 0x7ff4, 0xc20c, 0x9b67, 0xdbf3, +0x57db, 0x52f3, 0x6a05, 0x69c7, 0x008f, 0x00d5, 0x7d01, 0x008d, +0x05a0, 0x0478, 0x7d03, 0x0479, 0x7d1c, 0x7c15, 0x0479, 0x7c1e, +0x56ee, 0x62c8, 0x7e28, 0x0660, 0x7d02, 0x0210, 0x0212, 0x6a09, +0x7f22, 0x0212, 0x6a09, 0x7f1f, 0x0212, 0x6a09, 0x7f1c, 0x2003, +0x4800, 0x7cef, 0x9be2, 0x0015, 0x0015, 0x7802, 0x62c8, 0x6a0b, +0x9be1, 0x0015, 0x7802, 0x62c8, 0x6a0a, 0x9be1, 0x7802, 0x62c8, +0x6a09, 0x7c09, 0x6a28, 0x7f07, 0x4d00, 0x7d07, 0x52d3, 0x0801, +0x5802, 0x0400, 0x9bb3, 0xc279, 0x0454, 0x52d3, 0x0801, 0x5802, +0x0401, 0xdc0b, 0x9bb0, 0x0b70, 0x0311, 0x5313, 0x5fdb, 0x070a, +0x58d3, 0x008b, 0x5efb, 0xc13c, 0x7d15, 0x5ac0, 0x5bc8, 0xc14e, +0x7c11, 0x0388, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, +0x7d04, 0x9c0a, 0x0708, 0x5fdb, 0x070a, 0x008b, 0x52c3, 0x53cb, +0xc159, 0x7dec, 0x0200, 0x9bfb, 0x6e01, 0x610b, 0x7e2f, 0x620b, +0x7e2d, 0x630b, 0x7e2b, 0x0d0c, 0x0417, 0x0417, 0x0417, 0x049d, +0x1d08, 0x05cc, 0x7c01, 0x0d0c, 0x6ad1, 0x0f00, 0x0742, 0x6fc8, +0x6fdd, 0x7f1c, 0x008e, 0x009d, 0x6801, 0x670b, 0x7e17, 0x6bd5, +0x0804, 0x7802, 0x6fc8, 0x0712, 0x7c11, 0x670b, 0x7e0f, 0x0804, +0x7802, 0x6fc8, 0x0712, 0x7c0a, 0x6fdd, 0x7f08, 0x69d1, 0x0f01, +0x6fc8, 0x6fdd, 0x7f03, 0x0101, 0x0400, 0x9c20, 0x0007, 0x68ff, +0x680c, 0x0200, 0x9c20, 0xdc90, 0x57db, 0x52f3, 0x6a05, 0x52fb, +0x6ac7, 0x008f, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x0478, 0x7d03, +0x0479, 0x7d1c, 0x7c15, 0x0479, 0x7c1e, 0x56ee, 0x62c8, 0x7e28, +0x0660, 0x7d02, 0x0210, 0x0212, 0x6a09, 0x7f22, 0x0212, 0x6a09, +0x7f1f, 0x0212, 0x6a09, 0x7f1c, 0x2003, 0x4800, 0x7cef, 0x9c7f, +0x0015, 0x0015, 0x7802, 0x62c8, 0x6a0b, 0x9c7e, 0x0015, 0x7802, +0x62c8, 0x6a0a, 0x9c7e, 0x7802, 0x62c8, 0x6a09, 0x7c09, 0x6a28, +0x7f07, 0x4d00, 0x7d07, 0x52d3, 0x0801, 0x5802, 0x0400, 0x9c4f, +0xc279, 0x0454, 0x52d3, 0x0801, 0x5802, 0x0401, 0xdca8, 0x9c4c, +0x0b70, 0x0311, 0x5313, 0x5fdb, 0x070a, 0x58d3, 0x008b, 0x5efb, +0xc13c, 0x7d15, 0x5ac0, 0x5bc8, 0xc14e, 0x7c11, 0x0388, 0x5df0, +0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d04, 0x9ca7, 0x0708, +0x5fdb, 0x070a, 0x008b, 0x52c3, 0x53cb, 0xc159, 0x7dec, 0x0200, +0x9c98, 0xdd02, 0x52f3, 0x6a01, 0x57db, 0x52fb, 0x077f, 0x7d02, +0x6ad3, 0x9cbb, 0x6ad7, 0x008f, 0x38ff, 0x00d5, 0x7d01, 0x008d, +0x05a0, 0x5deb, 0x0478, 0x7d03, 0x0479, 0x7d1c, 0x7c20, 0x0479, +0x7c15, 0x56ee, 0x0660, 0x7d05, 0x6509, 0x7e2a, 0x620a, 0x7e28, +0x9cd5, 0x620a, 0x7e25, 0x6509, 0x7e23, 0x0512, 0x0512, 0x02ad, +0x6ac8, 0x7f1e, 0x2003, 0x4800, 0x7ced, 0x9ced, 0x7802, 0x6209, +0x6ac8, 0x9cec, 0x0015, 0x7802, 0x620a, 0x6ac8, 0x9cec, 0x0015, +0x0015, 0x7802, 0x620b, 0x6ac8, 0x7c0b, 0x6ddf, 0x7f09, 0x0000, +0x55eb, 0x4d00, 0x7d09, 0x52d3, 0x0801, 0x5802, 0x0400, 0x9cb4, +0x0007, 0x68cc, 0x680c, 0xc215, 0x52d3, 0x0801, 0x5802, 0x0401, +0xdd1a, 0x9cb2, 0x0b70, 0x0311, 0x5313, 0x5fdb, 0x070a, 0x58d3, +0x008b, 0x5efb, 0xc13c, 0x7d15, 0x5ac0, 0x5bc8, 0xc14e, 0x7c11, +0x0388, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d04, +0x9d19, 0x0708, 0x5fdb, 0x070a, 0x008b, 0x52c3, 0x53cb, 0xc159, +0x7dec, 0x0200, 0x9d0a +}; #endif #endif /* __SOF_DRIVERS_SDMA_H__ */ diff --git a/src/include/sof/drivers/timestamp.h b/src/include/sof/drivers/timestamp.h deleted file mode 100644 index ff867dc1e33b..000000000000 --- a/src/include/sof/drivers/timestamp.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2019 Intel Corporation. All rights reserved. - */ - -#ifndef __SOF_DRIVERS_TIMESTAMP_H__ -#define __SOF_DRIVERS_TIMESTAMP_H__ - -#include - -struct dai; -struct timestamp_cfg; -struct timestamp_data; - -/* HDA */ -int timestamp_hda_config(struct dai *dai, struct timestamp_cfg *cfg); -int timestamp_hda_start(struct dai *dai, struct timestamp_cfg *cfg); -int timestamp_hda_stop(struct dai *dai, struct timestamp_cfg *cfg); -int timestamp_hda_get(struct dai *dai, struct timestamp_cfg *cfg, - struct timestamp_data *tsd); - -/* DMIC */ -int timestamp_dmic_config(struct dai *dai, struct timestamp_cfg *cfg); -int timestamp_dmic_start(struct dai *dai, struct timestamp_cfg *cfg); -int timestamp_dmic_stop(struct dai *dai, struct timestamp_cfg *cfg); -int timestamp_dmic_get(struct dai *dai, struct timestamp_cfg *cfg, - struct timestamp_data *tsd); - -/* SSP */ -int timestamp_ssp_config(struct dai *dai, struct timestamp_cfg *cfg); -int timestamp_ssp_start(struct dai *dai, struct timestamp_cfg *cfg); -int timestamp_ssp_stop(struct dai *dai, struct timestamp_cfg *cfg); -int timestamp_ssp_get(struct dai *dai, struct timestamp_cfg *cfg, - struct timestamp_data *tsd); - -#endif /* __SOF_DRIVERS_TIMESTAMP_H__ */ diff --git a/src/include/sof/ipc/topology.h b/src/include/sof/ipc/topology.h index 810df643fc13..34748379dbc2 100644 --- a/src/include/sof/ipc/topology.h +++ b/src/include/sof/ipc/topology.h @@ -56,7 +56,7 @@ int ipc4_chain_dma_state(struct comp_dev *dev, struct ipc4_chain_dma *cdma); int ipc4_create_chain_dma(struct ipc *ipc, struct ipc4_chain_dma *cdma); int ipc4_trigger_chain_dma(struct ipc *ipc, struct ipc4_chain_dma *cdma, bool *delay); int ipc4_process_on_core(uint32_t core, bool blocking); -int ipc4_pipeline_complete(struct ipc *ipc, uint32_t comp_id); +int ipc4_pipeline_complete(struct ipc *ipc, uint32_t comp_id, uint32_t cmd); int ipc4_find_dma_config(struct ipc_config_dai *dai, uint8_t *data_buffer, uint32_t size); int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd); int ipc4_pipeline_trigger(struct ipc_comp_dev *ppl_icd, uint32_t cmd, bool *delayed); diff --git a/src/include/sof/lib/dai-zephyr.h b/src/include/sof/lib/dai-zephyr.h index 49fbd2e02aa8..98e174a43c8d 100644 --- a/src/include/sof/lib/dai-zephyr.h +++ b/src/include/sof/lib/dai-zephyr.h @@ -33,6 +33,7 @@ #include #include #include +#include /** \addtogroup sof_dai_drivers DAI Drivers * DAI Drivers API specification. @@ -52,30 +53,6 @@ struct dai { struct k_spinlock lock; /* protect properties */ }; -struct timestamp_cfg { - uint32_t walclk_rate; /* Rate in Hz, e.g. 19200000 */ - int type; /* SSP, DMIC, HDA, etc. */ - int direction; /* Playback, capture */ - int index; /* For SSPx to select correct timestamp register */ - int dma_id; /* GPDMA id*/ - int dma_chan_index; /* Used GPDMA channel */ - int dma_chan_count; /* Channels in single GPDMA */ -}; - -struct timestamp_data { - uint64_t walclk; /* Wall clock */ - uint64_t sample; /* Sample count */ - uint32_t walclk_rate; /* Rate in Hz, e.g. 19200000 */ -}; - -struct timestamp_ops { - int (*ts_config)(struct dai *dai, struct timestamp_cfg *cfg); - int (*ts_start)(struct dai *dai, struct timestamp_cfg *cfg); - int (*ts_stop)(struct dai *dai, struct timestamp_cfg *cfg); - int (*ts_get)(struct dai *dai, struct timestamp_cfg *cfg, - struct timestamp_data *tsd); -}; - union hdalink_cfg { uint16_t full; struct { @@ -141,7 +118,7 @@ struct dai_data { struct comp_dev *dai_dev; struct comp_buffer *dma_buffer; struct comp_buffer *local_buffer; - struct timestamp_cfg ts_config; + struct dai_ts_cfg ts_config; struct dai *dai; struct dma *dma; struct dai_group *group; /* NULL if no group assigned */ diff --git a/src/include/sof/math/fir_hifi3.h b/src/include/sof/math/fir_hifi3.h index a3d4b19ce0ce..aa1102ef2a1f 100644 --- a/src/include/sof/math/fir_hifi3.h +++ b/src/include/sof/math/fir_hifi3.h @@ -48,7 +48,7 @@ static inline void fir_core_setup_circular(struct fir_state_32x16 *fir) } /* Setup circular for component buffer */ -static inline void fir_comp_setup_circular(const struct audio_stream __sparse_cache *buffer) +static inline void fir_comp_setup_circular(const struct audio_stream *buffer) { AE_SETCBEGIN0(audio_stream_get_addr(buffer)); AE_SETCEND0(audio_stream_get_end_addr(buffer)); diff --git a/src/include/sof/probe/probe.h b/src/include/sof/probe/probe.h index 22522fb09fe3..7b6623737895 100644 --- a/src/include/sof/probe/probe.h +++ b/src/include/sof/probe/probe.h @@ -17,6 +17,11 @@ */ typedef void(*probe_logging_hook_t)(uint8_t *buffer, size_t length); +#if CONFIG_LOG_BACKEND_SOF_PROBE +void probe_logging_hook(uint8_t *buffer, size_t length); +const struct log_backend *log_backend_probe_get(void); +#endif + /** * @brief Initialize the probe logging backend. * diff --git a/src/include/sof/samples/audio/smart_amp_test.h b/src/include/sof/samples/audio/smart_amp_test.h index 7f24b5c37de8..3feda5005125 100644 --- a/src/include/sof/samples/audio/smart_amp_test.h +++ b/src/include/sof/samples/audio/smart_amp_test.h @@ -8,7 +8,6 @@ #ifndef __SOF_AUDIO_SMART_AMP_H__ #define __SOF_AUDIO_SMART_AMP_H__ -#include #include #include diff --git a/src/include/sof/schedule/dp_schedule.h b/src/include/sof/schedule/dp_schedule.h index 81650c563d80..9b7f85c7e798 100644 --- a/src/include/sof/schedule/dp_schedule.h +++ b/src/include/sof/schedule/dp_schedule.h @@ -13,6 +13,8 @@ #include #include +struct processing_module; + /** * * DP scheduler is a scheduler that creates a separate preemptible Zephyr thread for each SOF task @@ -49,9 +51,6 @@ * */ -/** \brief tell the scheduler to run the task immediately, even if LL tick is not yet running */ -#define SCHEDULER_DP_RUN_TASK_IMMEDIATELY ((uint64_t)-1) - /** * \brief Init the Data Processing scheduler */ @@ -64,7 +63,7 @@ int scheduler_dp_init(void); * \param[out] task pointer, pointer to allocated task structure will be return * \param[in] uid pointer to UUID of the task * \param[in] ops pointer to task functions - * \param[in] data pointer to the thread private data + * \param[in] mod pointer to the module to be run * \param[in] core CPU the thread should run on * \param[in] stack_size size of stack for a zephyr task * \param[in] task_priority priority of the zephyr task @@ -72,7 +71,7 @@ int scheduler_dp_init(void); int scheduler_dp_task_init(struct task **task, const struct sof_uuid_entry *uid, const struct task_ops *ops, - void *data, + struct processing_module *mod, uint16_t core, size_t stack_size, uint32_t task_priority); diff --git a/src/include/sof/schedule/ll_schedule_domain.h b/src/include/sof/schedule/ll_schedule_domain.h index f555c256398b..9765df5ef0bc 100644 --- a/src/include/sof/schedule/ll_schedule_domain.h +++ b/src/include/sof/schedule/ll_schedule_domain.h @@ -44,6 +44,17 @@ struct ll_schedule_domain_ops { struct task *task, uint32_t num_tasks); void (*domain_enable)(struct ll_schedule_domain *domain, int core); void (*domain_disable)(struct ll_schedule_domain *domain, int core); +#if CONFIG_CROSS_CORE_STREAM + /* + * Unlike domain_disable(), these are intended to temporary block LL from + * starting its next cycle. Triggering (e.g., by means of timer interrupt) + * is still enabled and registered but execution of next cycle is blocked. + * Once unblocked, if triggering were previously registered in a blocked + * state -- next cycle execution could start immediately. + */ + void (*domain_block)(struct ll_schedule_domain *domain); + void (*domain_unblock)(struct ll_schedule_domain *domain); +#endif void (*domain_set)(struct ll_schedule_domain *domain, uint64_t start); void (*domain_clear)(struct ll_schedule_domain *domain); bool (*domain_is_pending)(struct ll_schedule_domain *domain, @@ -192,6 +203,20 @@ static inline void domain_disable(struct ll_schedule_domain *domain, int core) } } +#if CONFIG_CROSS_CORE_STREAM +static inline void domain_block(struct ll_schedule_domain *domain) +{ + if (domain->ops->domain_block) + domain->ops->domain_block(domain); +} + +static inline void domain_unblock(struct ll_schedule_domain *domain) +{ + if (domain->ops->domain_unblock) + domain->ops->domain_unblock(domain); +} +#endif + static inline bool domain_is_pending(struct ll_schedule_domain *domain, struct task *task, struct comp_dev **comp) { diff --git a/src/include/sof/trace/preproc.h b/src/include/sof/trace/preproc.h index 17a7994fcb43..acc20086258e 100644 --- a/src/include/sof/trace/preproc.h +++ b/src/include/sof/trace/preproc.h @@ -158,7 +158,7 @@ return_t META_CONCAT(prefix, postfix) (args) /* counteract compiler warning about unused variables */ -#define UNUSED(arg1, ...) do { META_RECURSE( \ +#define SOF_TRACE_UNUSED(arg1, ...) do { META_RECURSE( \ META_MAP_AGGREGATE(1, _META_VOID2, _META_VOID(arg1), __VA_ARGS__)); \ } while (0) diff --git a/src/include/sof/trace/trace.h b/src/include/sof/trace/trace.h index d3953bd16afe..d1beb48d81e2 100644 --- a/src/include/sof/trace/trace.h +++ b/src/include/sof/trace/trace.h @@ -93,7 +93,7 @@ static inline struct trace *trace_get(void) /* Silences compiler warnings about unused variables */ #define trace_unused(class, ctx, id_1, id_2, format, ...) \ - UNUSED(ctx, id_1, id_2, ##__VA_ARGS__) + SOF_TRACE_UNUSED(ctx, id_1, id_2, ##__VA_ARGS__) struct trace_filter { uint32_t uuid_id; /**< type id, or 0 when not important */ @@ -233,19 +233,26 @@ void _log_sofdict(log_func_t sofdict_logf, bool atomic, const void *log_entry, #ifdef CONFIG_LIBRARY -extern int test_bench_trace; +#include + +/* trace level used on host configurations */ +extern int host_trace_level; + char *get_trace_class(uint32_t trace_class); #define _log_message(ignored_log_func, atomic, level, comp_class, ctx, id_1, id_2, format, ...) \ -do { \ - (void)ctx; \ - (void)id_1; \ - (void)id_2; \ - if (test_bench_trace) { \ - char *msg = "(%s:%d) " format; \ - fprintf(stderr, msg, strrchr(__FILE__, '/') + 1,\ - __LINE__, ##__VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } \ +do { \ + (void)ctx; \ + (void)id_1; \ + (void)id_2; \ + struct timeval tv; \ + char *msg = "(%s:%d) " format; \ + if (level >= host_trace_level) { \ + gettimeofday(&tv, NULL); \ + fprintf(stderr, "%ld.%6.6ld:", tv.tv_sec, tv.tv_usec); \ + fprintf(stderr, msg, strrchr(__FILE__, '/') + 1, \ + __LINE__, ##__VA_ARGS__); \ + fprintf(stderr, "\n"); \ + } \ } while (0) #define trace_point(x) do {} while (0) diff --git a/src/ipc/ipc-helper.c b/src/ipc/ipc-helper.c index bbcec49698f0..44983f6e6f95 100644 --- a/src/ipc/ipc-helper.c +++ b/src/ipc/ipc-helper.c @@ -36,7 +36,7 @@ LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL); /* create a new component in the pipeline */ -struct comp_buffer *buffer_new(const struct sof_ipc_buffer *desc) +struct comp_buffer *buffer_new(const struct sof_ipc_buffer *desc, bool is_shared) { struct comp_buffer *buffer; @@ -44,7 +44,8 @@ struct comp_buffer *buffer_new(const struct sof_ipc_buffer *desc) desc->size, desc->comp.pipeline_id, desc->comp.id, desc->flags); /* allocate buffer */ - buffer = buffer_alloc(desc->size, desc->caps, desc->flags, PLATFORM_DCACHE_ALIGN); + buffer = buffer_alloc(desc->size, desc->caps, desc->flags, PLATFORM_DCACHE_ALIGN, + is_shared); if (buffer) { buffer->id = desc->comp.id; buffer->pipeline_id = desc->comp.pipeline_id; @@ -79,7 +80,7 @@ int32_t ipc_comp_pipe_id(const struct ipc_comp_dev *icd) */ static void comp_update_params(uint32_t flag, struct sof_ipc_stream_params *params, - struct comp_buffer __sparse_cache *buffer) + struct comp_buffer *buffer) { if (flag & BUFF_PARAMS_FRAME_FMT) params->frame_fmt = audio_stream_get_frm_fmt(&buffer->stream); @@ -103,7 +104,6 @@ int comp_verify_params(struct comp_dev *dev, uint32_t flag, struct list_item *clist; struct comp_buffer *sinkb; struct comp_buffer *buf; - struct comp_buffer __sparse_cache *buf_c; int dir = dev->direction; if (!params) { @@ -127,22 +127,18 @@ int comp_verify_params(struct comp_dev *dev, uint32_t flag, struct comp_buffer, source_list); - buf_c = buffer_acquire(buf); - /* update specific pcm parameter with buffer parameter if * specific flag is set. */ - comp_update_params(flag, params, buf_c); + comp_update_params(flag, params, buf); /* overwrite buffer parameters with modified pcm * parameters */ - buffer_set_params(buf_c, params, BUFFER_UPDATE_FORCE); + buffer_set_params(buf, params, BUFFER_UPDATE_FORCE); /* set component period frames */ - component_set_nearest_period_frames(dev, audio_stream_get_rate(&buf_c->stream)); - - buffer_release(buf_c); + component_set_nearest_period_frames(dev, audio_stream_get_rate(&buf->stream)); } else { /* for other components we iterate over all downstream buffers * (for playback) or upstream buffers (for capture). @@ -151,19 +147,15 @@ int comp_verify_params(struct comp_dev *dev, uint32_t flag, list_for_item(clist, buffer_list) { buf = buffer_from_list(clist, dir); - buf_c = buffer_acquire(buf); - comp_update_params(flag, params, buf_c); - buffer_set_params(buf_c, params, BUFFER_UPDATE_FORCE); - buffer_release(buf_c); + comp_update_params(flag, params, buf); + buffer_set_params(buf, params, BUFFER_UPDATE_FORCE); } /* fetch sink buffer in order to calculate period frames */ sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - buf_c = buffer_acquire(sinkb); - component_set_nearest_period_frames(dev, audio_stream_get_rate(&buf_c->stream)); - buffer_release(buf_c); + component_set_nearest_period_frames(dev, audio_stream_get_rate(&sinkb->stream)); } return 0; @@ -174,8 +166,8 @@ int comp_buffer_connect(struct comp_dev *comp, uint32_t comp_core, { /* check if it's a connection between cores */ if (buffer->core != comp_core) { - /* set the buffer as a coherent object */ - coherent_shared_thread(buffer, c); + /* buffer must be shared */ + assert(buffer->is_shared); if (!comp->is_shared) comp_make_shared(comp); @@ -290,10 +282,8 @@ int ipc_comp_free(struct ipc *ipc, uint32_t comp_id) irq_local_disable(flags); list_for_item_safe(clist, tmp, &icd->cd->bsource_list) { struct comp_buffer *buffer = container_of(clist, struct comp_buffer, sink_list); - struct comp_buffer __sparse_cache *buffer_c = buffer_acquire(buffer); - buffer_c->sink = NULL; - buffer_release(buffer_c); + buffer->sink = NULL; /* Also if it isn't shared - we are about to modify uncached data */ dcache_writeback_invalidate_region(uncache_to_cache(buffer), sizeof(*buffer)); @@ -303,10 +293,8 @@ int ipc_comp_free(struct ipc *ipc, uint32_t comp_id) list_for_item_safe(clist, tmp, &icd->cd->bsink_list) { struct comp_buffer *buffer = container_of(clist, struct comp_buffer, source_list); - struct comp_buffer __sparse_cache *buffer_c = buffer_acquire(buffer); - buffer_c->source = NULL; - buffer_release(buffer_c); + buffer->source = NULL; /* Also if it isn't shared - we are about to modify uncached data */ dcache_writeback_invalidate_region(uncache_to_cache(buffer), sizeof(*buffer)); diff --git a/src/ipc/ipc3/dai.c b/src/ipc/ipc3/dai.c index decee57299b9..ab5143f64d13 100644 --- a/src/ipc/ipc3/dai.c +++ b/src/ipc/ipc3/dai.c @@ -65,6 +65,10 @@ int dai_config_dma_channel(struct dai_data *dd, struct comp_dev *dev, const void dd->stream_id); channel = EDMA_HS_GET_CHAN(handshake); break; + case SOF_DAI_IMX_MICFIL: + channel = dai_get_handshake(dd->dai, dai->direction, + dd->stream_id); + break; case SOF_DAI_AMD_BT: channel = dai_get_handshake(dd->dai, dai->direction, dd->stream_id); @@ -103,7 +107,6 @@ int ipc_dai_data_config(struct dai_data *dd, struct comp_dev *dev) { struct ipc_config_dai *dai = &dd->ipc_config; struct sof_ipc_dai_config *config = ipc_from_dai_config(dd->dai_spec_config); - struct comp_buffer __sparse_cache *buffer_c; if (!config) { comp_err(dev, "dai_data_config(): no config set for dai %d type %d", @@ -145,19 +148,18 @@ int ipc_dai_data_config(struct dai_data *dd, struct comp_dev *dev) * all formats, such as 8/16/24/32 bits. */ dev->ipc_config.frame_fmt = SOF_IPC_FRAME_S32_LE; - if (dd->dma_buffer) { - buffer_c = buffer_acquire(dd->dma_buffer); - audio_stream_set_frm_fmt(&buffer_c->stream, dev->ipc_config.frame_fmt); - buffer_release(buffer_c); - } + if (dd->dma_buffer) + audio_stream_set_frm_fmt(&dd->dma_buffer->stream, + dev->ipc_config.frame_fmt); + dd->config.burst_elems = dai_get_fifo_depth(dd->dai, dai->direction); /* As with HDA, the DMA channel is assigned in runtime, * not during topology parsing. */ dd->stream_id = config->alh.stream_id; break; + case SOF_DAI_IMX_MICFIL: case SOF_DAI_IMX_SAI: - COMPILER_FALLTHROUGH; case SOF_DAI_IMX_ESAI: dd->config.burst_elems = dai_get_fifo_depth(dd->dai, dai->direction); break; @@ -170,11 +172,9 @@ int ipc_dai_data_config(struct dai_data *dd, struct comp_dev *dev) break; case SOF_DAI_AMD_DMIC: dev->ipc_config.frame_fmt = SOF_IPC_FRAME_S32_LE; - if (dd->dma_buffer) { - buffer_c = buffer_acquire(dd->dma_buffer); - audio_stream_set_frm_fmt(&buffer_c->stream, dev->ipc_config.frame_fmt); - buffer_release(buffer_c); - } + if (dd->dma_buffer) + audio_stream_set_frm_fmt(&dd->dma_buffer->stream, + dev->ipc_config.frame_fmt); break; case SOF_DAI_AMD_HS: case SOF_DAI_AMD_HS_VIRTUAL: diff --git a/src/ipc/ipc3/helper.c b/src/ipc/ipc3/helper.c index 4a723b9539a7..f7b731ffde90 100644 --- a/src/ipc/ipc3/helper.c +++ b/src/ipc/ipc3/helper.c @@ -454,7 +454,7 @@ int ipc_buffer_new(struct ipc *ipc, const struct sof_ipc_buffer *desc) } /* register buffer with pipeline */ - buffer = buffer_new(desc); + buffer = buffer_new(desc, false); if (!buffer) { tr_err(&ipc_tr, "ipc_buffer_new(): buffer_new() failed"); return -ENOMEM; @@ -487,7 +487,6 @@ int ipc_buffer_free(struct ipc *ipc, uint32_t buffer_id) unsigned int core; bool sink_active = false; bool source_active = false; - struct comp_buffer __sparse_cache *buffer_c; /* check whether buffer exists */ ibd = ipc_get_buffer_by_id(ipc, buffer_id); @@ -498,8 +497,6 @@ int ipc_buffer_free(struct ipc *ipc, uint32_t buffer_id) if (!cpu_is_me(ibd->core)) return ipc_process_on_core(ibd->core, false); - buffer_c = buffer_acquire(ibd->cb); - /* try to find sink/source components to check if they still exists */ list_for_item(clist, &ipc->comp_list) { icd = container_of(clist, struct ipc_comp_dev, list); @@ -507,21 +504,19 @@ int ipc_buffer_free(struct ipc *ipc, uint32_t buffer_id) continue; /* check comp state if sink and source are valid */ - if (buffer_c->sink == icd->cd) { - sink = buffer_c->sink; - if (buffer_c->sink->state != COMP_STATE_READY) + if (ibd->cb->sink == icd->cd) { + sink = ibd->cb->sink; + if (ibd->cb->sink->state != COMP_STATE_READY) sink_active = true; } - if (buffer_c->source == icd->cd) { - source = buffer_c->source; - if (buffer_c->source->state != COMP_STATE_READY) + if (ibd->cb->source == icd->cd) { + source = ibd->cb->source; + if (ibd->cb->source->state != COMP_STATE_READY) source_active = true; } } - buffer_release(buffer_c); - /* * A buffer could be connected to 2 different pipelines. When one pipeline is freed, the * buffer comp that belongs in this pipeline will need to be freed even when the other @@ -572,6 +567,12 @@ static int ipc_comp_to_buffer_connect(struct ipc_comp_dev *comp, tr_dbg(&ipc_tr, "ipc: comp sink %d, source %d -> connect", buffer->id, comp->id); +#if CONFIG_INCOHERENT + if (comp->core != buffer->cb->core) { + tr_err(&ipc_tr, "ipc: shared buffers are not supported for IPC3 incoherent architectures"); + return -ENOTSUP; + } +#endif return comp_buffer_connect(comp->cd, comp->core, buffer->cb, PPL_CONN_DIR_COMP_TO_BUFFER); } @@ -582,6 +583,12 @@ static int ipc_buffer_to_comp_connect(struct ipc_comp_dev *buffer, tr_dbg(&ipc_tr, "ipc: comp sink %d, source %d -> connect", comp->id, buffer->id); +#if CONFIG_INCOHERENT + if (comp->core != buffer->cb->core) { + tr_err(&ipc_tr, "ipc: shared buffers are not supported for IPC3 incoherent architectures"); + return -ENOTSUP; + } +#endif return comp_buffer_connect(comp->cd, comp->core, buffer->cb, PPL_CONN_DIR_BUFFER_TO_COMP); } diff --git a/src/ipc/ipc4/CMakeLists.txt b/src/ipc/ipc4/CMakeLists.txt index 7f9d75f654be..2e162e702672 100644 --- a/src/ipc/ipc4/CMakeLists.txt +++ b/src/ipc/ipc4/CMakeLists.txt @@ -9,4 +9,4 @@ add_local_sources(sof ams_helpers.c ) -target_include_directories(sof_options INTERFACE ${PROJECT_SOURCE_DIR}/rimage/src/include) +target_include_directories(sof_options INTERFACE ${RIMAGE_TOP}/src/include) diff --git a/src/ipc/ipc4/handler.c b/src/ipc/ipc4/handler.c index 0ab182e84d04..209bddf65097 100644 --- a/src/ipc/ipc4/handler.c +++ b/src/ipc/ipc4/handler.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,56 @@ static struct ipc_msg msg_reply = {0, 0, 0, 0, LIST_INIT(msg_reply.list)}; static struct ipc_msg msg_notify = {0, 0, 0, 0, LIST_INIT(msg_notify.list)}; +#if CONFIG_LIBRARY +static inline struct ipc4_message_request *ipc4_get_message_request(void) +{ + struct ipc *ipc = ipc_get(); + + return (struct ipc4_message_request *)ipc->comp_data; +} + +static inline void ipc4_send_reply(struct ipc4_message_reply *reply) +{ + struct ipc *ipc = ipc_get(); + + memcpy((char *)ipc->comp_data, reply, sizeof(*reply)); +} + +static inline const struct ipc4_pipeline_set_state_data *ipc4_get_pipeline_data(void) +{ + const struct ipc4_pipeline_set_state_data *ppl_data; + struct ipc *ipc = ipc_get(); + + ppl_data = (const struct ipc4_pipeline_set_state_data *)ipc->comp_data; + + return ppl_data; +} +#else +static inline struct ipc4_message_request *ipc4_get_message_request(void) +{ + /* ignoring _hdr as it does not contain valid data in IPC4/IDC case */ + return ipc_from_hdr(&msg_data.msg_in); +} + +static inline void ipc4_send_reply(struct ipc4_message_reply *reply) +{ + struct ipc *ipc = ipc_get(); + char *data = ipc->comp_data; + + ipc_msg_send(&msg_reply, data, true); +} + +static inline const struct ipc4_pipeline_set_state_data *ipc4_get_pipeline_data(void) +{ + const struct ipc4_pipeline_set_state_data *ppl_data; + + ppl_data = (const struct ipc4_pipeline_set_state_data *)MAILBOX_HOSTBOX_BASE; + dcache_invalidate_region((__sparse_force void __sparse_cache *)ppl_data, + sizeof(*ppl_data)); + + return ppl_data; +} +#endif /* * Global IPC Operations. */ @@ -274,7 +325,7 @@ int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd) switch (status) { case COMP_STATE_INIT: tr_dbg(&ipc_tr, "pipeline %d: reset from init", ppl_icd->id); - ret = ipc4_pipeline_complete(ipc, ppl_icd->id); + ret = ipc4_pipeline_complete(ipc, ppl_icd->id, cmd); if (ret < 0) ret = IPC4_INVALID_REQUEST; @@ -296,7 +347,7 @@ int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd) switch (status) { case COMP_STATE_INIT: tr_dbg(&ipc_tr, "pipeline %d: pause from init", ppl_icd->id); - ret = ipc4_pipeline_complete(ipc, ppl_icd->id); + ret = ipc4_pipeline_complete(ipc, ppl_icd->id, cmd); if (ret < 0) ret = IPC4_INVALID_REQUEST; @@ -311,6 +362,7 @@ int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd) case SOF_IPC4_PIPELINE_STATE_EOS: if (status != COMP_STATE_ACTIVE) return IPC4_INVALID_REQUEST; + COMPILER_FALLTHROUGH; case SOF_IPC4_PIPELINE_STATE_SAVED: case SOF_IPC4_PIPELINE_STATE_ERROR_STOP: default: @@ -475,7 +527,8 @@ static int ipc4_set_pipeline_state(struct ipc4_message_request *ipc4) struct ipc4_pipeline_set_state state; struct ipc_comp_dev *ppl_icd; struct ipc *ipc = ipc_get(); - uint32_t cmd, ppl_count, id; + uint32_t cmd, ppl_count; + uint32_t id = 0; const uint32_t *ppl_id; bool use_idc = false; uint32_t idx; @@ -485,10 +538,8 @@ static int ipc4_set_pipeline_state(struct ipc4_message_request *ipc4) state.primary.dat = ipc4->primary.dat; state.extension.dat = ipc4->extension.dat; cmd = state.primary.r.ppl_state; + ppl_data = ipc4_get_pipeline_data(); - ppl_data = (const struct ipc4_pipeline_set_state_data *)MAILBOX_HOSTBOX_BASE; - dcache_invalidate_region((__sparse_force void __sparse_cache *)ppl_data, - sizeof(*ppl_data)); if (state.extension.r.multi_ppl) { ppl_count = ppl_data->pipelines_count; ppl_id = ppl_data->ppl_id; @@ -782,7 +833,7 @@ static int ipc4_process_glb_message(struct ipc4_message_request *ipc4) static int ipc4_init_module_instance(struct ipc4_message_request *ipc4) { - struct ipc4_module_init_instance module_init = {}; + struct ipc4_module_init_instance module_init; struct comp_dev *dev; /* we only need the common header here, all we have from the IPC */ int ret = memcpy_s(&module_init, sizeof(module_init), ipc4, sizeof(*ipc4)); @@ -872,7 +923,8 @@ static int ipc4_get_large_config_module_instance(struct ipc4_message_request *ip if (config.primary.r.module_id) { uint32_t comp_id; - comp_id = IPC4_COMP_ID(config.primary.r.module_id, config.primary.r.instance_id); + comp_id = IPC4_COMP_ID(config.primary.r.module_id, + config.primary.r.instance_id); dev = ipc4_get_comp_dev(comp_id); if (!dev) return IPC4_MOD_INVALID_ID; @@ -921,6 +973,69 @@ static int ipc4_get_large_config_module_instance(struct ipc4_message_request *ip return ret; } +static int ipc4_set_vendor_config_module_instance(struct comp_dev *dev, + const struct comp_driver *drv, + uint32_t module_id, + uint32_t instance_id, + bool init_block, + bool final_block, + uint32_t data_off_size, + const char *data) +{ + int ret; + + /* Old FW comment: bursted configs */ + if (init_block && final_block) { + const struct sof_tlv *tlv = (struct sof_tlv *)data; + /* if there is no payload in this large config set + * (4 bytes type | 4 bytes length=0 | no value) + * we do not handle such case + */ + if (data_off_size < sizeof(struct sof_tlv)) + return IPC4_INVALID_CONFIG_DATA_STRUCT; + + /* ===Iterate over payload=== + * Payload can have multiple sof_tlv structures inside, + * You can find how many by checking payload size (data_off_size) + * Here we just set pointer end_offset to the end of data + * and iterate until we reach that + */ + const uint8_t *end_offset = data + data_off_size; + + while ((const uint8_t *)tlv < end_offset) { + /* check for invalid length */ + if (!tlv->length) + return IPC4_INVALID_CONFIG_DATA_LEN; + + ret = drv->ops.set_large_config(dev, tlv->type, init_block, + final_block, tlv->length, tlv->value); + if (ret < 0) { + ipc_cmd_err(&ipc_tr, "failed to set large_config_module_instance %x : %x", + (uint32_t)module_id, (uint32_t)instance_id); + return IPC4_INVALID_RESOURCE_ID; + } + /* Move pointer to the end of this tlv */ + tlv = (struct sof_tlv *)((const uint8_t *)tlv + + sizeof(struct sof_tlv) + ALIGN_UP(tlv->length, 4)); + } + return IPC4_SUCCESS; + } + /* else, !(init_block && final_block) */ + const struct sof_tlv *tlv = (struct sof_tlv *)data; + uint32_t param_id = 0; + + if (init_block) { + /* for initial block use param_id from tlv + * move pointer and size to end of the tlv + */ + param_id = tlv->type; + data += sizeof(struct sof_tlv); + data_off_size -= sizeof(struct sof_tlv); + } + return drv->ops.set_large_config(dev, param_id, init_block, final_block, + data_off_size, (uint8_t *)data); +} + static int ipc4_set_large_config_module_instance(struct ipc4_message_request *ipc4) { struct ipc4_module_large_config config; @@ -956,16 +1071,25 @@ static int ipc4_set_large_config_module_instance(struct ipc4_message_request *ip return ipc4_process_on_core(dev->ipc_config.core, false); } - ret = drv->ops.set_large_config(dev, config.extension.r.large_param_id, - config.extension.r.init_block, - config.extension.r.final_block, - config.extension.r.data_off_size, - (const char *)MAILBOX_HOSTBOX_BASE); - if (ret < 0) { - ipc_cmd_err(&ipc_tr, "failed to set large_config_module_instance %x : %x", - (uint32_t)config.primary.r.module_id, - (uint32_t)config.primary.r.instance_id); - ret = IPC4_INVALID_RESOURCE_ID; + /* check for vendor param first */ + if (config.extension.r.large_param_id == VENDOR_CONFIG_PARAM) { + ret = ipc4_set_vendor_config_module_instance(dev, drv, + (uint32_t)config.primary.r.module_id, + (uint32_t)config.primary.r.instance_id, + config.extension.r.init_block, + config.extension.r.final_block, + config.extension.r.data_off_size, + (const char *)MAILBOX_HOSTBOX_BASE); + } else { + ret = drv->ops.set_large_config(dev, config.extension.r.large_param_id, + config.extension.r.init_block, config.extension.r.final_block, + config.extension.r.data_off_size, (const char *)MAILBOX_HOSTBOX_BASE); + if (ret < 0) { + ipc_cmd_err(&ipc_tr, "failed to set large_config_module_instance %x : %x", + (uint32_t)config.primary.r.module_id, + (uint32_t)config.primary.r.instance_id); + ret = IPC4_INVALID_RESOURCE_ID; + } } return ret; @@ -1275,8 +1399,7 @@ void ipc_msg_reply(struct sof_ipc_reply *reply) void ipc_cmd(struct ipc_cmd_hdr *_hdr) { - /* ignoring _hdr as it does not contain valid data in IPC4/IDC case */ - struct ipc4_message_request *in = ipc_from_hdr(&msg_data.msg_in); + struct ipc4_message_request *in = ipc4_get_message_request(); enum ipc4_message_target target; int err; @@ -1312,7 +1435,6 @@ void ipc_cmd(struct ipc_cmd_hdr *_hdr) /* FW sends an ipc message to host if request bit is clear */ if (in->primary.r.rsp == SOF_IPC4_MESSAGE_DIR_MSG_REQUEST) { struct ipc *ipc = ipc_get(); - char *data = ipc->comp_data; struct ipc4_message_reply reply; /* Process flow and time stamp for IPC4 msg processed on secondary core : @@ -1399,6 +1521,6 @@ void ipc_cmd(struct ipc_cmd_hdr *_hdr) tr_dbg(&ipc_tr, "tx-reply\t: %#x|%#x", msg_reply.header, msg_reply.extension); - ipc_msg_send(&msg_reply, data, true); + ipc4_send_reply(&reply); } } diff --git a/src/ipc/ipc4/helper.c b/src/ipc/ipc4/helper.c index 46a4ff1e3f1b..29ef61dfb5c9 100644 --- a/src/ipc/ipc4/helper.c +++ b/src/ipc/ipc4/helper.c @@ -74,12 +74,28 @@ void ipc_build_trace_posn(struct sof_ipc_dma_trace_posn *posn) posn->rhdr.hdr.size = 0; } +#if CONFIG_LIBRARY +static inline char *ipc4_get_comp_new_data(void) +{ + struct ipc *ipc = ipc_get(); + char *data = (char *)ipc->comp_data + sizeof(struct ipc4_module_init_instance); + + return data; +} +#else +static inline char *ipc4_get_comp_new_data(void) +{ + return (char *)MAILBOX_HOSTBOX_BASE; +} +#endif + struct comp_dev *comp_new_ipc4(struct ipc4_module_init_instance *module_init) { struct comp_ipc_config ipc_config; const struct comp_driver *drv; struct comp_dev *dev; uint32_t comp_id; + char *data; comp_id = IPC4_COMP_ID(module_init->primary.r.module_id, module_init->primary.r.instance_id); @@ -119,15 +135,17 @@ struct comp_dev *comp_new_ipc4(struct ipc4_module_init_instance *module_init) dcache_invalidate_region((__sparse_force void __sparse_cache *)MAILBOX_HOSTBOX_BASE, MAILBOX_HOSTBOX_SIZE); + data = ipc4_get_comp_new_data(); if (drv->type == SOF_COMP_MODULE_ADAPTER) { const struct ipc_config_process spec = { - .data = (const unsigned char *)MAILBOX_HOSTBOX_BASE, + .data = (const unsigned char *)data, /* spec_size in IPC4 is in DW. Convert to bytes. */ .size = module_init->extension.r.param_block_size * sizeof(uint32_t), }; + dev = drv->ops.create(drv, &ipc_config, (const void *)&spec); } else { - dev = drv->ops.create(drv, &ipc_config, (const void *)MAILBOX_HOSTBOX_BASE); + dev = drv->ops.create(drv, &ipc_config, (const void *)data); } if (!dev) return NULL; @@ -241,14 +259,11 @@ static int ipc_pipeline_module_free(uint32_t pipeline_id) /* free sink buffer allocated by current component in bind function */ list_for_item_safe(list, _list, &icd->cd->bsink_list) { - struct comp_buffer __sparse_cache *buffer_c; struct comp_dev *sink; buffer = container_of(list, struct comp_buffer, source_list); pipeline_disconnect(icd->cd, buffer, PPL_CONN_DIR_COMP_TO_BUFFER); - buffer_c = buffer_acquire(buffer); - sink = buffer_c->sink; - buffer_release(buffer_c); + sink = buffer->sink; /* free the buffer only when the sink module has also been disconnected */ if (!sink) @@ -257,14 +272,11 @@ static int ipc_pipeline_module_free(uint32_t pipeline_id) /* free source buffer allocated by current component in bind function */ list_for_item_safe(list, _list, &icd->cd->bsource_list) { - struct comp_buffer __sparse_cache *buffer_c; struct comp_dev *source; buffer = container_of(list, struct comp_buffer, sink_list); pipeline_disconnect(icd->cd, buffer, PPL_CONN_DIR_BUFFER_TO_COMP); - buffer_c = buffer_acquire(buffer); - source = buffer_c->source; - buffer_release(buffer_c); + source = buffer->source; /* free the buffer only when the source module has also been disconnected */ if (!source) @@ -315,29 +327,92 @@ int ipc_pipeline_free(struct ipc *ipc, uint32_t comp_id) return IPC4_SUCCESS; } -static struct comp_buffer *ipc4_create_buffer(struct comp_dev *src, struct comp_dev *sink, - uint32_t src_obs, uint32_t src_queue, +static struct comp_buffer *ipc4_create_buffer(struct comp_dev *src, bool is_shared, + uint32_t buf_size, uint32_t src_queue, uint32_t dst_queue) { struct sof_ipc_buffer ipc_buf; - int buf_size; - - /* double it since obs is single buffer size */ - buf_size = src_obs * 2; memset(&ipc_buf, 0, sizeof(ipc_buf)); ipc_buf.size = buf_size; ipc_buf.comp.id = IPC4_COMP_ID(src_queue, dst_queue); ipc_buf.comp.pipeline_id = src->ipc_config.pipeline_id; - ipc_buf.comp.core = src->ipc_config.core; - return buffer_new(&ipc_buf); + ipc_buf.comp.core = cpu_get_id(); + return buffer_new(&ipc_buf, is_shared); } +#if CONFIG_CROSS_CORE_STREAM +/* + * Disabling interrupts to block next LL cycle works much faster comparing using + * of condition variable and mutex. Since same core binding is the most typical + * case, let's use slower cond_var blocking mechanism only for not so typical + * cross-core binding. + * + * Note, disabling interrupts to block LL for cross-core binding case will not work + * as .bind() handlers are called on corresponding cores using IDC tasks. IDC requires + * interrupts to be enabled. Only disabling timer interrupt instead of all interrupts + * might work. However, as CPU could go to some power down mode while waiting for + * blocking IDC call response, it's not clear how safe is to assume CPU can wakeup + * without timer interrupt. It depends on blocking IDC waiting implementation. That + * is why additional cond_var mechanism to block LL was introduced which does not + * disable any interrupts. + */ + +#define ll_block(cross_core_bind) \ + do { \ + if (cross_core_bind) \ + domain_block(sof_get()->platform_timer_domain); \ + else \ + irq_local_disable(flags); \ + } while (0) + +#define ll_unblock(cross_core_bind) \ + do { \ + if (cross_core_bind) \ + domain_unblock(sof_get()->platform_timer_domain); \ + else \ + irq_local_enable(flags); \ + } while (0) + +/* Calling both ll_block() and ll_wait_finished_on_core() makes sure LL will not start its + * next cycle and its current cycle on specified core has finished. + */ +static int ll_wait_finished_on_core(struct comp_dev *dev) +{ + /* To make sure (blocked) LL has finished its current cycle, it is + * enough to send any blocking IDC to the core. Since IDC task has lower + * priority then LL thread and cannot preempt it, execution of IDC task + * happens when LL thread is not active waiting for its next cycle. + */ + + int ret; + struct ipc4_base_module_cfg dummy; + + if (cpu_is_me(dev->ipc_config.core)) + return 0; + + /* Any blocking IDC that does not change component state could be utilized */ + ret = comp_ipc4_get_attribute_remote(dev, COMP_ATTR_BASE_CONFIG, &dummy); + if (ret < 0) { + tr_err(&ipc_tr, "comp_ipc4_get_attribute_remote() failed for module %#x", + dev_comp_id(dev)); + return ret; + } + + return 0; +} + +#else + +#define ll_block(cross_core_bind) irq_local_disable(flags) +#define ll_unblock(cross_core_bind) irq_local_enable(flags) + +#endif + int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) { struct ipc4_module_bind_unbind *bu; struct comp_buffer *buffer; - struct comp_buffer __sparse_cache *buffer_c; struct comp_dev *source; struct comp_dev *sink; struct ipc4_base_module_cfg source_src_cfg; @@ -357,10 +432,15 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) return IPC4_INVALID_RESOURCE_ID; } - /* Pass IPC to target core if both modules has the same target core */ - if (!cpu_is_me(source->ipc_config.core) && source->ipc_config.core == sink->ipc_config.core) + bool cross_core_bind = source->ipc_config.core != sink->ipc_config.core; + + /* If both components are on same core -- process IPC on that core, + * otherwise stay on core 0 + */ + if (!cpu_is_me(source->ipc_config.core) && !cross_core_bind) return ipc4_process_on_core(source->ipc_config.core, false); + /* these might call comp_ipc4_get_attribute_remote() if necessary */ ret = comp_get_attribute(source, COMP_ATTR_BASE_CONFIG, &source_src_cfg); if (ret < 0) { tr_err(&ipc_tr, "failed to get base config for module %#x", dev_comp_id(source)); @@ -373,7 +453,20 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) return IPC4_FAILURE; } - buffer = ipc4_create_buffer(source, sink, source_src_cfg.obs, bu->extension.r.src_queue, + /* create a buffer + * in case of LL -> LL or LL->DP + * size = 2*obs of source module (obs is single buffer size) + * in case of DP -> LL + * size = 2*ibs of destination (LL) module. DP queue will handle obs of DP module + */ + uint32_t buf_size; + + if (source->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL) + buf_size = source_src_cfg.obs * 2; + else + buf_size = sink_src_cfg.ibs * 2; + + buffer = ipc4_create_buffer(source, cross_core_bind, buf_size, bu->extension.r.src_queue, bu->extension.r.dst_queue); if (!buffer) { tr_err(&ipc_tr, "failed to allocate buffer to bind %d to %d", src_id, sink_id); @@ -381,23 +474,39 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) } /* - * set ibs and obs in sink/src api of created buffer - * IBS of a buffer is OBS of source component - * OBS of a buffer is IBS of destination component + * set min_free_space and min_available in sink/src api of created buffer. + * buffer is connected like: + * source_module -> (sink_ifc) BUFFER (source_ifc) -> sink_module + * + * source_module needs to set its OBS (out buffer size) + * as min_free_space in buffer's sink ifc + * sink_module needs to set its IBS (input buffer size) + * as min_available in buffer's source ifc */ - - buffer_c = buffer_acquire(buffer); - source_set_ibs(audio_stream_get_source(&buffer_c->stream), source_src_cfg.obs); - sink_set_obs(audio_stream_get_sink(&buffer_c->stream), sink_src_cfg.ibs); - buffer_release(buffer_c); + sink_set_min_free_space(audio_stream_get_sink(&buffer->stream), source_src_cfg.obs); + source_set_min_available(audio_stream_get_source(&buffer->stream), sink_src_cfg.ibs); /* - * Connect and bind the buffer to both source and sink components with the interrupts - * disabled to prevent the IPC task getting preempted which could result in buffers being - * only half connected when a pipeline task gets executed. A spinlock isn't required - * because all connected pipelines need to be on the same core. + * Connect and bind the buffer to both source and sink components with LL processing been + * blocked on corresponding core(s) to prevent IPC or IDC task getting preempted which + * could result in buffers being only half connected when a pipeline task gets executed. */ - irq_local_disable(flags); + ll_block(cross_core_bind); + + if (cross_core_bind) { +#if CONFIG_CROSS_CORE_STREAM + /* Make sure LL has finished on both cores */ + if (!cpu_is_me(source->ipc_config.core)) + if (ll_wait_finished_on_core(source) < 0) + goto free; + if (!cpu_is_me(sink->ipc_config.core)) + if (ll_wait_finished_on_core(sink) < 0) + goto free; +#else + tr_err(&ipc_tr, "Cross-core binding is disabled"); + goto free; +#endif + } ret = comp_buffer_connect(source, source->ipc_config.core, buffer, PPL_CONN_DIR_COMP_TO_BUFFER); @@ -406,7 +515,6 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) goto free; } - ret = comp_buffer_connect(sink, sink->ipc_config.core, buffer, PPL_CONN_DIR_BUFFER_TO_COMP); if (ret < 0) { @@ -414,7 +522,7 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) goto e_sink_connect; } - + /* these might call comp_ipc4_bind_remote() if necessary */ ret = comp_bind(source, bu); if (ret < 0) goto e_src_bind; @@ -435,7 +543,7 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) source->direction_set = true; } - irq_local_enable(flags); + ll_unblock(cross_core_bind); return IPC4_SUCCESS; @@ -446,7 +554,7 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) e_sink_connect: pipeline_disconnect(source, buffer, PPL_CONN_DIR_COMP_TO_BUFFER); free: - irq_local_enable(flags); + ll_unblock(cross_core_bind); buffer_free(buffer); return IPC4_INVALID_RESOURCE_STATE; } @@ -465,6 +573,7 @@ int ipc_comp_disconnect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) uint32_t src_id, sink_id, buffer_id; uint32_t flags; int ret, ret1; + bool cross_core_unbind; bu = (struct ipc4_module_bind_unbind *)_connect; src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id); @@ -481,17 +590,18 @@ int ipc_comp_disconnect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) return 0; } - /* Pass IPC to target core if both modules has the same target core */ - if (!cpu_is_me(src->ipc_config.core) && src->ipc_config.core == sink->ipc_config.core) + cross_core_unbind = src->ipc_config.core != sink->ipc_config.core; + + /* Pass IPC to target core if both modules has the same target core, + * otherwise stay on core 0 + */ + if (!cpu_is_me(src->ipc_config.core) && !cross_core_unbind) return ipc4_process_on_core(src->ipc_config.core, false); buffer_id = IPC4_COMP_ID(bu->extension.r.src_queue, bu->extension.r.dst_queue); list_for_item(sink_list, &src->bsink_list) { struct comp_buffer *buf = container_of(sink_list, struct comp_buffer, source_list); - struct comp_buffer __sparse_cache *buf_c = buffer_acquire(buf); - bool found = buf_c->id == buffer_id; - - buffer_release(buf_c); + bool found = buf->id == buffer_id; if (found) { buffer = buf; @@ -504,17 +614,39 @@ int ipc_comp_disconnect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) /* * Disconnect and unbind buffer from source/sink components and continue to free the buffer - * even in case of errors. Disable interrupts during disconnect and unbinding to prevent - * the IPC task getting preempted which could result in buffers being only half connected - * when a pipeline task gets executed. A spinlock isn't required because all connected - * pipelines need to be on the same core. + * even in case of errors. Block LL processing during disconnect and unbinding to prevent + * IPC or IDC task getting preempted which could result in buffers being only half connected + * when a pipeline task gets executed. */ - irq_local_disable(flags); + ll_block(cross_core_unbind); + + if (cross_core_unbind) { +#if CONFIG_CROSS_CORE_STREAM + /* Make sure LL has finished on both cores */ + if (!cpu_is_me(src->ipc_config.core)) + if (ll_wait_finished_on_core(src) < 0) { + ll_unblock(cross_core_unbind); + return IPC4_FAILURE; + } + if (!cpu_is_me(sink->ipc_config.core)) + if (ll_wait_finished_on_core(sink) < 0) { + ll_unblock(cross_core_unbind); + return IPC4_FAILURE; + } +#else + tr_err(&ipc_tr, "Cross-core binding is disabled"); + ll_unblock(cross_core_unbind); + return IPC4_FAILURE; +#endif + } + pipeline_disconnect(src, buffer, PPL_CONN_DIR_COMP_TO_BUFFER); pipeline_disconnect(sink, buffer, PPL_CONN_DIR_BUFFER_TO_COMP); + /* these might call comp_ipc4_bind_remote() if necessary */ ret = comp_unbind(src, bu); ret1 = comp_unbind(sink, bu); - irq_local_enable(flags); + + ll_unblock(cross_core_unbind); buffer_free(buffer); @@ -628,7 +760,7 @@ static int ipc4_update_comps_direction(struct ipc *ipc, uint32_t ppl_id) return 0; } -int ipc4_pipeline_complete(struct ipc *ipc, uint32_t comp_id) +int ipc4_pipeline_complete(struct ipc *ipc, uint32_t comp_id, uint32_t cmd) { struct ipc_comp_dev *ipc_pipe; int ret; @@ -647,9 +779,11 @@ int ipc4_pipeline_complete(struct ipc *ipc, uint32_t comp_id) * pipeline w/o connection to gateway, so direction is not configured in binding phase. * Need to update direction for such modules when pipeline is completed. */ - ret = ipc4_update_comps_direction(ipc, comp_id); - if (ret < 0) - return ret; + if (cmd != SOF_IPC4_PIPELINE_STATE_RESET) { + ret = ipc4_update_comps_direction(ipc, comp_id); + if (ret < 0) + return ret; + } return ipc_pipeline_complete(ipc, comp_id); } @@ -710,6 +844,47 @@ const struct comp_driver *ipc4_get_drv(uint8_t *uuid) return drv; } +#if CONFIG_LIBRARY +struct ipc4_module_uuid { + int module_id; + struct sof_uuid uuid; +}; + +/* Hardcoded table mapping UUIDs with module ID's. TODO: replace this with a scalable solution */ +static const struct ipc4_module_uuid uuid_map[] = { + {0x6, {.a = 0x61bca9a8, .b = 0x18d0, .c = 0x4a18, + .d = { 0x8e, 0x7b, 0x26, 0x39, 0x21, 0x98, 0x04, 0xb7 }}}, /* gain */ + {0x2, {.a = 0x39656eb2, .b = 0x3b71, .c = 0x4049, + .d = { 0x8d, 0x3f, 0xf9, 0x2c, 0xd5, 0xc4, 0x3c, 0x09 }}}, /* mixin */ + {0x3, {.a = 0x3c56505a, .b = 0x24d7, .c = 0x418f, + .d = { 0xbd, 0xdc, 0xc1, 0xf5, 0xa3, 0xac, 0x2a, 0xe0 }}}, /* mixout */ + {0x96, {.a = 0xe2b6031c, .b = 0x47e8, .c = 0x11ed, + .d = { 0x07, 0xa9, 0x7f, 0x80, 0x1b, 0x6e, 0xfa, 0x6c }}}, /* host SHM write */ + {0x98, {.a = 0xdabe8814, .b = 0x47e8, .c = 0x11ed, + .d = { 0xa5, 0x8b, 0xb3, 0x09, 0x97, 0x4f, 0xec, 0xce }}}, /* host SHM read */ + {0x97, {.a = 0x72cee996, .b = 0x39f2, .c = 0x11ed, + .d = { 0xa0, 0x8f, 0x97, 0xfc, 0xc4, 0x2e, 0xaa, 0xeb }}}, /* ALSA aplay */ + {0x99, {.a = 0x66def9f0, .b = 0x39f2, .c = 0x11ed, + .d = { 0xf7, 0x89, 0xaf, 0x98, 0xa6, 0x44, 0x0c, 0xc4 }}}, /* ALSA arecord */ +}; + +static const struct comp_driver *ipc4_library_get_drv(int module_id) +{ + const struct ipc4_module_uuid *mod_uuid; + int i; + + for (i = 0; i < ARRAY_SIZE(uuid_map); i++) { + mod_uuid = &uuid_map[i]; + + if (mod_uuid->module_id == module_id) + return ipc4_get_drv((uint8_t *)&mod_uuid->uuid); + } + + tr_err(&comp_tr, "ipc4_library_get_drv(): Unsupported module ID %#x\n", module_id); + return NULL; +} +#endif + const struct comp_driver *ipc4_get_comp_drv(int module_id) { struct sof_man_fw_desc *desc = NULL; @@ -717,6 +892,10 @@ const struct comp_driver *ipc4_get_comp_drv(int module_id) struct sof_man_module *mod; int entry_index; +#if CONFIG_LIBRARY + return ipc4_library_get_drv(module_id); +#endif + #ifdef RIMAGE_MANIFEST desc = (struct sof_man_fw_desc *)IMR_BOOT_LDR_MANIFEST_BASE; #else @@ -839,7 +1018,7 @@ void ipc4_base_module_cfg_to_stream_params(const struct ipc4_base_module_cfg *ba params->chmap[i] = (base_cfg->audio_fmt.ch_map >> i * 4) & 0xf; } -void ipc4_update_buffer_format(struct comp_buffer __sparse_cache *buf_c, +void ipc4_update_buffer_format(struct comp_buffer *buf_c, const struct ipc4_audio_format *fmt) { enum sof_ipc_frame valid_fmt, frame_fmt; diff --git a/src/ipc/ipc4/logging.c b/src/ipc/ipc4/logging.c index 08cbfa870727..15ee85560f4b 100644 --- a/src/ipc/ipc4/logging.c +++ b/src/ipc/ipc4/logging.c @@ -4,18 +4,27 @@ // // Author: Kai Vehmanen +#if CONFIG_LOG_BACKEND_SOF_PROBE && CONFIG_LOG_BACKEND_ADSP_MTRACE +#error Cannot have both backends enabled +#endif + #include #include #include #include #include #include +#if !CONFIG_LIBRARY +#include +#include +#endif +#if CONFIG_LOG_BACKEND_SOF_PROBE +#include +#endif #ifdef CONFIG_LOG_BACKEND_ADSP_MTRACE -#include #include -#include #include #include @@ -150,16 +159,45 @@ int ipc4_logging_enable_logs(bool first_block, return 0; } -int ipc4_logging_shutdown(void) +#elif CONFIG_LOG_BACKEND_SOF_PROBE + +int ipc4_logging_enable_logs(bool first_block, + bool last_block, + uint32_t data_offset_or_size, + const char *data) { - struct ipc4_log_state_info log_state = { 0 }; + const struct log_backend *log_backend = log_backend_probe_get(); + const struct ipc4_log_state_info *log_state; - /* log_state.enable set to 0 above */ + if (!(first_block && last_block)) + return -EINVAL; - return ipc4_logging_enable_logs(true, true, sizeof(log_state), (char *)&log_state); + if (data_offset_or_size < sizeof(struct ipc4_log_state_info)) + return -EINVAL; + + /* Make sure we work on correct ipc data by invalidating cache + * data may be taken from different core to the one we are working + * on right now. + */ + dcache_invalidate_region((__sparse_force void __sparse_cache *)data, data_offset_or_size); + + log_state = (const struct ipc4_log_state_info *)data; + + if (log_state->enable) { + if (!probe_is_backend_configured()) + return -EINVAL; + + log_backend_activate(log_backend, probe_logging_hook); + + } else { + log_backend_deactivate(log_backend); + } + + return 0; } -#else +#else /* unsupported logging method */ + int ipc4_logging_enable_logs(bool first_block, bool last_block, uint32_t data_offset_or_size, @@ -168,9 +206,13 @@ int ipc4_logging_enable_logs(bool first_block, return IPC4_UNKNOWN_MESSAGE_TYPE; } +#endif + int ipc4_logging_shutdown(void) { - return 0; -} + struct ipc4_log_state_info log_state = { 0 }; -#endif + /* log_state.enable set to 0 above */ + + return ipc4_logging_enable_logs(true, true, sizeof(log_state), (char *)&log_state); +} diff --git a/src/lib/dma.c b/src/lib/dma.c index 6115cfba1e85..f124a040c4c3 100644 --- a/src/lib/dma.c +++ b/src/lib/dma.c @@ -321,11 +321,11 @@ void dma_sg_free(struct dma_sg_elem_array *elem_array) dma_sg_init(elem_array); } -int dma_buffer_copy_from(struct comp_buffer __sparse_cache *source, - struct comp_buffer __sparse_cache *sink, +int dma_buffer_copy_from(struct comp_buffer *source, + struct comp_buffer *sink, dma_process_func process, uint32_t source_bytes) { - struct audio_stream __sparse_cache *istream = &source->stream; + struct audio_stream *istream = &source->stream; uint32_t samples = source_bytes / audio_stream_sample_bytes(istream); uint32_t sink_bytes = audio_stream_sample_bytes(&sink->stream) * @@ -350,11 +350,11 @@ int dma_buffer_copy_from(struct comp_buffer __sparse_cache *source, return ret; } -int dma_buffer_copy_to(struct comp_buffer __sparse_cache *source, - struct comp_buffer __sparse_cache *sink, +int dma_buffer_copy_to(struct comp_buffer *source, + struct comp_buffer *sink, dma_process_func process, uint32_t sink_bytes) { - struct audio_stream __sparse_cache *ostream = &sink->stream; + struct audio_stream *ostream = &sink->stream; uint32_t samples = sink_bytes / audio_stream_sample_bytes(ostream); uint32_t source_bytes = audio_stream_sample_bytes(&source->stream) * @@ -379,11 +379,11 @@ int dma_buffer_copy_to(struct comp_buffer __sparse_cache *source, return ret; } -int dma_buffer_copy_from_no_consume(struct comp_buffer __sparse_cache *source, - struct comp_buffer __sparse_cache *sink, +int dma_buffer_copy_from_no_consume(struct comp_buffer *source, + struct comp_buffer *sink, dma_process_func process, uint32_t source_bytes) { - struct audio_stream __sparse_cache *istream = &source->stream; + struct audio_stream *istream = &source->stream; uint32_t samples = source_bytes / audio_stream_sample_bytes(istream); uint32_t sink_bytes = audio_stream_sample_bytes(&sink->stream) * diff --git a/src/logging/log_backend_probe.c b/src/logging/log_backend_probe.c index b99da2e0a795..6baf22df2e14 100644 --- a/src/logging/log_backend_probe.c +++ b/src/logging/log_backend_probe.c @@ -109,3 +109,13 @@ void probe_logging_init(probe_logging_hook_t fn) { probe_hook = fn; } + +const struct log_backend *log_backend_probe_get(void) +{ + return &log_backend_adsp_probe; +} + +bool probe_is_backend_configured(void) +{ + return probe_hook != NULL; +} diff --git a/src/math/CMakeLists.txt b/src/math/CMakeLists.txt index d27063c80b0d..899810544864 100644 --- a/src/math/CMakeLists.txt +++ b/src/math/CMakeLists.txt @@ -1,6 +1,7 @@ # SPDX-License-Identifier: BSD-3-Clause if(BUILD_LIBRARY) + add_local_sources(sof numbers.c) return() endif() diff --git a/src/platform/Kconfig b/src/platform/Kconfig index f36c5ac2b7e4..18836cb23d3f 100644 --- a/src/platform/Kconfig +++ b/src/platform/Kconfig @@ -100,6 +100,7 @@ config IMX8M select XT_WAITI_DELAY select IMX select IMX_SDMA + select IMX_MICFIL select SCHEDULE_DMA_MULTI_CHANNEL select IMX_INTERRUPT_IRQSTEER help @@ -169,6 +170,19 @@ config VANGOGH help Select if your target platform is vangogh-compatible +config ACP_6_3 + bool "Build for ACP_6_3" + select XT_INTERRUPT_LEVEL_5 + select XT_INTERRUPT_LEVEL_3 + select XT_INTERRUPT_LEVEL_1 + select XT_INTERRUPT_LEVEL_4 + select XT_WAITI_DELAY + select XTENSA_EXCLUSIVE + select AMD + select SCHEDULE_DMA_MULTI_CHANNEL + help + Select if your target platform is acp_6_3-compatible + config MT8186 bool "Build for MTK MT8186" select XT_INTERRUPT_LEVEL_1 @@ -279,7 +293,6 @@ config CAVS select INTEL select XT_INTERRUPT_LEVEL_2 select XT_INTERRUPT_LEVEL_5 - select INTEL_HDA if !ZEPHYR_NATIVE_DRIVERS select INTEL_MN select WAKEUP_HOOK select SCHEDULE_DMA_SINGLE_CHANNEL @@ -399,6 +412,7 @@ config RIMAGE_SIGNING_SCHEMA default "rn" if RENOIR default "rmb" if REMBRANDT default "vangogh" if VANGOGH + default "acp_6_3" if ACP_6_3 default "mt8186" if MT8186 default "mt8188" if MT8188 default "mt8195" if MT8195 diff --git a/src/platform/amd/CMakeLists.txt b/src/platform/amd/CMakeLists.txt index f3c352bb17fc..b9095b3845f2 100644 --- a/src/platform/amd/CMakeLists.txt +++ b/src/platform/amd/CMakeLists.txt @@ -6,4 +6,6 @@ elseif(CONFIG_REMBRANDT) add_subdirectory(rembrandt) elseif(CONFIG_VANGOGH) add_subdirectory(vangogh) +elseif(CONFIG_ACP_6_3) + add_subdirectory(acp_6_3) endif() diff --git a/src/platform/amd/acp_6_3/CMakeLists.txt b/src/platform/amd/acp_6_3/CMakeLists.txt new file mode 100644 index 000000000000..ec909d60035f --- /dev/null +++ b/src/platform/amd/acp_6_3/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: BSD-3-Clause + +add_subdirectory(lib) + +add_local_sources(sof platform.c) diff --git a/src/platform/amd/acp_6_3/acp_6_3.x.in b/src/platform/amd/acp_6_3/acp_6_3.x.in new file mode 100644 index 000000000000..44de135f96f3 --- /dev/null +++ b/src/platform/amd/acp_6_3/acp_6_3.x.in @@ -0,0 +1,581 @@ +/* + * Linker Script for AMD ACP_6_3 + * + * This script is run through the GNU C preprocessor to align the memory + * offsets with headers. + * + * Use spaces for formatting as cpp ignore tab sizes. + */ + +#include +#include + +OUTPUT_ARCH(xtensa) + +MEMORY +{ + vector_reset_text : + org = XCHAL_RESET_VECTOR_PADDR, + len = SOF_MEM_RESET_TEXT_SIZE + vector_reset_lit : + org = XCHAL_RESET_VECTOR_PADDR + SOF_MEM_RESET_TEXT_SIZE, + len = SOF_MEM_RESET_LIT_SIZE + vector_base_text : + org = XCHAL_WINDOW_VECTORS_VADDR, //XCHAL_VECBASE_RESET_PADDR, + len = SOF_MEM_VECBASE_LIT_SIZE + vector_int2_lit : + org = XCHAL_INTLEVEL2_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_int2_text : + org = XCHAL_INTLEVEL2_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + vector_int3_lit : + org = XCHAL_INTLEVEL3_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_int3_text : + org = XCHAL_INTLEVEL3_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + vector_int4_lit : + org = XCHAL_INTLEVEL4_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_int4_text : + org = XCHAL_INTLEVEL4_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + vector_int5_lit : + org = XCHAL_INTLEVEL5_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_int5_text : + org = XCHAL_INTLEVEL5_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + vector_int6_lit : + org = XCHAL_INTLEVEL6_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_int6_text : + org = XCHAL_INTLEVEL6_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + + vector_int7_lit : + org = XCHAL_INTLEVEL7_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_int7_text : + org = XCHAL_INTLEVEL7_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + vector_kernel_lit : + org = XCHAL_KERNEL_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_kernel_text : + org = XCHAL_KERNEL_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + vector_user_lit : + org = XCHAL_USER_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_user_text : + org = XCHAL_USER_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + vector_double_lit : + org = XCHAL_DOUBLEEXC_VECTOR_PADDR - SOF_MEM_VECT_LIT_SIZE, + len = SOF_MEM_VECT_LIT_SIZE + vector_double_text : + org = XCHAL_DOUBLEEXC_VECTOR_PADDR, + len = SOF_MEM_VECT_TEXT_SIZE + sof_iram_text_start : + org = XCHAL_DOUBLEEXC_VECTOR_PADDR + SOF_MEM_VECT_TEXT_SIZE, + len = IRAM_BASE + (XCHAL_DOUBLEEXC_VECTOR_PADDR + SOF_MEM_VECT_TEXT_SIZE) + sof_sdram0 : + org = DRAM0_BASE, + len = DRAM0_SIZE + DRAM1_SIZE - SOF_STACK_SIZE + system_heap : + org = HEAP_SYSTEM_BASE, + len = HEAP_SYSTEM_SIZE + system_runtime_heap : + org = HEAP_SYS_RUNTIME_BASE, + len = HEAP_SYS_RUNTIME_SIZE + runtime_heap : + org = HEAP_RUNTIME_BASE, + len = HEAP_RUNTIME_SIZE + buffer_heap : + org = HEAP_BUFFER_BASE, + len = HEAP_BUFFER_SIZE + sof_stack : + org = SOF_STACK_END, + len = SOF_STACK_BASE - SOF_STACK_END, +sof_sdram1 : + org = DRAM1_BASE, + len = DRAM1_SIZE +sof_sram1 : + org = SRAM1_BASE, + len = SRAM1_SIZE + static_uuid_entries_seg (!ari) : + org = UUID_ENTRY_ELF_BASE, + len = UUID_ENTRY_ELF_SIZE + static_log_entries_seg (!ari) : + org = LOG_ENTRY_ELF_BASE, + len = LOG_ENTRY_ELF_SIZE + fw_metadata_seg (!ari) : + org = EXT_MANIFEST_ELF_BASE, + len = EXT_MANIFEST_ELF_SIZE +} + +PHDRS +{ + vector_reset_text_phdr PT_LOAD; + vector_reset_lit_phdr PT_LOAD; + vector_base_text_phdr PT_LOAD; + vector_base_lit_phdr PT_LOAD; + vector_int2_text_phdr PT_LOAD; + vector_int2_lit_phdr PT_LOAD; + vector_int3_text_phdr PT_LOAD; + vector_int3_lit_phdr PT_LOAD; + vector_int4_text_phdr PT_LOAD; + vector_int4_lit_phdr PT_LOAD; + vector_int5_text_phdr PT_LOAD; + vector_int5_lit_phdr PT_LOAD; + vector_int6_text_phdr PT_LOAD; + vector_int6_lit_phdr PT_LOAD; + vector_int7_text_phdr PT_LOAD; + vector_int7_lit_phdr PT_LOAD; + vector_kernel_text_phdr PT_LOAD; + vector_kernel_lit_phdr PT_LOAD; + vector_user_text_phdr PT_LOAD; + vector_user_lit_phdr PT_LOAD; + vector_double_text_phdr PT_LOAD; + vector_double_lit_phdr PT_LOAD; + sof_iram_text_start_phdr PT_LOAD; + sof_sdram0_phdr PT_LOAD; + sof_sram1_phdr PT_LOAD; + sof_stack_phdr PT_LOAD; + system_heap_phdr PT_LOAD; + system_runtime_heap_phdr PT_LOAD; + runtime_heap_phdr PT_LOAD; + buffer_heap_phdr PT_LOAD; + sof_sdram1_phdr PT_LOAD; + static_uuid_entries_phdr PT_NOTE; + static_log_entries_phdr PT_NOTE; + metadata_entries_phdr PT_NOTE; +} + +/* Default entry point: */ +ENTRY(_ResetVector) +_rom_store_table = 0; + +/* ABI0 does not use Window base */ +PROVIDE(_memmap_vecbase_reset = XCHAL_WINDOW_VECTORS_VADDR); + +/* Various memory-map dependent cache attribute settings: */ +_memmap_cacheattr_wb_base = 0x20004400; +_memmap_cacheattr_wt_base = 0x20001100; +_memmap_cacheattr_bp_base = 0x20002200; +_memmap_cacheattr_unused_mask = 0x0FFF00FF; +_memmap_cacheattr_wb_trapnull = 0x2222442F; +_memmap_cacheattr_wba_trapnull = 0x2222442F; +_memmap_cacheattr_wbna_trapnull = 0x2222552F; +_memmap_cacheattr_wt_trapnull = 0x2222112F; +_memmap_cacheattr_bp_trapnull = 0x2222222F; +_memmap_cacheattr_wb_strict = 0x2FFF44FF; +_memmap_cacheattr_wt_strict = 0x2FFF11FF; +_memmap_cacheattr_bp_strict = 0x2FFF22FF; +_memmap_cacheattr_wb_allvalid = 0x22224422; +_memmap_cacheattr_wt_allvalid = 0x22221122; +_memmap_cacheattr_bp_allvalid = 0x22222222; +PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wbna_trapnull); +_EXT_MAN_ALIGN_ = 16; +EXTERN(ext_man_fw_ver) + + +SECTIONS +{ + .ResetVector.text : ALIGN(4) + { + _ResetVector_text_start = ABSOLUTE(.); + KEEP (*(.ResetVector.text)) + _ResetVector_text_end = ABSOLUTE(.); + } >vector_reset_text :vector_reset_text_phdr + + .ResetVector.literal : ALIGN(4) + { + _ResetVector_literal_start = ABSOLUTE(.); + *(.ResetVector.literal) + _ResetVector_literal_end = ABSOLUTE(.); + } >vector_reset_lit :vector_reset_lit_phdr + + .WindowVectors.text : ALIGN(4) + { + _WindowVectors_text_start = ABSOLUTE(.); + KEEP (*(.WindowVectors.text)) + _WindowVectors_text_end = ABSOLUTE(.); + } >vector_base_text :vector_base_text_phdr + + .Level2InterruptVector.literal : ALIGN(4) + { + _Level2InterruptVector_literal_start = ABSOLUTE(.); + *(.Level2InterruptVector.literal) + _Level2InterruptVector_literal_end = ABSOLUTE(.); + } >vector_int2_lit :vector_int2_lit_phdr + + .Level2InterruptVector.text : ALIGN(4) + { + _Level2InterruptVector_text_start = ABSOLUTE(.); + KEEP (*(.Level2InterruptVector.text)) + _Level2InterruptVector_text_end = ABSOLUTE(.); + } >vector_int2_text :vector_int2_text_phdr + + .Level3InterruptVector.literal : ALIGN(4) + { + _Level3InterruptVector_literal_start = ABSOLUTE(.); + *(.Level3InterruptVector.literal) + _Level3InterruptVector_literal_end = ABSOLUTE(.); + } >vector_int3_lit :vector_int3_lit_phdr + + .Level3InterruptVector.text : ALIGN(4) + { + _Level3InterruptVector_text_start = ABSOLUTE(.); + KEEP (*(.Level3InterruptVector.text)) + _Level3InterruptVector_text_end = ABSOLUTE(.); + } >vector_int3_text :vector_int3_text_phdr + + .Level4InterruptVector.literal : ALIGN(4) + { + _Level4InterruptVector_literal_start = ABSOLUTE(.); + *(.Level4InterruptVector.literal) + _Level4InterruptVector_literal_end = ABSOLUTE(.); + } >vector_int4_lit :vector_int4_lit_phdr + + .Level4InterruptVector.text : ALIGN(4) + { + _Level4InterruptVector_text_start = ABSOLUTE(.); + KEEP (*(.Level4InterruptVector.text)) + _Level4InterruptVector_text_end = ABSOLUTE(.); + } >vector_int4_text :vector_int4_text_phdr + + .Level5InterruptVector.literal : ALIGN(4) + { + _Level5InterruptVector_literal_start = ABSOLUTE(.); + *(.Level5InterruptVector.literal) + _Level5InterruptVector_literal_end = ABSOLUTE(.); + } >vector_int5_lit :vector_int5_lit_phdr + + .Level5InterruptVector.text : ALIGN(4) + { + _Level5InterruptVector_text_start = ABSOLUTE(.); + KEEP (*(.Level5InterruptVector.text)) + _Level5InterruptVector_text_end = ABSOLUTE(.); + } >vector_int5_text :vector_int5_text_phdr + + .DebugExceptionVector.literal : ALIGN(4) + { + _DebugExceptionVector_literal_start = ABSOLUTE(.); + *(.DebugExceptionVector.literal) + _DebugExceptionVector_literal_end = ABSOLUTE(.); + } >vector_int6_lit :vector_int6_lit_phdr + + .DebugExceptionVector.text : ALIGN(4) + { + _DebugExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.DebugExceptionVector.text)) + _DebugExceptionVector_text_end = ABSOLUTE(.); + } >vector_int6_text :vector_int6_text_phdr + + .NMIExceptionVector.literal : ALIGN(4) + { + _NMIExceptionVector_literal_start = ABSOLUTE(.); + *(.NMIExceptionVector.literal) + _NMIExceptionVector_literal_end = ABSOLUTE(.); + } >vector_int7_lit :vector_int5_lit_phdr + + .NMIExceptionVector.text : ALIGN(4) + { + _NMIExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.NMIExceptionVector.text)) + _NMIExceptionVector_text_end = ABSOLUTE(.); + } >vector_int7_text :vector_int5_text_phdr + + .KernelExceptionVector.literal : ALIGN(4) + { + _KernelExceptionVector_literal_start = ABSOLUTE(.); + *(.KernelExceptionVector.literal) + _KernelExceptionVector_literal_end = ABSOLUTE(.); + } >vector_kernel_lit :vector_kernel_lit_phdr + + .KernelExceptionVector.text : ALIGN(4) + { + _KernelExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.KernelExceptionVector.text)) + _KernelExceptionVector_text_end = ABSOLUTE(.); + } >vector_kernel_text :vector_kernel_text_phdr + + .UserExceptionVector.literal : ALIGN(4) + { + _UserExceptionVector_literal_start = ABSOLUTE(.); + *(.UserExceptionVector.literal) + _UserExceptionVector_literal_end = ABSOLUTE(.); + } >vector_user_lit :vector_user_lit_phdr + + .UserExceptionVector.text : ALIGN(4) + { + _UserExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.UserExceptionVector.text)) + _UserExceptionVector_text_end = ABSOLUTE(.); + } >vector_user_text :vector_user_text_phdr + + .DoubleExceptionVector.literal : ALIGN(4) + { + _DoubleExceptionVector_literal_start = ABSOLUTE(.); + *(.DoubleExceptionVector.literal) + _DoubleExceptionVector_literal_end = ABSOLUTE(.); + } >vector_double_lit :vector_double_lit_phdr + + .DoubleExceptionVector.text : ALIGN(4) + { + _DoubleExceptionVector_text_start = ABSOLUTE(.); + KEEP (*(.DoubleExceptionVector.text)) + _DoubleExceptionVector_text_end = ABSOLUTE(.); + } >vector_double_text :vector_double_text_phdr + + .iram.text : ALIGN(4) + { + _stext = .; + _iram_text_start = ABSOLUTE(.); + *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) + _iram_text_end = ABSOLUTE(.); + } >sof_iram_text_start :sof_iram_text_start_phdr + + /* stack */ + _end = SOF_STACK_END; + PROVIDE(end = SOF_STACK_END); + _stack_sentry = SOF_STACK_END; + __stack = SOF_STACK_BASE; + + .text : ALIGN(4) + { + _stext = .; + _text_start = ABSOLUTE(.); + *(.entry.text) + *(.init.literal) + KEEP(*(.init)) + *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.fini.literal) + KEEP(*(.fini)) + *(.gnu.version) + _text_end = ABSOLUTE(.); + _etext = .; + } >sof_iram_text_start :sof_iram_text_start_phdr + + .rodata : ALIGN(4) + { + _rodata_start = ABSOLUTE(.); + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); + KEEP (*(.xt_except_table)) + KEEP (*(.gcc_except_table)) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + KEEP (*(.eh_frame)) + /* C++ constructor and destructor tables, properly ordered: */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS__ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + . = ALIGN(4); /* this table MUST be 4-byte aligned */ + _bss_table_start = ABSOLUTE(.); + LONG(_bss_start) + LONG(_bss_end) + _bss_table_end = ABSOLUTE(.); + _rodata_end = ABSOLUTE(.); + } >sof_sram1 :sof_sram1_phdr + + .module_init : ALIGN(4) + { + _module_init_start = ABSOLUTE(.); + *(*.initcall) + _module_init_end = ABSOLUTE(.); + } >sof_sram1 :sof_sram1_phdr + + .data : ALIGN(4) + { + _data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + KEEP(*(.gnu.linkonce.d.*personality*)) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + KEEP(*(.jcr)) + _trace_ctx_start = ABSOLUTE(.); + *(.trace_ctx) + _trace_ctx_end = ABSOLUTE(.); + _data_end = ABSOLUTE(.); + } >sof_sram1 :sof_sram1_phdr + + .lit4 : ALIGN(4) + { + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + } >sof_sram1 :sof_sram1_phdr + + .fw_ready : ALIGN(4) + { + KEEP (*(.fw_ready)) + } >sof_sram1 :sof_sram1_phdr + + + .bss (NOLOAD) : ALIGN(8) + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + _bss_end = ABSOLUTE(.); + } >sof_sram1 :sof_sram1_phdr + + +.sof_stack (NOLOAD) : ALIGN(8) + { + . = ALIGN (4096); + _sof_stack_start = ABSOLUTE(.); + . = . + SOF_STACK_TOTAL_SIZE; + _sof_stack_end = ABSOLUTE(.); + } >sof_stack :sof_stack_phdr + + .reset.rodata : ALIGN(4) + { + _reset_rodata_start = ABSOLUTE(.); + *(.reset.rodata) + _reset_rodata_end = ABSOLUTE(.); + } >sof_sram1 :sof_sram1_phdr + + + .system_heap (NOLOAD) : ALIGN(8) + { + . = ALIGN (32); + _system_heap_start = ABSOLUTE(.); + . = . + HEAP_SYSTEM_SIZE; + _system_heap_end = ABSOLUTE(.); + } >system_heap :system_heap_phdr + + .system_runtime_heap (NOLOAD) : ALIGN(8) + { + . = ALIGN (HEAP_BUF_ALIGNMENT); + _system_runtime_heap_start = ABSOLUTE(.); + . = . + HEAP_SYS_RUNTIME_SIZE; + _system_runtime_heap_end = ABSOLUTE(.); + } >system_runtime_heap :system_runtime_heap_phdr + + .runtime_heap (NOLOAD) : ALIGN(8) + { + . = ALIGN (32); + _runtime_heap_start = ABSOLUTE(.); + . = . + HEAP_RUNTIME_SIZE; + _runtime_heap_end = ABSOLUTE(.); + } >runtime_heap :runtime_heap_phdr + + .buffer_heap (NOLOAD) : ALIGN(8) + { + . = ALIGN (HEAP_BUF_ALIGNMENT); + _buffer_heap_start = ABSOLUTE(.); + . = . + HEAP_BUFFER_SIZE; + _buffer_heap_end = ABSOLUTE(.); + } >buffer_heap :buffer_heap_phdr + + .static_uuid_entries (COPY) : ALIGN(1024) + { + *(*.static_uuids) + } > static_uuid_entries_seg :static_uuid_entries_phdr + + .static_log_entries (COPY) : ALIGN(1024) + { + *(*.static_log*) + } > static_log_entries_seg :static_log_entries_phdr + + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + .xt.insn 0 : + { + KEEP (*(.xt.insn)) + KEEP (*(.gnu.linkonce.x.*)) + } + .xt.prop 0 : + { + KEEP (*(.xt.prop)) + KEEP (*(.xt.prop.*)) + KEEP (*(.gnu.linkonce.prop.*)) + } + .xt.lit 0 : + { + KEEP (*(.xt.lit)) + KEEP (*(.xt.lit.*)) + KEEP (*(.gnu.linkonce.p.*)) + } + .xt.profile_range 0 : + { + KEEP (*(.xt.profile_range)) + KEEP (*(.gnu.linkonce.profile_range.*)) + } + .xt.profile_ranges 0 : + { + KEEP (*(.xt.profile_ranges)) + KEEP (*(.gnu.linkonce.xt.profile_ranges.*)) + } + .xt.profile_files 0 : + { + KEEP (*(.xt.profile_files)) + KEEP (*(.gnu.linkonce.xt.profile_files.*)) + } + + .fw_metadata (COPY) : ALIGN(1024) + { + KEEP (*(.fw_metadata)) + . = ALIGN(_EXT_MAN_ALIGN_); + } >fw_metadata_seg :metadata_entries_phdr + +} diff --git a/src/platform/amd/acp_6_3/include/arch/xtensa/config/core-isa.h b/src/platform/amd/acp_6_3/include/arch/xtensa/config/core-isa.h new file mode 100644 index 000000000000..e006725edc39 --- /dev/null +++ b/src/platform/amd/acp_6_3/include/arch/xtensa/config/core-isa.h @@ -0,0 +1,714 @@ +/* + * xtensa/config/core-isa.h -- HAL definitions that are dependent on Xtensa + * processor CORE configuration + * + * See , which includes this file, for more details. + */ + +/* Xtensa processor core configuration information. + + Customer ID=7490; Build=0xa28f5; Copyright (c) 1999-2022 Tensilica 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 XTENSA_CORE_CONFIGURATION_H_ +#define XTENSA_CORE_CONFIGURATION_H_ + + +/**************************************************************************** + Parameters Useful for Any Code, USER or PRIVILEGED + ****************************************************************************/ + +/* + * Note: Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is + * configured, and a value of 0 otherwise. These macros are always defined. + */ + + +/*---------------------------------------------------------------------- + ISA + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_BE 0 /* big-endian byte ordering */ +#define XCHAL_HAVE_WINDOWED 1 /* windowed registers option */ +#define XCHAL_NUM_AREGS 64 /* num of physical addr regs */ +#define XCHAL_NUM_AREGS_LOG2 6 /* log2(XCHAL_NUM_AREGS) */ +#define XCHAL_MAX_INSTRUCTION_SIZE 16 /* max instr bytes (3..8) */ +#define XCHAL_HAVE_DEBUG 1 /* debug option */ +#define XCHAL_HAVE_DENSITY 1 /* 16-bit instructions */ +#define XCHAL_HAVE_LOOPS 1 /* zero-overhead loops */ +#define XCHAL_LOOP_BUFFER_SIZE 256 /* zero-ov. loop instr buffer size */ +#define XCHAL_HAVE_NSA 1 /* NSA/NSAU instructions */ +#define XCHAL_HAVE_MINMAX 1 /* MIN/MAX instructions */ +#define XCHAL_HAVE_SEXT 1 /* SEXT instruction */ +#define XCHAL_HAVE_DEPBITS 0 /* DEPBITS instruction */ +#define XCHAL_HAVE_CLAMPS 1 /* CLAMPS instruction */ +#define XCHAL_HAVE_MUL16 1 /* MUL16S/MUL16U instructions */ +#define XCHAL_HAVE_MUL32 1 /* MULL instruction */ +#define XCHAL_HAVE_MUL32_HIGH 1 /* MULUH/MULSH instructions */ +#define XCHAL_HAVE_DIV32 1 /* QUOS/QUOU/REMS/REMU instructions */ +#define XCHAL_HAVE_L32R 1 /* L32R instruction */ +#define XCHAL_HAVE_ABSOLUTE_LITERALS 0 /* non-PC-rel (extended) L32R */ +#define XCHAL_HAVE_CONST16 0 /* CONST16 instruction */ +#define XCHAL_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */ +#define XCHAL_HAVE_EXCLUSIVE 0 /* L32EX/S32EX instructions */ +#define XCHAL_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */ +#define XCHAL_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */ +#define XCHAL_HAVE_CALL4AND12 1 /* (obsolete option) */ +#define XCHAL_HAVE_ABS 1 /* ABS instruction */ +#define XCHAL_HAVE_RELEASE_SYNC 1 /* L32AI/S32RI instructions */ +#define XCHAL_HAVE_S32C1I 1 /* S32C1I instruction */ +#define XCHAL_HAVE_SPECULATION 0 /* speculation */ +#define XCHAL_HAVE_FULL_RESET 1 /* all regs/state reset */ +#define XCHAL_NUM_CONTEXTS 1 /* */ +#define XCHAL_NUM_MISC_REGS 2 /* num of scratch regs (0..4) */ +#define XCHAL_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */ +#define XCHAL_HAVE_PRID 0 /* processor ID register */ +#define XCHAL_HAVE_EXTERN_REGS 1 /* WER/RER instructions */ +#define XCHAL_HAVE_MX 0 /* MX core (Tensilica internal) */ +#define XCHAL_HAVE_MP_INTERRUPTS 0 /* interrupt distributor port */ +#define XCHAL_HAVE_MP_RUNSTALL 0 /* core RunStall control port */ +#define XCHAL_HAVE_PSO 0 /* Power Shut-Off */ +#define XCHAL_HAVE_PSO_CDM 0 /* core/debug/mem pwr domains */ +#define XCHAL_HAVE_PSO_FULL_RETENTION 0 /* all regs preserved on PSO */ +#define XCHAL_HAVE_THREADPTR 1 /* THREADPTR register */ +#define XCHAL_HAVE_BOOLEANS 1 /* boolean registers */ +#define XCHAL_HAVE_CP 1 /* CPENABLE reg (coprocessor) */ +#define XCHAL_CP_MAXCFG 2 /* max allowed cp id plus one */ +#define XCHAL_HAVE_MAC16 0 /* MAC16 package */ +#define XCHAL_HAVE_LX 1 /* LX core */ +#define XCHAL_HAVE_NX 0 /* NX core (starting RH) */ + +#define XCHAL_HAVE_SUPERGATHER 0 /* SuperGather */ + +#define XCHAL_HAVE_FUSION 0 /* Fusion*/ +#define XCHAL_HAVE_FUSION_FP 0 /* Fusion FP option */ +#define XCHAL_HAVE_FUSION_LOW_POWER 0 /* Fusion Low Power option */ +#define XCHAL_HAVE_FUSION_AES 0 /* Fusion BLE/Wifi AES-128 CCM option */ +#define XCHAL_HAVE_FUSION_CONVENC 0 /* Fusion Conv Encode option */ +#define XCHAL_HAVE_FUSION_LFSR_CRC 0 /* Fusion LFSR-CRC option */ +#define XCHAL_HAVE_FUSION_BITOPS 0 /* Fusion Bit Operations Support option */ +#define XCHAL_HAVE_FUSION_AVS 0 /* Fusion AVS option */ +#define XCHAL_HAVE_FUSION_16BIT_BASEBAND 0 /* Fusion 16-bit Baseband option */ +#define XCHAL_HAVE_FUSION_VITERBI 0 /* Fusion Viterbi option */ +#define XCHAL_HAVE_FUSION_SOFTDEMAP 0 /* Fusion Soft Bit Demap option */ +#define XCHAL_HAVE_HIFIPRO 0 /* HiFiPro Audio Engine pkg */ +#define XCHAL_HAVE_HIFI5 1 /* HiFi5 Audio Engine pkg */ +#define XCHAL_HAVE_HIFI5_NN_MAC 1 /* HiFi5 Audio Engine NN-MAC option */ +#define XCHAL_HAVE_HIFI5_VFPU 1 /* HiFi5 Audio Engine Single-Precision VFPU option */ +#define XCHAL_HAVE_HIFI5_HP_VFPU 1 /* HiFi5 Audio Engine Half-Precision VFPU option */ +#define XCHAL_HAVE_HIFI4 0 /* HiFi4 Audio Engine pkg */ +#define XCHAL_HAVE_HIFI4_VFPU 1 /* HiFi4 Audio Engine VFPU option */ +#define XCHAL_HAVE_HIFI3 1 /* HiFi3 Audio Engine pkg */ +#define XCHAL_HAVE_HIFI3_VFPU 1 /* HiFi3 Audio Engine VFPU option */ +#define XCHAL_HAVE_HIFI3Z 0 /* HiFi3Z Audio Engine pkg */ +#define XCHAL_HAVE_HIFI3Z_VFPU 0 /* HiFi3Z Audio Engine VFPU option */ +#define XCHAL_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */ +#define XCHAL_HAVE_HIFI2EP 0 /* HiFi2EP */ +#define XCHAL_HAVE_HIFI_MINI 0 + + + +#define XCHAL_HAVE_VECTORFPU2005 0 /* vector floating-point pkg */ +#define XCHAL_HAVE_USER_DPFPU 0 /* user DP floating-point pkg */ +#define XCHAL_HAVE_USER_SPFPU 1 /* user SP floating-point pkg */ +#define XCHAL_HAVE_FP 1 /* single prec floating point */ +#define XCHAL_HAVE_FP_DIV 1 /* FP with DIV instructions */ +#define XCHAL_HAVE_FP_RECIP 1 /* FP with RECIP instructions */ +#define XCHAL_HAVE_FP_SQRT 1 /* FP with SQRT instructions */ +#define XCHAL_HAVE_FP_RSQRT 1 /* FP with RSQRT instructions */ +#define XCHAL_HAVE_DFP 0 /* double precision FP pkg */ +#define XCHAL_HAVE_DFP_DIV 0 /* DFP with DIV instructions */ +#define XCHAL_HAVE_DFP_RECIP 0 /* DFP with RECIP instructions*/ +#define XCHAL_HAVE_DFP_SQRT 0 /* DFP with SQRT instructions */ +#define XCHAL_HAVE_DFP_RSQRT 0 /* DFP with RSQRT instructions*/ +#define XCHAL_HAVE_DFP_ACCEL 0 /* double precision FP acceleration pkg */ +#define XCHAL_HAVE_DFP_accel XCHAL_HAVE_DFP_ACCEL /* for backward compatibility */ + +#define XCHAL_HAVE_DFPU_SINGLE_ONLY 0 /* DFPU Coprocessor, single precision only */ +#define XCHAL_HAVE_DFPU_SINGLE_DOUBLE 0 /* DFPU Coprocessor, single and double precision */ +#define XCHAL_HAVE_VECTRA1 0 /* Vectra I pkg */ +#define XCHAL_HAVE_VECTRALX 0 /* Vectra LX pkg */ + +#define XCHAL_HAVE_FUSIONG 0 /* FusionG */ +#define XCHAL_HAVE_FUSIONG3 0 /* FusionG3 */ +#define XCHAL_HAVE_FUSIONG6 0 /* FusionG6 */ +#define XCHAL_HAVE_FUSIONG_SP_VFPU 0 /* sp_vfpu option on FusionG */ +#define XCHAL_HAVE_FUSIONG_DP_VFPU 0 /* dp_vfpu option on FusionG */ +#define XCHAL_FUSIONG_SIMD32 0 /* simd32 for FusionG */ + +#define XCHAL_HAVE_FUSIONJ 0 /* FusionJ */ +#define XCHAL_HAVE_FUSIONJ6 0 /* FusionJ6 */ +#define XCHAL_HAVE_FUSIONJ_SP_VFPU 0 /* sp_vfpu option on FusionJ */ +#define XCHAL_HAVE_FUSIONJ_DP_VFPU 0 /* dp_vfpu option on FusionJ */ +#define XCHAL_FUSIONJ_SIMD32 0 /* simd32 for FusionJ */ + +#define XCHAL_HAVE_PDX 0 /* PDX-LX */ +#define XCHAL_PDX_SIMD32 0 /* simd32 for PDX */ +#define XCHAL_HAVE_PDX4 0 /* PDX4-LX */ +#define XCHAL_HAVE_PDX8 0 /* PDX8-LX */ +#define XCHAL_HAVE_PDX16 0 /* PDX16-LX */ +#define XCHAL_HAVE_PDXNX 0 /* PDX-NX */ + +#define XCHAL_HAVE_CONNXD2 0 /* ConnX D2 pkg */ +#define XCHAL_HAVE_CONNXD2_DUALLSFLIX 0 /* ConnX D2 & Dual LoadStore Flix */ +#define XCHAL_HAVE_BALL 0 +#define XCHAL_HAVE_BALLAP 0 +#define XCHAL_HAVE_BBE16 0 /* ConnX BBE16 pkg */ +#define XCHAL_HAVE_BBE16_RSQRT 0 /* BBE16 & vector recip sqrt */ +#define XCHAL_HAVE_BBE16_VECDIV 0 /* BBE16 & vector divide */ +#define XCHAL_HAVE_BBE16_DESPREAD 0 /* BBE16 & despread */ +#define XCHAL_HAVE_CONNX_B10 0 /* ConnX B10 pkg*/ +#define XCHAL_HAVE_CONNX_B20 0 /* ConnX B20 pkg*/ +#define XCHAL_HAVE_CONNX_B_DP_VFPU 0 /* Double-precision Vector Floating-point option on ConnX B10 & B20 */ +#define XCHAL_HAVE_CONNX_B_SP_VFPU 0 /* Single-precision Vector Floating-point option on ConnX B10 & B20 */ +#define XCHAL_HAVE_CONNX_B_SPX_VFPU 0 /* Single-precision Extended Vector Floating-point option on ConnX B10 & B20 */ +#define XCHAL_HAVE_CONNX_B_HPX_VFPU 0 /* Half-precision Extended Vector Floating-point option on ConnX B10 & B20 */ +#define XCHAL_HAVE_CONNX_B_32B_MAC 0 /* 32-bit vector MAC (real and complex), FIR & FFT option on ConnX B10 & B20 */ +#define XCHAL_HAVE_CONNX_B_VITERBI 0 /* Viterbi option on ConnX B10 & B20 */ +#define XCHAL_HAVE_CONNX_B_TURBO 0 /* Turbo option on ConnX B10 & B20 */ +#define XCHAL_HAVE_CONNX_B_LDPC 0 /* LDPC option on ConnX B10 & B20 */ +#define XCHAL_HAVE_BBENEP 0 /* ConnX BBENEP pkgs */ +#define XCHAL_HAVE_BBENEP_SP_VFPU 0 /* sp_vfpu option on BBE-EP */ +#define XCHAL_HAVE_BSP3 0 /* ConnX BSP3 pkg */ +#define XCHAL_HAVE_BSP3_TRANSPOSE 0 /* BSP3 & transpose32x32 */ +#define XCHAL_HAVE_SSP16 0 /* ConnX SSP16 pkg */ +#define XCHAL_HAVE_SSP16_VITERBI 0 /* SSP16 & viterbi */ +#define XCHAL_HAVE_TURBO16 0 /* ConnX Turbo16 pkg */ +#define XCHAL_HAVE_BBP16 0 /* ConnX BBP16 pkg */ +#define XCHAL_HAVE_FLIX3 0 /* basic 3-way FLIX option */ +#define XCHAL_HAVE_GRIVPEP 0 /* General Release of IVPEP */ +#define XCHAL_HAVE_GRIVPEP_HISTOGRAM 0 /* Histogram option on GRIVPEP */ + +#define XCHAL_HAVE_VISION 0 /* Vision P5/P6 */ +#define XCHAL_VISION_SIMD16 0 /* simd16 for Vision P5/P6 */ +#define XCHAL_VISION_TYPE 0 /* Vision P5, P6, Q6, Q7 or Q8 */ +#define XCHAL_VISION_QUAD_MAC_TYPE 0 /* quad_mac option on Vision P6 */ +#define XCHAL_HAVE_VISION_HISTOGRAM 0 /* histogram option on Vision P5/P6 */ +#define XCHAL_HAVE_VISION_DP_VFPU 0 /* dp_vfpu option on Vision Q7/Q8 */ +#define XCHAL_HAVE_VISION_SP_VFPU 0 /* sp_vfpu option on Vision P5/P6/Q6/Q7 */ +#define XCHAL_HAVE_VISION_SP_VFPU_2XFMAC 0 /* sp_vfpu_2xfma option on Vision Q7 */ +#define XCHAL_HAVE_VISION_HP_VFPU 0 /* hp_vfpu option on Vision P6/Q6 */ +#define XCHAL_HAVE_VISION_HP_VFPU_2XFMAC 0 /* hp_vfpu_2xfma option on Vision Q7 */ + +#define XCHAL_HAVE_VISIONC 0 /* Vision C */ + +#define XCHAL_HAVE_XNNE 0 /* XNNE */ + +/*---------------------------------------------------------------------- + MISC + ----------------------------------------------------------------------*/ + +#define XCHAL_NUM_LOADSTORE_UNITS 2 /* load/store units */ +#define XCHAL_NUM_WRITEBUFFER_ENTRIES 16 /* size of write buffer */ +#define XCHAL_INST_FETCH_WIDTH 16 /* instr-fetch width in bytes */ +#define XCHAL_DATA_WIDTH 16 /* data width in bytes */ +#define XCHAL_DATA_PIPE_DELAY 2 /* d-side pipeline delay + (1 = 5-stage, 2 = 7-stage) */ +#define XCHAL_CLOCK_GATING_GLOBAL 1 /* global clock gating */ +#define XCHAL_CLOCK_GATING_FUNCUNIT 1 /* funct. unit clock gating */ +/* In T1050, applies to selected core load and store instructions (see ISA): */ +#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */ +#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/ +#define XCHAL_UNALIGNED_LOAD_HW 0 /* unaligned loads work in hw */ +#define XCHAL_UNALIGNED_STORE_HW 0 /* unaligned stores work in hw*/ + +#define XCHAL_UNIFIED_LOADSTORE 0 + +#define XCHAL_SW_VERSION 1406000 /* sw version of this header */ +#define XCHAL_SW_VERSION_MAJOR 14000 /* major ver# of sw */ +#define XCHAL_SW_VERSION_MINOR 6 /* minor ver# of sw */ +#define XCHAL_SW_VERSION_MICRO 0 /* micro ver# of sw */ +#define XCHAL_SW_MINOR_VERSION 1406000 /* with zeroed micro */ +#define XCHAL_SW_MICRO_VERSION 1406000 + +#define XCHAL_CORE_ID "ACP_6_3_HiFi5_PROD_Linux" /* alphanum core name + (CoreID) set in the Xtensa + Processor Generator */ + +#define XCHAL_BUILD_UNIQUE_ID 0x000A28F5 /* 22-bit sw build ID */ + +/* + * These definitions describe the hardware targeted by this software. + */ +#define XCHAL_HW_CONFIGID0 0xC3038286 /* ConfigID hi 32 bits*/ +#define XCHAL_HW_CONFIGID1 0x29892812 /* ConfigID lo 32 bits*/ +#define XCHAL_HW_VERSION_NAME "LX7.1.6" /* full version name */ +#define XCHAL_HW_VERSION_MAJOR 2810 /* major ver# of targeted hw */ +#define XCHAL_HW_VERSION_MINOR 6 /* minor ver# of targeted hw */ +#define XCHAL_HW_VERSION_MICRO 0 /* subdot ver# of targeted hw */ +#define XCHAL_HW_VERSION 281060 /* major*100+(major<2810 ? minor : minor*10+micro) */ +#define XCHAL_HW_REL_LX7 1 +#define XCHAL_HW_REL_LX7_1 1 +#define XCHAL_HW_REL_LX7_1_6 1 +#define XCHAL_HW_CONFIGID_RELIABLE 1 +/* If software targets a *range* of hardware versions, these are the bounds: */ +#define XCHAL_HW_MIN_VERSION_MAJOR 2810 /* major v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION_MINOR 6 /* minor v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION_MICRO 0 /* micro v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION 281060 /* earliest targeted hw */ +#define XCHAL_HW_MAX_VERSION_MAJOR 2810 /* major v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION_MINOR 6 /* minor v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION_MICRO 0 /* micro v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION 281060 /* latest targeted hw */ + +/* Config is enabled for functional safety: */ +#define XCHAL_HAVE_FUNC_SAFETY 0 + +/* Config is enabled for secure operation: */ +#define XCHAL_HAVE_SECURE 0 + +#define XCHAL_HAVE_APB 0 + +/*---------------------------------------------------------------------- + CACHE + ----------------------------------------------------------------------*/ + +#define XCHAL_ICACHE_LINESIZE 128 /* I-cache line size in bytes */ +#define XCHAL_DCACHE_LINESIZE 128 /* D-cache line size in bytes */ +#define XCHAL_ICACHE_LINEWIDTH 7 /* log2(I line size in bytes) */ +#define XCHAL_DCACHE_LINEWIDTH 7 /* log2(D line size in bytes) */ + +#define XCHAL_ICACHE_SIZE 131072 /* I-cache size in bytes or 0 */ +#define XCHAL_ICACHE_SIZE_LOG2 17 +#define XCHAL_DCACHE_SIZE 131072 /* D-cache size in bytes or 0 */ +#define XCHAL_DCACHE_SIZE_LOG2 17 + +#define XCHAL_DCACHE_IS_WRITEBACK 1 /* writeback feature */ +#define XCHAL_DCACHE_IS_COHERENT 0 /* MP coherence feature */ + +#define XCHAL_HAVE_PREFETCH 1 /* PREFCTL register */ +#define XCHAL_HAVE_PREFETCH_L1 1 /* prefetch to L1 cache */ +#define XCHAL_PREFETCH_CASTOUT_LINES 1 /* dcache pref. castout bufsz */ +#define XCHAL_PREFETCH_ENTRIES 16 /* cache prefetch entries */ +#define XCHAL_PREFETCH_BLOCK_ENTRIES 8 /* prefetch block streams */ +#define XCHAL_HAVE_CACHE_BLOCKOPS 1 /* block prefetch for caches */ +#define XCHAL_HAVE_CME_DOWNGRADES 0 +#define XCHAL_HAVE_ICACHE_TEST 1 /* Icache test instructions */ +#define XCHAL_HAVE_DCACHE_TEST 1 /* Dcache test instructions */ +#define XCHAL_HAVE_ICACHE_DYN_WAYS 1 /* Icache dynamic way support */ +#define XCHAL_HAVE_DCACHE_DYN_WAYS 1 /* Dcache dynamic way support */ +#define XCHAL_HAVE_ICACHE_DYN_ENABLE 1 /* Icache enabled via MEMCTL */ +#define XCHAL_HAVE_DCACHE_DYN_ENABLE 1 /* Dcache enabled via MEMCTL */ + +#define XCHAL_L1SCACHE_SIZE 0 +#define XCHAL_L1SCACHE_SIZE_LOG2 0 +#define XCHAL_L1SCACHE_WAYS 1 +#define XCHAL_L1SCACHE_WAYS_LOG2 0 +#define XCHAL_L1SCACHE_ACCESS_SIZE 0 +#define XCHAL_L1SCACHE_BANKS 1 + +#define XCHAL_L1VCACHE_SIZE 0 + +#define XCHAL_HAVE_L2 0 /* NX L2 cache controller */ +#define XCHAL_HAVE_L2_CACHE 0 +#define XCHAL_NUM_CORES_IN_CLUSTER 0 + +/* PRID_ID macros are for internal use only ... subject to removal */ +#define PRID_ID_SHIFT 0 +#define PRID_ID_BITS 4 +#define PRID_ID_MASK 0x0000000F + +/* This one is a form of caching, though not architecturally visible: */ +#define XCHAL_HAVE_BRANCH_PREDICTION 0 /* branch [target] prediction */ + + + + +/**************************************************************************** + Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code + ****************************************************************************/ + + +#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY + +/*---------------------------------------------------------------------- + CACHE + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_PIF 1 /* any outbound bus present */ + +#define XCHAL_HAVE_AXI 1 /* AXI bus */ +#define XCHAL_HAVE_AXI_ECC 1 /* ECC on AXI bus */ +#define XCHAL_HAVE_ACELITE 0 /* ACELite bus */ + +#define XCHAL_HAVE_PIF_WR_RESP 1 /* pif write response */ +#define XCHAL_HAVE_PIF_REQ_ATTR 1 /* pif attribute */ + +/* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */ + +/* Number of cache sets in log2(lines per way): */ +#define XCHAL_ICACHE_SETWIDTH 8 +#define XCHAL_DCACHE_SETWIDTH 8 + +/* Cache set associativity (number of ways): */ +#define XCHAL_ICACHE_WAYS 4 +#define XCHAL_ICACHE_WAYS_LOG2 2 +#define XCHAL_DCACHE_WAYS 4 +#define XCHAL_DCACHE_WAYS_LOG2 2 + +/* Cache features: */ +#define XCHAL_ICACHE_LINE_LOCKABLE 1 +#define XCHAL_DCACHE_LINE_LOCKABLE 1 +#define XCHAL_ICACHE_ECC_PARITY 0 +#define XCHAL_DCACHE_ECC_PARITY 0 +#define XCHAL_ICACHE_ECC_WIDTH 4 +#define XCHAL_DCACHE_ECC_WIDTH 1 + +/* Cache access size in bytes (affects operation of SICW instruction): */ +#define XCHAL_ICACHE_ACCESS_SIZE 16 +#define XCHAL_DCACHE_ACCESS_SIZE 16 + +#define XCHAL_DCACHE_BANKS 2 /* number of banks */ + +/* The number of Cache lines associated with a single cache tag */ +#define XCHAL_DCACHE_LINES_PER_TAG_LOG2 0 + +/* Number of encoded cache attr bits (see for decoded bits): */ +#define XCHAL_CA_BITS 4 + + +/*---------------------------------------------------------------------- + INTERNAL I/D RAM/ROMs and XLMI + ----------------------------------------------------------------------*/ +#define XCHAL_NUM_INSTROM 0 /* number of core instr. ROMs */ +#define XCHAL_NUM_INSTRAM 1 /* number of core instr. RAMs */ +#define XCHAL_NUM_DATAROM 0 /* number of core data ROMs */ +#define XCHAL_NUM_DATARAM 1 /* number of core data RAMs */ +#define XCHAL_NUM_URAM 0 /* number of core unified RAMs*/ +#define XCHAL_NUM_XLMI 0 /* number of core XLMI ports */ +#define XCHAL_HAVE_IRAMCFG 0 /* IRAMxCFG register present */ +#define XCHAL_HAVE_DRAMCFG 0 /* DRAMxCFG register present */ + +/* Instruction RAM 0: */ +#define XCHAL_INSTRAM0_VADDR 0x7F000000 /* virtual address */ +#define XCHAL_INSTRAM0_PADDR 0x7F000000 /* physical address */ +#define XCHAL_INSTRAM0_SIZE 524288 /* size in bytes */ +#define XCHAL_INSTRAM0_ECC_PARITY 0 /* ECC/parity type, 0=none */ +#define XCHAL_HAVE_INSTRAM0 1 +#define XCHAL_INSTRAM0_HAVE_IDMA 0 /* idma supported by this local memory */ + +/* Data RAM 0: */ +#define XCHAL_DATARAM0_VADDR 0xE0000000 /* virtual address */ +#define XCHAL_DATARAM0_PADDR 0xE0000000 /* physical address */ +#define XCHAL_DATARAM0_SIZE 524288 /* size in bytes */ +#define XCHAL_DATARAM0_ECC_PARITY 0 /* ECC/parity type, 0=none */ +#define XCHAL_DATARAM0_BANKS 2 /* number of banks */ +#define XCHAL_HAVE_DATARAM0 1 +#define XCHAL_DATARAM0_HAVE_IDMA 0 /* idma supported by this local memory */ + +#define XCHAL_HAVE_IMEM_LOADSTORE 1 /* can load/store to IROM/IRAM*/ + + +/*---------------------------------------------------------------------- + IDMA + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_IDMA 0 + + + +/*---------------------------------------------------------------------- + INTERRUPTS and TIMERS + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_INTERRUPTS 1 /* interrupt option */ +#define XCHAL_HAVE_NMI 1 /* non-maskable interrupt */ +#define XCHAL_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */ +#define XCHAL_NUM_TIMERS 2 /* number of CCOMPAREn regs */ +#define XCHAL_NUM_INTERRUPTS 9 /* number of interrupts */ +#define XCHAL_NUM_INTERRUPTS_LOG2 4 /* ceil(log2(NUM_INTERRUPTS)) */ +#define XCHAL_NUM_EXTINTERRUPTS 5 /* num of external interrupts */ +#define XCHAL_NUM_INTLEVELS 6 /* number of interrupt levels + (not including level zero) */ + + +#define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */ +#define XCHAL_EXCM_LEVEL 5 /* level masked by PS.EXCM */ + /* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */ + +/* Masks of interrupts at each interrupt level: */ +#define XCHAL_INTLEVEL1_MASK 0x00000143 +#define XCHAL_INTLEVEL2_MASK 0x00000004 +#define XCHAL_INTLEVEL3_MASK 0x00000008 +#define XCHAL_INTLEVEL4_MASK 0x00000010 +#define XCHAL_INTLEVEL5_MASK 0x00000020 +#define XCHAL_INTLEVEL6_MASK 0x00000000 +#define XCHAL_INTLEVEL7_MASK 0x00000080 + +/* Masks of interrupts at each range 1..n of interrupt levels: */ +#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x00000143 +#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x00000147 +#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x0000014F +#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x0000015F +#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x0000017F +#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x0000017F +#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x000001FF + +/* Level of each interrupt: */ +#define XCHAL_INT0_LEVEL 1 +#define XCHAL_INT1_LEVEL 1 +#define XCHAL_INT2_LEVEL 2 +#define XCHAL_INT3_LEVEL 3 +#define XCHAL_INT4_LEVEL 4 +#define XCHAL_INT5_LEVEL 5 +#define XCHAL_INT6_LEVEL 1 +#define XCHAL_INT7_LEVEL 7 +#define XCHAL_INT8_LEVEL 1 +#define XCHAL_DEBUGLEVEL 6 /* debug interrupt level */ +#define XCHAL_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */ +#define XCHAL_NMILEVEL 7 /* NMI "level" (for use with + EXCSAVE/EPS/EPC_n, RFI n) */ + +/* Type of each interrupt: */ +#define XCHAL_INT0_TYPE XTHAL_INTTYPE_TIMER +#define XCHAL_INT1_TYPE XTHAL_INTTYPE_SOFTWARE +#define XCHAL_INT2_TYPE XTHAL_INTTYPE_WRITE_ERROR +#define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT6_TYPE XTHAL_INTTYPE_TIMER +#define XCHAL_INT7_TYPE XTHAL_INTTYPE_NMI +#define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_LEVEL + +/* Masks of interrupts for each type of interrupt: */ +#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xFFFFFE00 +#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x00000138 +#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x00000000 +#define XCHAL_INTTYPE_MASK_NMI 0x00000080 +#define XCHAL_INTTYPE_MASK_SOFTWARE 0x00000002 +#define XCHAL_INTTYPE_MASK_TIMER 0x00000041 +#define XCHAL_INTTYPE_MASK_ETIE 0x00000000 +#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000004 +#define XCHAL_INTTYPE_MASK_DBG_REQUEST 0x00000000 +#define XCHAL_INTTYPE_MASK_BREAKIN 0x00000000 +#define XCHAL_INTTYPE_MASK_TRAX 0x00000000 +#define XCHAL_INTTYPE_MASK_PROFILING 0x00000000 +#define XCHAL_INTTYPE_MASK_IDMA_DONE 0x00000000 +#define XCHAL_INTTYPE_MASK_IDMA_ERR 0x00000000 +#define XCHAL_INTTYPE_MASK_GS_ERR 0x00000000 +#define XCHAL_INTTYPE_MASK_L2_ERR 0x00000000 +#define XCHAL_INTTYPE_MASK_L2_STATUS 0x00000000 +#define XCHAL_INTTYPE_MASK_COR_ECC_ERR 0x00000000 +#define XCHAL_INTTYPE_MASK_WWDT 0x00000000 +#define XCHAL_INTTYPE_MASK_FXLK 0x00000000 + +/* Interrupt numbers assigned to specific interrupt sources: */ +#define XCHAL_TIMER0_INTERRUPT 0 /* CCOMPARE0 */ +#define XCHAL_TIMER1_INTERRUPT 6 /* CCOMPARE1 */ +#define XCHAL_TIMER2_INTERRUPT XTHAL_TIMER_UNCONFIGURED +#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED +#define XCHAL_NMI_INTERRUPT 7 /* non-maskable interrupt */ +#define XCHAL_WRITE_ERROR_INTERRUPT 2 + +/* Interrupt numbers for levels at which only one interrupt is configured: */ +#define XCHAL_INTLEVEL2_NUM 2 +#define XCHAL_INTLEVEL3_NUM 3 +#define XCHAL_INTLEVEL4_NUM 4 +#define XCHAL_INTLEVEL5_NUM 5 +#define XCHAL_INTLEVEL7_NUM 7 +/* (There are many interrupts each at level(s) 1.) */ + + +/* + * External interrupt mapping. + * These macros describe how Xtensa processor interrupt numbers + * (as numbered internally, eg. in INTERRUPT and INTENABLE registers) + * map to external BInterrupt pins, for those interrupts + * configured as external (level-triggered, edge-triggered, or NMI). + * See the Xtensa processor databook for more details. + */ + +/* Core interrupt numbers mapped to each EXTERNAL BInterrupt pin number: */ +#define XCHAL_EXTINT0_NUM 3 /* (intlevel 3) */ +#define XCHAL_EXTINT1_NUM 4 /* (intlevel 4) */ +#define XCHAL_EXTINT2_NUM 5 /* (intlevel 5) */ +#define XCHAL_EXTINT3_NUM 7 /* (intlevel 7) */ +#define XCHAL_EXTINT4_NUM 8 /* (intlevel 1) */ +/* EXTERNAL BInterrupt pin numbers mapped to each core interrupt number: */ +#define XCHAL_INT3_EXTNUM 0 /* (intlevel 3) */ +#define XCHAL_INT4_EXTNUM 1 /* (intlevel 4) */ +#define XCHAL_INT5_EXTNUM 2 /* (intlevel 5) */ +#define XCHAL_INT7_EXTNUM 3 /* (intlevel 7) */ +#define XCHAL_INT8_EXTNUM 4 /* (intlevel 1) */ + +#define XCHAL_HAVE_ISB 0 /* No ISB */ +#define XCHAL_ISB_VADDR 0 /* N/A */ +#define XCHAL_HAVE_ITB 0 /* No ITB */ +#define XCHAL_ITB_VADDR 0 /* N/A */ + +#define XCHAL_HAVE_KSL 0 /* Kernel Stack Limit */ +#define XCHAL_HAVE_ISL 0 /* Interrupt Stack Limit */ +#define XCHAL_HAVE_PSL 0 /* Pageable Stack Limit */ + + +/*---------------------------------------------------------------------- + EXCEPTIONS and VECTORS + ----------------------------------------------------------------------*/ + +#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture + number: 1 == XEA1 (until T1050) + 2 == XEA2 (T1040 onwards) + 3 == XEA3 (LX8/NX/SX onwards) + 0 == XEAX (extern) or TX */ +#define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */ +#define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */ +#define XCHAL_HAVE_XEA3 0 /* Exception Architecture 3 */ +#define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */ +#define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */ +#define XCHAL_HAVE_IMPRECISE_EXCEPTIONS 0 /* imprecise exception option */ +#define XCHAL_EXCCAUSE_NUM 64 /* Number of exceptions */ +#define XCHAL_HAVE_HALT 0 /* halt architecture option */ +#define XCHAL_HAVE_BOOTLOADER 0 /* boot loader (for TX) */ +#define XCHAL_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */ +#define XCHAL_HAVE_VECTOR_SELECT 0 /* relocatable vectors */ +#define XCHAL_HAVE_VECBASE 0 /* relocatable vectors */ + +#define XCHAL_RESET_VECOFS 0x00000000 +#define XCHAL_RESET_VECTOR_VADDR 0x7F000000 +#define XCHAL_RESET_VECTOR_PADDR 0x7F000000 +#define XCHAL_USER_VECOFS 0x00000000 +#define XCHAL_USER_VECTOR_VADDR 0x7F000740 +#define XCHAL_USER_VECTOR_PADDR 0x7F000740 +#define XCHAL_KERNEL_VECOFS 0x00000000 +#define XCHAL_KERNEL_VECTOR_VADDR 0x7F000700 +#define XCHAL_KERNEL_VECTOR_PADDR 0x7F000700 +#define XCHAL_DOUBLEEXC_VECOFS 0x00000000 +#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0x7F0007C0 +#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x7F0007C0 +#define XCHAL_WINDOW_OF4_VECOFS 0x00000000 +#define XCHAL_WINDOW_UF4_VECOFS 0x00000040 +#define XCHAL_WINDOW_OF8_VECOFS 0x00000080 +#define XCHAL_WINDOW_UF8_VECOFS 0x000000C0 +#define XCHAL_WINDOW_OF12_VECOFS 0x00000100 +#define XCHAL_WINDOW_UF12_VECOFS 0x00000140 +#define XCHAL_WINDOW_VECTORS_VADDR 0x7F000400 +#define XCHAL_WINDOW_VECTORS_PADDR 0x7F000400 +#define XCHAL_INTLEVEL2_VECOFS 0x00000000 +#define XCHAL_INTLEVEL2_VECTOR_VADDR 0x7F000580 +#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x7F000580 +#define XCHAL_INTLEVEL3_VECOFS 0x00000000 +#define XCHAL_INTLEVEL3_VECTOR_VADDR 0x7F0005C0 +#define XCHAL_INTLEVEL3_VECTOR_PADDR 0x7F0005C0 +#define XCHAL_INTLEVEL4_VECOFS 0x00000000 +#define XCHAL_INTLEVEL4_VECTOR_VADDR 0x7F000600 +#define XCHAL_INTLEVEL4_VECTOR_PADDR 0x7F000600 +#define XCHAL_INTLEVEL5_VECOFS 0x00000000 +#define XCHAL_INTLEVEL5_VECTOR_VADDR 0x7F000640 +#define XCHAL_INTLEVEL5_VECTOR_PADDR 0x7F000640 +#define XCHAL_INTLEVEL6_VECOFS 0x00000000 +#define XCHAL_INTLEVEL6_VECTOR_VADDR 0x7F000680 +#define XCHAL_INTLEVEL6_VECTOR_PADDR 0x7F000680 +#define XCHAL_DEBUG_VECOFS XCHAL_INTLEVEL6_VECOFS +#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL6_VECTOR_VADDR +#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL6_VECTOR_PADDR +#define XCHAL_NMI_VECOFS 0x00000000 +#define XCHAL_NMI_VECTOR_VADDR 0x7F0006C0 +#define XCHAL_NMI_VECTOR_PADDR 0x7F0006C0 +#define XCHAL_INTLEVEL7_VECOFS XCHAL_NMI_VECOFS +#define XCHAL_INTLEVEL7_VECTOR_VADDR XCHAL_NMI_VECTOR_VADDR +#define XCHAL_INTLEVEL7_VECTOR_PADDR XCHAL_NMI_VECTOR_PADDR + + +/*---------------------------------------------------------------------- + DEBUG MODULE + ----------------------------------------------------------------------*/ + +/* Misc */ +#define XCHAL_HAVE_DEBUG_ERI 0 /* ERI to debug module */ +#define XCHAL_HAVE_DEBUG_APB 0 /* APB to debug module */ +#define XCHAL_HAVE_DEBUG_JTAG 1 /* JTAG to debug module */ + +/* On-Chip Debug (OCD) */ +#define XCHAL_HAVE_OCD 1 /* OnChipDebug option */ +#define XCHAL_NUM_IBREAK 2 /* number of IBREAKn regs */ +#define XCHAL_NUM_DBREAK 2 /* number of DBREAKn regs */ +#define XCHAL_HAVE_OCD_DIR_ARRAY 0 /* faster OCD option (to LX4) */ +#define XCHAL_HAVE_OCD_LS32DDR 1 /* L32DDR/S32DDR (faster OCD) */ + +/* TRAX (in core) */ +#define XCHAL_HAVE_TRAX 0 /* TRAX in debug module */ +#define XCHAL_TRAX_MEM_SIZE 0 /* TRAX memory size in bytes */ +#define XCHAL_TRAX_MEM_SHAREABLE 0 /* start/end regs; ready sig. */ +#define XCHAL_TRAX_ATB_WIDTH 0 /* ATB width (bits), 0=no ATB */ +#define XCHAL_TRAX_TIME_WIDTH 0 /* timestamp bitwidth, 0=none */ + +/* Perf counters */ +#define XCHAL_NUM_PERF_COUNTERS 0 /* performance counters */ + + +/*---------------------------------------------------------------------- + MMU + ----------------------------------------------------------------------*/ + +/* See core-matmap.h header file for more details. */ + +#define XCHAL_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */ +#define XCHAL_HAVE_SPANNING_WAY 1 /* one way maps I+D 4GB vaddr */ +#define XCHAL_SPANNING_WAY 0 /* TLB spanning way number */ +#define XCHAL_HAVE_IDENTITY_MAP 0 /* vaddr == paddr always */ +#define XCHAL_HAVE_CACHEATTR 0 /* CACHEATTR register present */ +#define XCHAL_HAVE_MIMIC_CACHEATTR 0 /* region protection */ +#define XCHAL_HAVE_XLT_CACHEATTR 1 /* region prot. w/translation */ +#define XCHAL_HAVE_PTP_MMU 0 /* full MMU (with page table + [autorefill] and protection) + usable for an MMU-based OS */ + +/* If none of the above last 5 are set, it's a custom TLB configuration. */ + +#define XCHAL_MMU_ASID_BITS 0 /* number of bits in ASIDs */ +#define XCHAL_MMU_RINGS 1 /* number of rings (1..4) */ +#define XCHAL_MMU_RING_BITS 0 /* num of bits in RING field */ + +/*---------------------------------------------------------------------- + MPU + ----------------------------------------------------------------------*/ +#define XCHAL_HAVE_MPU 0 +#define XCHAL_MPU_ENTRIES 0 +#define XCHAL_MPU_LOCK 0 + +#define XCHAL_MPU_ALIGN_REQ 1 /* MPU requires alignment of entries to background map */ +#define XCHAL_MPU_BACKGROUND_ENTRIES 0 /* number of entries in bg map*/ +#define XCHAL_MPU_BG_CACHEADRDIS 0 /* default CACHEADRDIS for bg */ + +#define XCHAL_MPU_ALIGN_BITS 0 +#define XCHAL_MPU_ALIGN 0 + +/*----------------------------------------------------------------------- + CSR Parity +------------------------------------------------------------------------*/ +#define XCHAL_HAVE_CSR_PARITY 0 + + +/*---------------------------------------------------------------------- + FLEX-LOCK +------------------------------------------------------------------------*/ + +#define XCHAL_HAVE_FXLK 0 + +/*---------------------------------------------------------------------- + WWDT (Windowed Watchdog Timer) +------------------------------------------------------------------------*/ +#define XCHAL_HAVE_WWDT 0 +#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */ + + +#endif /* XTENSA_CORE_CONFIGURATION_H_ */ + diff --git a/src/platform/amd/acp_6_3/include/arch/xtensa/config/core-matmap.h b/src/platform/amd/acp_6_3/include/arch/xtensa/config/core-matmap.h new file mode 100644 index 000000000000..5195b5230905 --- /dev/null +++ b/src/platform/amd/acp_6_3/include/arch/xtensa/config/core-matmap.h @@ -0,0 +1,317 @@ +/* + * xtensa/config/core-matmap.h -- Memory access and translation mapping + * parameters (CHAL) of the Xtensa processor core configuration. + * + * If you are using Xtensa Tools, see (which includes + * this file) for more details. + * + * In the Xtensa processor products released to date, all parameters + * defined in this file are derivable (at least in theory) from + * information contained in the core-isa.h header file. + * In particular, the following core configuration parameters are relevant: + * XCHAL_HAVE_CACHEATTR + * XCHAL_HAVE_MIMIC_CACHEATTR + * XCHAL_HAVE_XLT_CACHEATTR + * XCHAL_HAVE_PTP_MMU + * XCHAL_ITLB_ARF_ENTRIES_LOG2 + * XCHAL_DTLB_ARF_ENTRIES_LOG2 + * XCHAL_DCACHE_IS_WRITEBACK + * XCHAL_ICACHE_SIZE (presence of I-cache) + * XCHAL_DCACHE_SIZE (presence of D-cache) + * XCHAL_HW_VERSION_MAJOR + * XCHAL_HW_VERSION_MINOR + */ + +/* Customer ID=7490; Build=0xa28f5; Copyright (c) 1999-2022 Tensilica 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 XTENSA_CONFIG_CORE_MATMAP_H +#define XTENSA_CONFIG_CORE_MATMAP_H + + +/*---------------------------------------------------------------------- + CACHE (MEMORY ACCESS) ATTRIBUTES + ----------------------------------------------------------------------*/ + + + +/* Cache Attribute encodings -- lists of access modes for each cache attribute: */ +#define XCHAL_FCA_LIST XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_CACHED XCHAL_SEP \ + XTHAL_FAM_BYPASS XCHAL_SEP \ + XTHAL_FAM_CACHED XCHAL_SEP \ + XTHAL_FAM_CACHED XCHAL_SEP \ + XTHAL_FAM_CACHED XCHAL_SEP \ + XTHAL_FAM_BYPASS XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION +#define XCHAL_LCA_LIST XTHAL_LAM_CACHED_NOALLOC XCHAL_SEP \ + XTHAL_LAM_CACHED XCHAL_SEP \ + XTHAL_LAM_BYPASSG XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_CACHED XCHAL_SEP \ + XTHAL_LAM_CACHED XCHAL_SEP \ + XTHAL_LAM_BYPASSG XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION +#define XCHAL_SCA_LIST XTHAL_SAM_WRITETHRU XCHAL_SEP \ + XTHAL_SAM_WRITETHRU XCHAL_SEP \ + XTHAL_SAM_BYPASS XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_WRITEBACK XCHAL_SEP \ + XTHAL_SAM_WRITEBACK_NOALLOC XCHAL_SEP \ + XTHAL_SAM_BYPASS XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION + +#define XCHAL_CA_R (0xC0 | 0x40000000) +#define XCHAL_CA_RX (0xD0 | 0x40000000) +#define XCHAL_CA_RW (0xE0 | 0x40000000) +#define XCHAL_CA_RWX (0xF0 | 0x40000000) + +/* + * Specific encoded cache attribute values of general interest. + * If a specific cache mode is not available, the closest available + * one is returned instead (eg. writethru instead of writeback, + * bypass instead of writethru). + */ +#define XCHAL_CA_BYPASS 2 /* cache disabled (bypassed) mode */ +#define XCHAL_CA_BYPASSBUF 6 /* cache disabled (bypassed) bufferable mode */ +#define XCHAL_CA_WRITETHRU 1 /* cache enabled (write-through) mode */ +#define XCHAL_CA_WRITEBACK 4 /* cache enabled (write-back) mode */ +#define XCHAL_HAVE_CA_WRITEBACK_NOALLOC 1 /* write-back no-allocate availability */ +#define XCHAL_CA_WRITEBACK_NOALLOC 5 /* cache enabled (write-back no-allocate) mode */ +#define XCHAL_CA_ILLEGAL 15 /* no access allowed (all cause exceptions) mode */ + +/*---------------------------------------------------------------------- + MMU + ----------------------------------------------------------------------*/ + +/* + * General notes on MMU parameters. + * + * Terminology: + * ASID = address-space ID (acts as an "extension" of virtual addresses) + * VPN = virtual page number + * PPN = physical page number + * CA = encoded cache attribute (access modes) + * TLB = translation look-aside buffer (term is stretched somewhat here) + * I = instruction (fetch accesses) + * D = data (load and store accesses) + * way = each TLB (ITLB and DTLB) consists of a number of "ways" + * that simultaneously match the virtual address of an access; + * a TLB successfully translates a virtual address if exactly + * one way matches the vaddr; if none match, it is a miss; + * if multiple match, one gets a "multihit" exception; + * each way can be independently configured in terms of number of + * entries, page sizes, which fields are writable or constant, etc. + * set = group of contiguous ways with exactly identical parameters + * ARF = auto-refill; hardware services a 1st-level miss by loading a PTE + * from the page table and storing it in one of the auto-refill ways; + * if this PTE load also misses, a miss exception is posted for s/w. + * min-wired = a "min-wired" way can be used to map a single (minimum-sized) + * page arbitrarily under program control; it has a single entry, + * is non-auto-refill (some other way(s) must be auto-refill), + * all its fields (VPN, PPN, ASID, CA) are all writable, and it + * supports the XCHAL_MMU_MIN_PTE_PAGE_SIZE page size (a current + * restriction is that this be the only page size it supports). + * + * TLB way entries are virtually indexed. + * TLB ways that support multiple page sizes: + * - must have all writable VPN and PPN fields; + * - can only use one page size at any given time (eg. setup at startup), + * selected by the respective ITLBCFG or DTLBCFG special register, + * whose bits n*4+3 .. n*4 index the list of page sizes for way n + * (XCHAL_xTLB_SETm_PAGESZ_LOG2_LIST for set m corresponding to way n); + * this list may be sparse for auto-refill ways because auto-refill + * ways have independent lists of supported page sizes sharing a + * common encoding with PTE entries; the encoding is the index into + * this list; unsupported sizes for a given way are zero in the list; + * selecting unsupported sizes results in undefine hardware behaviour; + * - is only possible for ways 0 thru 7 (due to ITLBCFG/DTLBCFG definition). + */ + +#define XCHAL_MMU_ASID_INVALID 0 /* ASID value indicating invalid address space */ +#define XCHAL_MMU_ASID_KERNEL 0 /* ASID value indicating kernel (ring 0) address space */ +#define XCHAL_MMU_SR_BITS 0 /* number of size-restriction bits supported */ +#define XCHAL_MMU_CA_BITS 4 /* number of bits needed to hold cache attribute encoding */ +#define XCHAL_MMU_MAX_PTE_PAGE_SIZE 29 /* max page size in a PTE structure (log2) */ +#define XCHAL_MMU_MIN_PTE_PAGE_SIZE 29 /* min page size in a PTE structure (log2) */ + + +/*** Instruction TLB: ***/ + +#define XCHAL_ITLB_WAY_BITS 0 /* number of bits holding the ways */ +#define XCHAL_ITLB_WAYS 1 /* number of ways (n-way set-associative TLB) */ +#define XCHAL_ITLB_ARF_WAYS 0 /* number of auto-refill ways */ +#define XCHAL_ITLB_SETS 1 /* number of sets (groups of ways with identical settings) */ + +/* Way set to which each way belongs: */ +#define XCHAL_ITLB_WAY0_SET 0 + +/* Ways sets that are used by hardware auto-refill (ARF): */ +#define XCHAL_ITLB_ARF_SETS 0 /* number of auto-refill sets */ + +/* Way sets that are "min-wired" (see terminology comment above): */ +#define XCHAL_ITLB_MINWIRED_SETS 0 /* number of "min-wired" sets */ + + +/* ITLB way set 0 (group of ways 0 thru 0): */ +#define XCHAL_ITLB_SET0_WAY 0 /* index of first way in this way set */ +#define XCHAL_ITLB_SET0_WAYS 1 /* number of (contiguous) ways in this way set */ +#define XCHAL_ITLB_SET0_ENTRIES_LOG2 3 /* log2(number of entries in this way) */ +#define XCHAL_ITLB_SET0_ENTRIES 8 /* number of entries in this way (always a power of 2) */ +#define XCHAL_ITLB_SET0_ARF 0 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */ +#define XCHAL_ITLB_SET0_PAGESIZES 1 /* number of supported page sizes in this way */ +#define XCHAL_ITLB_SET0_PAGESZ_BITS 0 /* number of bits to encode the page size */ +#define XCHAL_ITLB_SET0_PAGESZ_LOG2_MIN 29 /* log2(minimum supported page size) */ +#define XCHAL_ITLB_SET0_PAGESZ_LOG2_MAX 29 /* log2(maximum supported page size) */ +#define XCHAL_ITLB_SET0_PAGESZ_LOG2_LIST 29 /* list of log2(page size)s, separated by XCHAL_SEP; + 2^PAGESZ_BITS entries in list, unsupported entries are zero */ +#define XCHAL_ITLB_SET0_ASID_CONSTMASK 0 /* constant ASID bits; 0 if all writable */ +#define XCHAL_ITLB_SET0_VPN_CONSTMASK 0x00000000 /* constant VPN bits, not including entry index bits; 0 if all writable */ +#define XCHAL_ITLB_SET0_PPN_CONSTMASK 0 /* constant PPN bits, including entry index bits; 0 if all writable */ +#define XCHAL_ITLB_SET0_CA_CONSTMASK 0 /* constant CA bits; 0 if all writable */ +#define XCHAL_ITLB_SET0_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */ +#define XCHAL_ITLB_SET0_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */ +#define XCHAL_ITLB_SET0_PPN_RESET 1 /* 1 if PPN reset values defined (and all writable); 0 otherwise */ +#define XCHAL_ITLB_SET0_CA_RESET 1 /* 1 if CA reset values defined (and all writable); 0 otherwise */ +/* Constant VPN values for each entry of ITLB way set 0 (because VPN_CONSTMASK is non-zero): */ +#define XCHAL_ITLB_SET0_E0_VPN_CONST 0x00000000 +#define XCHAL_ITLB_SET0_E1_VPN_CONST 0x20000000 +#define XCHAL_ITLB_SET0_E2_VPN_CONST 0x40000000 +#define XCHAL_ITLB_SET0_E3_VPN_CONST 0x60000000 +#define XCHAL_ITLB_SET0_E4_VPN_CONST 0x80000000 +#define XCHAL_ITLB_SET0_E5_VPN_CONST 0xA0000000 +#define XCHAL_ITLB_SET0_E6_VPN_CONST 0xC0000000 +#define XCHAL_ITLB_SET0_E7_VPN_CONST 0xE0000000 +/* Reset PPN values for each entry of ITLB way set 0 (because SET0_PPN_RESET is non-zero): */ +#define XCHAL_ITLB_SET0_E0_PPN_RESET 0x00000000 +#define XCHAL_ITLB_SET0_E1_PPN_RESET 0x20000000 +#define XCHAL_ITLB_SET0_E2_PPN_RESET 0x40000000 +#define XCHAL_ITLB_SET0_E3_PPN_RESET 0x60000000 +#define XCHAL_ITLB_SET0_E4_PPN_RESET 0x80000000 +#define XCHAL_ITLB_SET0_E5_PPN_RESET 0xA0000000 +#define XCHAL_ITLB_SET0_E6_PPN_RESET 0xC0000000 +#define XCHAL_ITLB_SET0_E7_PPN_RESET 0xE0000000 +/* Reset CA values for each entry of ITLB way set 0 (because SET0_CA_RESET is non-zero): */ +#define XCHAL_ITLB_SET0_E0_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E1_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E2_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E3_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E4_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E5_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E6_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E7_CA_RESET 0x02 + + +/*** Data TLB: ***/ + +#define XCHAL_DTLB_WAY_BITS 0 /* number of bits holding the ways */ +#define XCHAL_DTLB_WAYS 1 /* number of ways (n-way set-associative TLB) */ +#define XCHAL_DTLB_ARF_WAYS 0 /* number of auto-refill ways */ +#define XCHAL_DTLB_SETS 1 /* number of sets (groups of ways with identical settings) */ + +/* Way set to which each way belongs: */ +#define XCHAL_DTLB_WAY0_SET 0 + +/* Ways sets that are used by hardware auto-refill (ARF): */ +#define XCHAL_DTLB_ARF_SETS 0 /* number of auto-refill sets */ + +/* Way sets that are "min-wired" (see terminology comment above): */ +#define XCHAL_DTLB_MINWIRED_SETS 0 /* number of "min-wired" sets */ + + +/* DTLB way set 0 (group of ways 0 thru 0): */ +#define XCHAL_DTLB_SET0_WAY 0 /* index of first way in this way set */ +#define XCHAL_DTLB_SET0_WAYS 1 /* number of (contiguous) ways in this way set */ +#define XCHAL_DTLB_SET0_ENTRIES_LOG2 3 /* log2(number of entries in this way) */ +#define XCHAL_DTLB_SET0_ENTRIES 8 /* number of entries in this way (always a power of 2) */ +#define XCHAL_DTLB_SET0_ARF 0 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */ +#define XCHAL_DTLB_SET0_PAGESIZES 1 /* number of supported page sizes in this way */ +#define XCHAL_DTLB_SET0_PAGESZ_BITS 0 /* number of bits to encode the page size */ +#define XCHAL_DTLB_SET0_PAGESZ_LOG2_MIN 29 /* log2(minimum supported page size) */ +#define XCHAL_DTLB_SET0_PAGESZ_LOG2_MAX 29 /* log2(maximum supported page size) */ +#define XCHAL_DTLB_SET0_PAGESZ_LOG2_LIST 29 /* list of log2(page size)s, separated by XCHAL_SEP; + 2^PAGESZ_BITS entries in list, unsupported entries are zero */ +#define XCHAL_DTLB_SET0_ASID_CONSTMASK 0 /* constant ASID bits; 0 if all writable */ +#define XCHAL_DTLB_SET0_VPN_CONSTMASK 0x00000000 /* constant VPN bits, not including entry index bits; 0 if all writable */ +#define XCHAL_DTLB_SET0_PPN_CONSTMASK 0 /* constant PPN bits, including entry index bits; 0 if all writable */ +#define XCHAL_DTLB_SET0_CA_CONSTMASK 0 /* constant CA bits; 0 if all writable */ +#define XCHAL_DTLB_SET0_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */ +#define XCHAL_DTLB_SET0_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */ +#define XCHAL_DTLB_SET0_PPN_RESET 1 /* 1 if PPN reset values defined (and all writable); 0 otherwise */ +#define XCHAL_DTLB_SET0_CA_RESET 1 /* 1 if CA reset values defined (and all writable); 0 otherwise */ +/* Constant VPN values for each entry of DTLB way set 0 (because VPN_CONSTMASK is non-zero): */ +#define XCHAL_DTLB_SET0_E0_VPN_CONST 0x00000000 +#define XCHAL_DTLB_SET0_E1_VPN_CONST 0x20000000 +#define XCHAL_DTLB_SET0_E2_VPN_CONST 0x40000000 +#define XCHAL_DTLB_SET0_E3_VPN_CONST 0x60000000 +#define XCHAL_DTLB_SET0_E4_VPN_CONST 0x80000000 +#define XCHAL_DTLB_SET0_E5_VPN_CONST 0xA0000000 +#define XCHAL_DTLB_SET0_E6_VPN_CONST 0xC0000000 +#define XCHAL_DTLB_SET0_E7_VPN_CONST 0xE0000000 +/* Reset PPN values for each entry of DTLB way set 0 (because SET0_PPN_RESET is non-zero): */ +#define XCHAL_DTLB_SET0_E0_PPN_RESET 0x00000000 +#define XCHAL_DTLB_SET0_E1_PPN_RESET 0x20000000 +#define XCHAL_DTLB_SET0_E2_PPN_RESET 0x40000000 +#define XCHAL_DTLB_SET0_E3_PPN_RESET 0x60000000 +#define XCHAL_DTLB_SET0_E4_PPN_RESET 0x80000000 +#define XCHAL_DTLB_SET0_E5_PPN_RESET 0xA0000000 +#define XCHAL_DTLB_SET0_E6_PPN_RESET 0xC0000000 +#define XCHAL_DTLB_SET0_E7_PPN_RESET 0xE0000000 +/* Reset CA values for each entry of DTLB way set 0 (because SET0_CA_RESET is non-zero): */ +#define XCHAL_DTLB_SET0_E0_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E1_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E2_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E3_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E4_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E5_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E6_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E7_CA_RESET 0x02 + + + + +#endif /*XTENSA_CONFIG_CORE_MATMAP_H*/ + diff --git a/src/platform/amd/acp_6_3/include/arch/xtensa/config/defs.h b/src/platform/amd/acp_6_3/include/arch/xtensa/config/defs.h new file mode 100644 index 000000000000..0da4586ce0d3 --- /dev/null +++ b/src/platform/amd/acp_6_3/include/arch/xtensa/config/defs.h @@ -0,0 +1,38 @@ +/* Definitions for Xtensa instructions, types, and protos. */ + +/* Customer ID=12153; Build=0x878bf; Copyright (c) 2003-2004 Tensilica 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. */ + +/* NOTE: This file exists only for backward compatibility with T1050 + and earlier Xtensa releases. It includes only a subset of the + available header files. */ + +#ifndef _XTENSA_BASE_HEADER +#define _XTENSA_BASE_HEADER + +#ifdef __XTENSA__ + +#include +#include +#include + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_BASE_HEADER */ diff --git a/src/platform/amd/acp_6_3/include/arch/xtensa/config/specreg.h b/src/platform/amd/acp_6_3/include/arch/xtensa/config/specreg.h new file mode 100644 index 000000000000..0c54c7290dd6 --- /dev/null +++ b/src/platform/amd/acp_6_3/include/arch/xtensa/config/specreg.h @@ -0,0 +1,108 @@ +/* + * Xtensa Special Register symbolic names + */ + +/* $Id: //depot/rel/Homewood/ib.6/Xtensa/SWConfig/hal/specreg.h.tpp#1 $ */ + +/* Customer ID=7490; Build=0xa28f5; Copyright (c) 1998-2002 Tensilica 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 XTENSA_SPECREG_H +#define XTENSA_SPECREG_H + +/* Include these special register bitfield definitions, for historical reasons: */ +#include + + +/* Special registers: */ +#define LBEG 0 +#define LEND 1 +#define LCOUNT 2 +#define SAR 3 +#define BR 4 +#define SCOMPARE1 12 +#define PREFCTL 40 +#define WINDOWBASE 72 +#define WINDOWSTART 73 +#define IBREAKENABLE 96 +#define MEMCTL 97 +#define ATOMCTL 99 +#define DDR 104 +#define IBREAKA_0 128 +#define IBREAKA_1 129 +#define DBREAKA_0 144 +#define DBREAKA_1 145 +#define DBREAKC_0 160 +#define DBREAKC_1 161 +#define EPC_1 177 +#define EPC_2 178 +#define EPC_3 179 +#define EPC_4 180 +#define EPC_5 181 +#define EPC_6 182 +#define EPC_7 183 +#define DEPC 192 +#define EPS_2 194 +#define EPS_3 195 +#define EPS_4 196 +#define EPS_5 197 +#define EPS_6 198 +#define EPS_7 199 +#define EXCSAVE_1 209 +#define EXCSAVE_2 210 +#define EXCSAVE_3 211 +#define EXCSAVE_4 212 +#define EXCSAVE_5 213 +#define EXCSAVE_6 214 +#define EXCSAVE_7 215 +#define CPENABLE 224 +#define INTERRUPT 226 +#define INTENABLE 228 +#define PS 230 +#define EXCCAUSE 232 +#define DEBUGCAUSE 233 +#define CCOUNT 234 +#define PRID 235 +#define ICOUNT 236 +#define ICOUNTLEVEL 237 +#define EXCVADDR 238 +#define CCOMPARE_0 240 +#define CCOMPARE_1 241 +#define MISC_REG_0 244 +#define MISC_REG_1 245 + + +/* Special cases (bases of special register series): */ +#define IBREAKA 128 +#define DBREAKA 144 +#define DBREAKC 160 +#define EPC 176 +#define EPS 192 +#define EXCSAVE 208 +#define CCOMPARE 240 + +/* Special names for read-only and write-only interrupt registers: */ +#define INTREAD 226 +#define INTSET 226 +#define INTCLEAR 227 + +#endif /* XTENSA_SPECREG_H */ + diff --git a/src/platform/amd/acp_6_3/include/arch/xtensa/config/system.h b/src/platform/amd/acp_6_3/include/arch/xtensa/config/system.h new file mode 100644 index 000000000000..31459310d3d7 --- /dev/null +++ b/src/platform/amd/acp_6_3/include/arch/xtensa/config/system.h @@ -0,0 +1,262 @@ +/* + * xtensa/config/system.h -- HAL definitions that are dependent on SYSTEM configuration + * + * NOTE: The location and contents of this file are highly subject to change. + * + * Source for configuration-independent binaries (which link in a + * configuration-specific HAL library) must NEVER include this file. + * The HAL itself has historically included this file in some instances, + * but this is not appropriate either, because the HAL is meant to be + * core-specific but system independent. + */ + +/* Customer ID=7490; Build=0xa28f5; Copyright (c) 2000-2010 Tensilica 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 XTENSA_CONFIG_SYSTEM_H +#define XTENSA_CONFIG_SYSTEM_H + + +/*---------------------------------------------------------------------- + CONFIGURED SOFTWARE OPTIONS + ----------------------------------------------------------------------*/ + +#define XSHAL_USE_ABSOLUTE_LITERALS 0 /* (sw-only option, whether software uses absolute literals) */ +#define XSHAL_HAVE_TEXT_SECTION_LITERALS 1 /* Set if there is some memory that allows both code and literals. */ + +#define XSHAL_ABI XTHAL_ABI_WINDOWED /* (sw-only option, selected ABI) */ +/* The above maps to one of the following constants: */ +#define XTHAL_ABI_WINDOWED 0 +#define XTHAL_ABI_CALL0 1 + +#define XSHAL_CLIB XTHAL_CLIB_XCLIB /* (sw-only option, selected C library) */ +/* The above maps to one of the following constants: */ +#define XTHAL_CLIB_NEWLIB 0 +#define XTHAL_CLIB_UCLIBC 1 +#define XTHAL_CLIB_XCLIB 2 + +#define XSHAL_USE_FLOATING_POINT 1 + +#define XSHAL_FLOATING_POINT_ABI 1 + +/* SW workarounds enabled for HW errata: */ + +/*---------------------------------------------------------------------- + DEVICE ADDRESSES + ----------------------------------------------------------------------*/ + +/* + * Strange place to find these, but the configuration GUI + * allows moving these around to account for various core + * configurations. Specific boards (and their BSP software) + * will have specific meanings for these components. + */ + +/* I/O Block areas: */ +#define XSHAL_IOBLOCK_CACHED_VADDR 0x70000000 +#define XSHAL_IOBLOCK_CACHED_PADDR 0x70000000 +#define XSHAL_IOBLOCK_CACHED_SIZE 0x0E000000 + +#define XSHAL_IOBLOCK_BYPASS_VADDR 0x90000000 +#define XSHAL_IOBLOCK_BYPASS_PADDR 0x90000000 +#define XSHAL_IOBLOCK_BYPASS_SIZE 0x0E000000 + +/* System ROM: */ +#define XSHAL_ROM_VADDR 0x50000000 +#define XSHAL_ROM_PADDR 0x50000000 +#define XSHAL_ROM_SIZE 0x00020000 +/* Largest available area (free of vectors): */ +#define XSHAL_ROM_AVAIL_VADDR 0x50000000 +#define XSHAL_ROM_AVAIL_VSIZE 0x00020000 + +/* System RAM: */ +#define XSHAL_RAM_VADDR 0x60000000 +#define XSHAL_RAM_PADDR 0x60000000 +#define XSHAL_RAM_VSIZE 0x1F000000 +#define XSHAL_RAM_PSIZE 0x1F000000 +#define XSHAL_RAM_SIZE XSHAL_RAM_PSIZE +/* Largest available area (free of vectors): */ +#define XSHAL_RAM_AVAIL_VADDR 0x60000000 +#define XSHAL_RAM_AVAIL_VSIZE 0x1F000000 + +/* + * Shadow system RAM (same device as system RAM, at different address). + * (Emulation boards need this for the SONIC Ethernet driver + * when data caches are configured for writeback mode.) + * NOTE: on full MMU configs, this points to the BYPASS virtual address + * of system RAM, ie. is the same as XSHAL_RAM_* except that virtual + * addresses are viewed through the BYPASS static map rather than + * the CACHED static map. + */ +#define XSHAL_RAM_BYPASS_VADDR 0x20000000 +#define XSHAL_RAM_BYPASS_PADDR 0x20000000 +#define XSHAL_RAM_BYPASS_PSIZE 0x1F000000 + +/* Alternate system RAM (different device than system RAM): */ + +/* Some available location in which to place devices in a simulation (eg. XTMP): */ +#define XSHAL_SIMIO_CACHED_VADDR 0xC0000000 +#define XSHAL_SIMIO_BYPASS_VADDR 0xC0000000 +#define XSHAL_SIMIO_PADDR 0xC0000000 +#define XSHAL_SIMIO_SIZE 0x20000000 + + +/*---------------------------------------------------------------------- + * For use by reference testbench exit and diagnostic routines. + */ +#define XSHAL_MAGIC_EXIT 0xc0000000 +#define XSHAL_STL_INFO_LOCATION 0x9ffffffc + +/*---------------------------------------------------------------------- + * DEVICE-ADDRESS DEPENDENT... + * + * Values written to CACHEATTR special register (or its equivalent) + * to enable and disable caches in various modes. + *----------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------- + BACKWARD COMPATIBILITY ... + ----------------------------------------------------------------------*/ + +/* + * NOTE: the following two macros are DEPRECATED. Use the latter + * board-specific macros instead, which are specially tuned for the + * particular target environments' memory maps. + */ +#define XSHAL_CACHEATTR_BYPASS XSHAL_XT2000_CACHEATTR_BYPASS /* disable caches in bypass mode */ +#define XSHAL_CACHEATTR_DEFAULT XSHAL_XT2000_CACHEATTR_DEFAULT /* default setting to enable caches (no writeback!) */ + +/*---------------------------------------------------------------------- + GENERIC + ----------------------------------------------------------------------*/ + +/* For the following, a 512MB region is used if it contains a system (PIF) RAM, + * system (PIF) ROM, local memory, or XLMI. */ + +/* These set any unused 512MB region to cache-BYPASS attribute: */ +#define XSHAL_ALLVALID_CACHEATTR_WRITEBACK 0x42224422 /* enable caches in write-back mode */ +#define XSHAL_ALLVALID_CACHEATTR_WRITEALLOC 0x12221122 /* enable caches in write-allocate mode */ +#define XSHAL_ALLVALID_CACHEATTR_WRITETHRU 0x12221122 /* enable caches in write-through mode */ +#define XSHAL_ALLVALID_CACHEATTR_BYPASS 0x22222222 /* disable caches in bypass mode */ +#define XSHAL_ALLVALID_CACHEATTR_DEFAULT XSHAL_ALLVALID_CACHEATTR_WRITEBACK /* default setting to enable caches */ + +/* These set any unused 512MB region to ILLEGAL attribute: */ +#define XSHAL_STRICT_CACHEATTR_WRITEBACK 0x4FFF44FF /* enable caches in write-back mode */ +#define XSHAL_STRICT_CACHEATTR_WRITEALLOC 0x1FFF11FF /* enable caches in write-allocate mode */ +#define XSHAL_STRICT_CACHEATTR_WRITETHRU 0x1FFF11FF /* enable caches in write-through mode */ +#define XSHAL_STRICT_CACHEATTR_BYPASS 0x2FFF22FF /* disable caches in bypass mode */ +#define XSHAL_STRICT_CACHEATTR_DEFAULT XSHAL_STRICT_CACHEATTR_WRITEBACK /* default setting to enable caches */ + +/* These set the first 512MB, if unused, to ILLEGAL attribute to help catch + * NULL-pointer dereference bugs; all other unused 512MB regions are set + * to cache-BYPASS attribute: */ +#define XSHAL_TRAPNULL_CACHEATTR_WRITEBACK 0x4222442F /* enable caches in write-back mode */ +#define XSHAL_TRAPNULL_CACHEATTR_WRITEALLOC 0x1222112F /* enable caches in write-allocate mode */ +#define XSHAL_TRAPNULL_CACHEATTR_WRITETHRU 0x1222112F /* enable caches in write-through mode */ +#define XSHAL_TRAPNULL_CACHEATTR_BYPASS 0x2222222F /* disable caches in bypass mode */ +#define XSHAL_TRAPNULL_CACHEATTR_DEFAULT XSHAL_TRAPNULL_CACHEATTR_WRITEBACK /* default setting to enable caches */ + +/*---------------------------------------------------------------------- + ISS (Instruction Set Simulator) SPECIFIC ... + ----------------------------------------------------------------------*/ + +/* For now, ISS defaults to the TRAPNULL settings: */ +#define XSHAL_ISS_CACHEATTR_WRITEBACK XSHAL_TRAPNULL_CACHEATTR_WRITEBACK +#define XSHAL_ISS_CACHEATTR_WRITEALLOC XSHAL_TRAPNULL_CACHEATTR_WRITEALLOC +#define XSHAL_ISS_CACHEATTR_WRITETHRU XSHAL_TRAPNULL_CACHEATTR_WRITETHRU +#define XSHAL_ISS_CACHEATTR_BYPASS XSHAL_TRAPNULL_CACHEATTR_BYPASS +#define XSHAL_ISS_CACHEATTR_DEFAULT XSHAL_TRAPNULL_CACHEATTR_WRITEBACK + +#define XSHAL_ISS_PIPE_REGIONS 0 +#define XSHAL_ISS_SDRAM_REGIONS 0 + + +/*---------------------------------------------------------------------- + XT2000 BOARD SPECIFIC ... + ----------------------------------------------------------------------*/ + +/* For the following, a 512MB region is used if it contains any system RAM, + * system ROM, local memory, XLMI, or other XT2000 board device or memory. + * Regions containing devices are forced to cache-BYPASS mode regardless + * of whether the macro is _WRITEBACK vs. _BYPASS etc. */ + +/* These set any 512MB region unused on the XT2000 to ILLEGAL attribute: */ +#define XSHAL_XT2000_CACHEATTR_WRITEBACK 0x4FF2442F /* enable caches in write-back mode */ +#define XSHAL_XT2000_CACHEATTR_WRITEALLOC 0x1FF2112F /* enable caches in write-allocate mode */ +#define XSHAL_XT2000_CACHEATTR_WRITETHRU 0x1FF2112F /* enable caches in write-through mode */ +#define XSHAL_XT2000_CACHEATTR_BYPASS 0x2FF2222F /* disable caches in bypass mode */ +#define XSHAL_XT2000_CACHEATTR_DEFAULT XSHAL_XT2000_CACHEATTR_WRITEBACK /* default setting to enable caches */ + +#define XSHAL_XT2000_PIPE_REGIONS 0x00000000 /* BusInt pipeline regions */ +#define XSHAL_XT2000_SDRAM_REGIONS 0x00000044 /* BusInt SDRAM regions */ + + +/*---------------------------------------------------------------------- + VECTOR INFO AND SIZES + ----------------------------------------------------------------------*/ + +#define XSHAL_VECTORS_PACKED 0 /* UNUSED */ +#define XSHAL_STATIC_VECTOR_SELECT 0 +#define XSHAL_RESET_VECTOR_VADDR 0x7F000000 +#define XSHAL_RESET_VECTOR_PADDR 0x7F000000 + +/* + * Sizes allocated to vectors by the system (memory map) configuration. + * These sizes are constrained by core configuration (eg. one vector's + * code cannot overflow into another vector) but are dependent on the + * system or board (or LSP) memory map configuration. + * + * Whether or not each vector happens to be in a system ROM is also + * a system configuration matter, sometimes useful, included here also: + */ +#define XSHAL_RESET_VECTOR_SIZE 0x00000300 +#define XSHAL_RESET_VECTOR_ISROM 0 +#define XSHAL_USER_VECTOR_SIZE 0x00000038 +#define XSHAL_USER_VECTOR_ISROM 0 +#define XSHAL_PROGRAMEXC_VECTOR_SIZE XSHAL_USER_VECTOR_SIZE /* for backward compatibility */ +#define XSHAL_USEREXC_VECTOR_SIZE XSHAL_USER_VECTOR_SIZE /* for backward compatibility */ +#define XSHAL_KERNEL_VECTOR_SIZE 0x00000038 +#define XSHAL_KERNEL_VECTOR_ISROM 0 +#define XSHAL_STACKEDEXC_VECTOR_SIZE XSHAL_KERNEL_VECTOR_SIZE /* for backward compatibility */ +#define XSHAL_KERNELEXC_VECTOR_SIZE XSHAL_KERNEL_VECTOR_SIZE /* for backward compatibility */ +#define XSHAL_DOUBLEEXC_VECTOR_SIZE 0x00000040 +#define XSHAL_DOUBLEEXC_VECTOR_ISROM 0 +#define XSHAL_WINDOW_VECTORS_SIZE 0x00000178 +#define XSHAL_WINDOW_VECTORS_ISROM 0 +#define XSHAL_INTLEVEL2_VECTOR_SIZE 0x00000038 +#define XSHAL_INTLEVEL2_VECTOR_ISROM 0 +#define XSHAL_INTLEVEL3_VECTOR_SIZE 0x00000038 +#define XSHAL_INTLEVEL3_VECTOR_ISROM 0 +#define XSHAL_INTLEVEL4_VECTOR_SIZE 0x00000038 +#define XSHAL_INTLEVEL4_VECTOR_ISROM 0 +#define XSHAL_INTLEVEL5_VECTOR_SIZE 0x00000038 +#define XSHAL_INTLEVEL5_VECTOR_ISROM 0 +#define XSHAL_INTLEVEL6_VECTOR_SIZE 0x00000038 +#define XSHAL_INTLEVEL6_VECTOR_ISROM 0 +#define XSHAL_DEBUG_VECTOR_SIZE XSHAL_INTLEVEL6_VECTOR_SIZE +#define XSHAL_DEBUG_VECTOR_ISROM XSHAL_INTLEVEL6_VECTOR_ISROM +#define XSHAL_NMI_VECTOR_SIZE 0x00000038 +#define XSHAL_NMI_VECTOR_ISROM 0 +#define XSHAL_INTLEVEL7_VECTOR_SIZE XSHAL_NMI_VECTOR_SIZE + +#endif /*XTENSA_CONFIG_SYSTEM_H*/ + diff --git a/src/platform/amd/acp_6_3/include/arch/xtensa/config/tie-asm.h b/src/platform/amd/acp_6_3/include/arch/xtensa/config/tie-asm.h new file mode 100644 index 000000000000..ce8f0103809b --- /dev/null +++ b/src/platform/amd/acp_6_3/include/arch/xtensa/config/tie-asm.h @@ -0,0 +1,366 @@ +/* + * tie-asm.h -- compile-time HAL assembler definitions dependent on CORE & TIE + * + * NOTE: This header file is not meant to be included directly. + */ + +/* This header file contains assembly-language definitions (assembly + macros, etc.) for this specific Xtensa processor's TIE extensions + and options. It is customized to this Xtensa processor configuration. + + Customer ID=7490; Build=0xa28f5; Copyright (c) 1999-2022 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 _XTENSA_CORE_TIE_ASM_H +#define _XTENSA_CORE_TIE_ASM_H + +#include + +/* Selection parameter values for save-area save/restore macros: */ +/* Option vs. TIE: */ +#define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */ +#define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */ +#define XTHAL_SAS_ANYOT 0x0003 /* both of the above */ +/* Whether used automatically by compiler: */ +#define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */ +#define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */ +#define XTHAL_SAS_ANYCC 0x000C /* both of the above */ +/* ABI handling across function calls: */ +#define XTHAL_SAS_CALR 0x0010 /* caller-saved */ +#define XTHAL_SAS_CALE 0x0020 /* callee-saved */ +#define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */ +#define XTHAL_SAS_ANYABI 0x0070 /* all of the above three */ +/* Misc */ +#define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */ +#define XTHAL_SAS3(optie,ccuse,abi) ( ((optie) & XTHAL_SAS_ANYOT) \ + | ((ccuse) & XTHAL_SAS_ANYCC) \ + | ((abi) & XTHAL_SAS_ANYABI) ) + + + /* + * Macro to store all non-coprocessor (extra) custom TIE and optional state + * (not including zero-overhead loop registers). + * Required parameters: + * ptr Save area pointer address register (clobbered) + * (register must contain a 4 byte aligned address). + * at1..at4 Four temporary address registers (first XCHAL_NCP_NUM_ATMPS + * registers are clobbered, the remaining are unused). + * Optional parameters: + * continue If macro invoked as part of a larger store sequence, set to 1 + * if this is not the first in the sequence. Defaults to 0. + * ofs Offset from start of larger sequence (from value of first ptr + * in sequence) at which to store. Defaults to next available space + * (or 0 if is 0). + * select Select what category(ies) of registers to store, as a bitmask + * (see XTHAL_SAS_xxx constants). Defaults to all registers. + * alloc Select what category(ies) of registers to allocate; if any + * category is selected here that is not in , space for + * the corresponding registers is skipped without doing any load. + */ + .macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0 + xchal_sa_start \continue, \ofs + // Optional global registers used by default by the compiler: + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~(\select) + xchal_sa_align \ptr, 0, 1016, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_+0 + wur.threadptr \at1 // threadptr option + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 1016, 4, 4 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .endif + // Optional caller-saved registers not used by default by the compiler: + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select) + xchal_sa_align \ptr, 0, 1012, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_+0 + wsr.br \at1 // boolean option + l32i \at1, \ptr, .Lxchal_ofs_+4 + wsr.scompare1 \at1 // conditional store option + .set .Lxchal_ofs_, .Lxchal_ofs_ + 8 + .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 1012, 4, 4 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 8 + .endif + .endm // xchal_ncp_load + + +#define XCHAL_NCP_NUM_ATMPS 1 + + /* + * Macro to store the state of TIE coprocessor AudioEngineLX. + * Required parameters: + * ptr Save area pointer address register (clobbered) + * (register must contain a 16 byte aligned address). + * at1..at4 Four temporary address registers (first XCHAL_CP1_NUM_ATMPS + * registers are clobbered, the remaining are unused). + * Optional parameters are the same as for xchal_ncp_store. + */ +#define xchal_cp_AudioEngineLX_store xchal_cp1_store + .macro xchal_cp1_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0 + xchal_sa_start \continue, \ofs + // Custom caller-saved registers not used by default by the compiler: + .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select) + xchal_sa_align \ptr, 0, 0, 16, 16 + ae_s64.i aed0, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_s64.i aed1, \ptr, .Lxchal_ofs_+0 + ae_s64.i aed2, \ptr, .Lxchal_ofs_+8 + ae_s64.i aed3, \ptr, .Lxchal_ofs_+16 + ae_s64.i aed4, \ptr, .Lxchal_ofs_+24 + ae_s64.i aed5, \ptr, .Lxchal_ofs_+32 + ae_s64.i aed6, \ptr, .Lxchal_ofs_+40 + ae_s64.i aed7, \ptr, .Lxchal_ofs_+48 + ae_s64.i aed8, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_s64.i aed9, \ptr, .Lxchal_ofs_+0 + ae_s64.i aed10, \ptr, .Lxchal_ofs_+8 + ae_s64.i aed11, \ptr, .Lxchal_ofs_+16 + ae_s64.i aed12, \ptr, .Lxchal_ofs_+24 + ae_s64.i aed13, \ptr, .Lxchal_ofs_+32 + ae_s64.i aed14, \ptr, .Lxchal_ofs_+40 + ae_s64.i aed15, \ptr, .Lxchal_ofs_+48 + ae_s64.i aed16, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_s64.i aed17, \ptr, .Lxchal_ofs_+0 + ae_s64.i aed18, \ptr, .Lxchal_ofs_+8 + ae_s64.i aed19, \ptr, .Lxchal_ofs_+16 + ae_s64.i aed20, \ptr, .Lxchal_ofs_+24 + ae_s64.i aed21, \ptr, .Lxchal_ofs_+32 + ae_s64.i aed22, \ptr, .Lxchal_ofs_+40 + ae_s64.i aed23, \ptr, .Lxchal_ofs_+48 + ae_s64.i aed24, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_s64.i aed25, \ptr, .Lxchal_ofs_+0 + ae_s64.i aed26, \ptr, .Lxchal_ofs_+8 + ae_s64.i aed27, \ptr, .Lxchal_ofs_+16 + ae_s64.i aed28, \ptr, .Lxchal_ofs_+24 + ae_s64.i aed29, \ptr, .Lxchal_ofs_+32 + ae_s64.i aed30, \ptr, .Lxchal_ofs_+40 + ae_s64.i aed31, \ptr, .Lxchal_ofs_+48 + ae_movae \at1, aep0 + s8i \at1, \ptr, .Lxchal_ofs_+56 + ae_movae \at1, aep1 + s8i \at1, \ptr, .Lxchal_ofs_+57 + ae_movae \at1, aep2 + s8i \at1, \ptr, .Lxchal_ofs_+58 + ae_movae \at1, aep3 + s8i \at1, \ptr, .Lxchal_ofs_+59 + addi.a \ptr, \ptr, 64 + ae_salign128.i u0, \ptr, .Lxchal_ofs_+0 + ae_salign128.i u1, \ptr, .Lxchal_ofs_+16 + ae_salign128.i u2, \ptr, .Lxchal_ofs_+32 + ae_salign128.i u3, \ptr, .Lxchal_ofs_+48 + addi.a \ptr, \ptr, -320 + ae_movdrzbvc aed0 // ureg AE_ZBIASV8C + ae_s64.i aed0, \ptr, .Lxchal_ofs_+0 + 0 + ae_movvfcrfsr aed0 // ureg FCR_FSR + ae_s64.i aed0, \ptr, .Lxchal_ofs_+8 + 0 + rur.ae_ovf_sar \at1 // ureg 240 + s32i \at1, \ptr, .Lxchal_ofs_+16 + rur.ae_bithead \at1 // ureg 241 + s32i \at1, \ptr, .Lxchal_ofs_+20 + rur.ae_ts_fts_bu_bp \at1 // ureg 242 + s32i \at1, \ptr, .Lxchal_ofs_+24 + rur.ae_cw_sd_no \at1 // ureg 243 + s32i \at1, \ptr, .Lxchal_ofs_+28 + rur.ae_cbegin0 \at1 // ureg 246 + s32i \at1, \ptr, .Lxchal_ofs_+32 + rur.ae_cend0 \at1 // ureg 247 + s32i \at1, \ptr, .Lxchal_ofs_+36 + rur.ae_cbegin1 \at1 // ureg 248 + s32i \at1, \ptr, .Lxchal_ofs_+40 + rur.ae_cend1 \at1 // ureg 249 + s32i \at1, \ptr, .Lxchal_ofs_+44 + rur.ae_cbegin2 \at1 // ureg 250 + s32i \at1, \ptr, .Lxchal_ofs_+48 + rur.ae_cend2 \at1 // ureg 251 + s32i \at1, \ptr, .Lxchal_ofs_+52 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 384 + .elseif ((XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 0, 16, 16 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 384 + .endif + .endm // xchal_cp1_store + + /* + * Macro to load the state of TIE coprocessor AudioEngineLX. + * Required parameters: + * ptr Save area pointer address register (clobbered) + * (register must contain a 16 byte aligned address). + * at1..at4 Four temporary address registers (first XCHAL_CP1_NUM_ATMPS + * registers are clobbered, the remaining are unused). + * Optional parameters are the same as for xchal_ncp_load. + */ +#define xchal_cp_AudioEngineLX_load xchal_cp1_load + .macro xchal_cp1_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0 + xchal_sa_start \continue, \ofs + // Custom caller-saved registers not used by default by the compiler: + .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select) + xchal_sa_align \ptr, 0, 0, 16, 16 + ae_l64.i aed0, \ptr, .Lxchal_ofs_+0 + 0 // ureg AE_ZBIASV8C + ae_movzbvcdr aed0 + ae_l64.i aed0, \ptr, .Lxchal_ofs_+8 + 0 // ureg FCR_FSR + ae_movfcrfsrv aed0 + l32i \at1, \ptr, .Lxchal_ofs_+16 + wur.ae_ovf_sar \at1 // ureg 240 + l32i \at1, \ptr, .Lxchal_ofs_+20 + wur.ae_bithead \at1 // ureg 241 + l32i \at1, \ptr, .Lxchal_ofs_+24 + wur.ae_ts_fts_bu_bp \at1 // ureg 242 + l32i \at1, \ptr, .Lxchal_ofs_+28 + wur.ae_cw_sd_no \at1 // ureg 243 + l32i \at1, \ptr, .Lxchal_ofs_+32 + wur.ae_cbegin0 \at1 // ureg 246 + l32i \at1, \ptr, .Lxchal_ofs_+36 + wur.ae_cend0 \at1 // ureg 247 + l32i \at1, \ptr, .Lxchal_ofs_+40 + wur.ae_cbegin1 \at1 // ureg 248 + l32i \at1, \ptr, .Lxchal_ofs_+44 + wur.ae_cend1 \at1 // ureg 249 + l32i \at1, \ptr, .Lxchal_ofs_+48 + wur.ae_cbegin2 \at1 // ureg 250 + l32i \at1, \ptr, .Lxchal_ofs_+52 + wur.ae_cend2 \at1 // ureg 251 + ae_l64.i aed0, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_l64.i aed1, \ptr, .Lxchal_ofs_+0 + ae_l64.i aed2, \ptr, .Lxchal_ofs_+8 + ae_l64.i aed3, \ptr, .Lxchal_ofs_+16 + ae_l64.i aed4, \ptr, .Lxchal_ofs_+24 + ae_l64.i aed5, \ptr, .Lxchal_ofs_+32 + ae_l64.i aed6, \ptr, .Lxchal_ofs_+40 + ae_l64.i aed7, \ptr, .Lxchal_ofs_+48 + ae_l64.i aed8, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_l64.i aed9, \ptr, .Lxchal_ofs_+0 + ae_l64.i aed10, \ptr, .Lxchal_ofs_+8 + ae_l64.i aed11, \ptr, .Lxchal_ofs_+16 + ae_l64.i aed12, \ptr, .Lxchal_ofs_+24 + ae_l64.i aed13, \ptr, .Lxchal_ofs_+32 + ae_l64.i aed14, \ptr, .Lxchal_ofs_+40 + ae_l64.i aed15, \ptr, .Lxchal_ofs_+48 + ae_l64.i aed16, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_l64.i aed17, \ptr, .Lxchal_ofs_+0 + ae_l64.i aed18, \ptr, .Lxchal_ofs_+8 + ae_l64.i aed19, \ptr, .Lxchal_ofs_+16 + ae_l64.i aed20, \ptr, .Lxchal_ofs_+24 + ae_l64.i aed21, \ptr, .Lxchal_ofs_+32 + ae_l64.i aed22, \ptr, .Lxchal_ofs_+40 + ae_l64.i aed23, \ptr, .Lxchal_ofs_+48 + ae_l64.i aed24, \ptr, .Lxchal_ofs_+56 + addi.a \ptr, \ptr, 64 + ae_l64.i aed25, \ptr, .Lxchal_ofs_+0 + ae_l64.i aed26, \ptr, .Lxchal_ofs_+8 + ae_l64.i aed27, \ptr, .Lxchal_ofs_+16 + ae_l64.i aed28, \ptr, .Lxchal_ofs_+24 + ae_l64.i aed29, \ptr, .Lxchal_ofs_+32 + ae_l64.i aed30, \ptr, .Lxchal_ofs_+40 + ae_l64.i aed31, \ptr, .Lxchal_ofs_+48 + addi.a \ptr, \ptr, 56 + l8ui \at1, \ptr, .Lxchal_ofs_+0 + ae_movea aep0, \at1 + l8ui \at1, \ptr, .Lxchal_ofs_+1 + ae_movea aep1, \at1 + l8ui \at1, \ptr, .Lxchal_ofs_+2 + ae_movea aep2, \at1 + l8ui \at1, \ptr, .Lxchal_ofs_+3 + ae_movea aep3, \at1 + addi.a \ptr, \ptr, 8 + ae_lalign128.i u0, \ptr, .Lxchal_ofs_+0 + ae_lalign128.i u1, \ptr, .Lxchal_ofs_+16 + ae_lalign128.i u2, \ptr, .Lxchal_ofs_+32 + ae_lalign128.i u3, \ptr, .Lxchal_ofs_+48 + .set .Lxchal_pofs_, .Lxchal_pofs_ + 320 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 64 + .elseif ((XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 0, 16, 16 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 384 + .endif + .endm // xchal_cp1_load + +#define XCHAL_CP1_NUM_ATMPS 1 +#define XCHAL_SA_NUM_ATMPS 1 + + /* Empty macros for unconfigured coprocessors: */ + .macro xchal_cp0_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp0_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp2_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp2_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp3_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp3_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp4_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp4_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp5_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp5_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp6_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp6_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp7_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp7_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + +#endif /*_XTENSA_CORE_TIE_ASM_H*/ + diff --git a/src/platform/amd/acp_6_3/include/arch/xtensa/config/tie.h b/src/platform/amd/acp_6_3/include/arch/xtensa/config/tie.h new file mode 100644 index 000000000000..22fe621c7127 --- /dev/null +++ b/src/platform/amd/acp_6_3/include/arch/xtensa/config/tie.h @@ -0,0 +1,211 @@ +/* + * tie.h -- compile-time HAL definitions dependent on CORE & TIE configuration + * + * NOTE: This header file is not meant to be included directly. + */ + +/* This header file describes this specific Xtensa processor's TIE extensions + that extend basic Xtensa core functionality. It is customized to this + Xtensa processor configuration. + + Customer ID=7490; Build=0xa28f5; Copyright (c) 1999-2022 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 XTENSA_CORE_TIE_H +#define XTENSA_CORE_TIE_H + +/* parasoft-begin-suppress ALL "This file not MISRA checked." */ + +#define XCHAL_CP_NUM 1 /* number of coprocessors */ +#define XCHAL_CP_MAX 2 /* max CP ID + 1 (0 if none) */ +#define XCHAL_CP_MASK 0x02 /* bitmask of all CPs by ID */ +#define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */ + +/* Basic parameters of each coprocessor: */ +#define XCHAL_CP1_NAME "AudioEngineLX" +#define XCHAL_CP1_IDENT AudioEngineLX +#define XCHAL_CP1_SA_SIZE 384 /* size of state save area */ +#define XCHAL_CP1_SA_ALIGN 16 /* min alignment of save area */ +#define XCHAL_CP_ID_AUDIOENGINELX 1 /* coprocessor ID (0..7) */ + +/* Filler info for unassigned coprocessors, to simplify arrays etc: */ +#define XCHAL_CP0_SA_SIZE 0 +#define XCHAL_CP0_SA_ALIGN 1 +#define XCHAL_CP2_SA_SIZE 0 +#define XCHAL_CP2_SA_ALIGN 1 +#define XCHAL_CP3_SA_SIZE 0 +#define XCHAL_CP3_SA_ALIGN 1 +#define XCHAL_CP4_SA_SIZE 0 +#define XCHAL_CP4_SA_ALIGN 1 +#define XCHAL_CP5_SA_SIZE 0 +#define XCHAL_CP5_SA_ALIGN 1 +#define XCHAL_CP6_SA_SIZE 0 +#define XCHAL_CP6_SA_ALIGN 1 +#define XCHAL_CP7_SA_SIZE 0 +#define XCHAL_CP7_SA_ALIGN 1 + +/* Save area for non-coprocessor optional and custom (TIE) state: */ +#define XCHAL_NCP_SA_SIZE 12 +#define XCHAL_NCP_SA_ALIGN 4 + +/* Total save area for optional and custom state (NCP + CPn): */ +#define XCHAL_TOTAL_SA_SIZE 400 /* with 16-byte align padding */ +#define XCHAL_TOTAL_SA_ALIGN 16 /* actual minimum alignment */ + +/* + * Detailed contents of save areas. + * NOTE: caller must define the XCHAL_SA_REG macro (not defined here) + * before expanding the XCHAL_xxx_SA_LIST() macros. + * + * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize, + * dbnum,base,regnum,bitsz,gapsz,reset,x...) + * + * s = passed from XCHAL_*_LIST(s), eg. to select how to expand + * ccused = set if used by compiler without special options or code + * abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global) + * kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg) + * opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg) + * name = lowercase reg name (no quotes) + * galign = group byte alignment (power of 2) (galign >= align) + * align = register byte alignment (power of 2) + * asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz) + * (not including any pad bytes required to galign this or next reg) + * dbnum = unique target number f/debug (see ) + * base = reg shortname w/o index (or sr=special, ur=TIE user reg) + * regnum = reg index in regfile, or special/TIE-user reg number + * bitsz = number of significant bits (regfile width, or ur/sr mask bits) + * gapsz = intervening bits, if bitsz bits not stored contiguously + * (padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize) + * reset = register reset value (or 0 if undefined at reset) + * x = reserved for future use (0 until then) + * + * To filter out certain registers, e.g. to expand only the non-global + * registers used by the compiler, you can do something like this: + * + * #define XCHAL_SA_REG(s,ccused,p...) SELCC##ccused(p) + * #define SELCC0(p...) + * #define SELCC1(abikind,p...) SELAK##abikind(p) + * #define SELAK0(p...) REG(p) + * #define SELAK1(p...) REG(p) + * #define SELAK2(p...) + * #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \ + * ...what you want to expand... + */ + +#define XCHAL_NCP_SA_NUM 3 +#define XCHAL_NCP_SA_LIST(s) \ + XCHAL_SA_REG(s,1,2,1,1, threadptr, 4, 4, 4,0x03E7, ur,231, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, br, 4, 4, 4,0x0204, sr,4 , 16,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, scompare1, 4, 4, 4,0x020C, sr,12 , 32,0,0,0) + +#define XCHAL_CP0_SA_NUM 0 +#define XCHAL_CP0_SA_LIST(s) /* empty */ + +#define XCHAL_CP1_SA_NUM 52 +#define XCHAL_CP1_SA_LIST(s) \ + XCHAL_SA_REG(s,0,0,1,0, ae_zbiasv8c,16, 8, 8,0x1029, ur,-1 , 16,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, fcr_fsr, 8, 8, 8,0x102A, ur,-1 , 7,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_ovf_sar, 4, 4, 4,0x03F0, ur,240, 15,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_bithead, 4, 4, 4,0x03F1, ur,241, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0,ae_ts_fts_bu_bp, 4, 4, 4,0x03F2, ur,242, 16,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cw_sd_no, 4, 4, 4,0x03F3, ur,243, 29,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cbegin0, 4, 4, 4,0x03F6, ur,246, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cend0, 4, 4, 4,0x03F7, ur,247, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cbegin1, 4, 4, 4,0x03F8, ur,248, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cend1, 4, 4, 4,0x03F9, ur,249, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cbegin2, 4, 4, 4,0x03FA, ur,250, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cend2, 4, 4, 4,0x03FB, ur,251, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed0, 8, 8, 8,0x1000, aed,0 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed1, 8, 8, 8,0x1001, aed,1 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed2, 8, 8, 8,0x1002, aed,2 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed3, 8, 8, 8,0x1003, aed,3 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed4, 8, 8, 8,0x1004, aed,4 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed5, 8, 8, 8,0x1005, aed,5 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed6, 8, 8, 8,0x1006, aed,6 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed7, 8, 8, 8,0x1007, aed,7 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed8, 8, 8, 8,0x1008, aed,8 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed9, 8, 8, 8,0x1009, aed,9 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed10, 8, 8, 8,0x100A, aed,10 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed11, 8, 8, 8,0x100B, aed,11 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed12, 8, 8, 8,0x100C, aed,12 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed13, 8, 8, 8,0x100D, aed,13 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed14, 8, 8, 8,0x100E, aed,14 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed15, 8, 8, 8,0x100F, aed,15 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed16, 8, 8, 8,0x1010, aed,16 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed17, 8, 8, 8,0x1011, aed,17 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed18, 8, 8, 8,0x1012, aed,18 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed19, 8, 8, 8,0x1013, aed,19 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed20, 8, 8, 8,0x1014, aed,20 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed21, 8, 8, 8,0x1015, aed,21 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed22, 8, 8, 8,0x1016, aed,22 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed23, 8, 8, 8,0x1017, aed,23 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed24, 8, 8, 8,0x1018, aed,24 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed25, 8, 8, 8,0x1019, aed,25 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed26, 8, 8, 8,0x101A, aed,26 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed27, 8, 8, 8,0x101B, aed,27 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed28, 8, 8, 8,0x101C, aed,28 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed29, 8, 8, 8,0x101D, aed,29 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed30, 8, 8, 8,0x101E, aed,30 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed31, 8, 8, 8,0x101F, aed,31 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep0, 1, 1, 1,0x1024, aep,0 , 8,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep1, 1, 1, 1,0x1025, aep,1 , 8,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep2, 1, 1, 1,0x1026, aep,2 , 8,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep3, 1, 1, 1,0x1027, aep,3 , 8,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u0,16,16,16,0x1020, u,0 ,128,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u1,16,16,16,0x1021, u,1 ,128,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u2,16,16,16,0x1022, u,2 ,128,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u3,16,16,16,0x1023, u,3 ,128,0,0,0) + +#define XCHAL_CP2_SA_NUM 0 +#define XCHAL_CP2_SA_LIST(s) /* empty */ + +#define XCHAL_CP3_SA_NUM 0 +#define XCHAL_CP3_SA_LIST(s) /* empty */ + +#define XCHAL_CP4_SA_NUM 0 +#define XCHAL_CP4_SA_LIST(s) /* empty */ + +#define XCHAL_CP5_SA_NUM 0 +#define XCHAL_CP5_SA_LIST(s) /* empty */ + +#define XCHAL_CP6_SA_NUM 0 +#define XCHAL_CP6_SA_LIST(s) /* empty */ + +#define XCHAL_CP7_SA_NUM 0 +#define XCHAL_CP7_SA_LIST(s) /* empty */ + +/* Byte length of instruction from its first nibble (op0 field), per FLIX. */ +#define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16 +/* Byte length of instruction from its first byte, per FLIX. */ +#define XCHAL_BYTE0_FORMAT_LENGTHS \ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,16 + +/* parasoft-end-suppress ALL "This file not MISRA checked." */ + +#endif /* XTENSA_CORE_TIE_H */ + diff --git a/src/platform/amd/acp_6_3/include/arch/xtensa/tie/xt_datacache.h b/src/platform/amd/acp_6_3/include/arch/xtensa/tie/xt_datacache.h new file mode 100644 index 000000000000..8e83064e2923 --- /dev/null +++ b/src/platform/amd/acp_6_3/include/arch/xtensa/tie/xt_datacache.h @@ -0,0 +1,132 @@ +// Customer ID=12153; Build=0x878bf; 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. + +/* Definitions for the xt_datacache TIE package */ + +/* Do not modify. This is automatically generated.*/ + +#ifndef _XTENSA_xt_datacache_HEADER +#define _XTENSA_xt_datacache_HEADER + +/* parasoft-begin-suppress ALL "This file not MISRA checked." */ + +#ifdef __XTENSA__ +#ifdef __XCC__ + +#ifndef _ASMLANGUAGE +#ifndef _NOCLANGUAGE +#ifndef __ASSEMBLER__ + +#include + +/* + * The following prototypes describe intrinsic functions + * corresponding to TIE instructions. Some TIE instructions + * may produce multiple results (designated as "out" operands + * in the iclass section) or may have operands used as both + * inputs and outputs (designated as "inout"). However, the C + * and C++ languages do not provide syntax that can express + * the in/out/inout constraints of TIE intrinsics. + * Nevertheless, the compiler understands these constraints + * and will check that the intrinsic functions are used + * correctly. To improve the readability of these prototypes, + * the "out" and "inout" parameters are marked accordingly + * with comments. + */ + +extern void _TIE_xt_datacache_DHI(const int * s, immediate i); +extern void _TIE_xt_datacache_DHI_B(const int * s, int i); +extern void _TIE_xt_datacache_DHU(const int * s, immediate i); +extern void _TIE_xt_datacache_DHWB(const int * s, immediate i); +extern void _TIE_xt_datacache_DHWBI(const int * s, immediate i); +extern void _TIE_xt_datacache_DHWBI_B(const int * s, int i); +extern void _TIE_xt_datacache_DHWB_B(const int * s, int i); +extern void _TIE_xt_datacache_DII(const int * s, immediate i); +extern void _TIE_xt_datacache_DIU(const int * s, immediate i); +extern void _TIE_xt_datacache_DIWB(const int * s, immediate i); +extern void _TIE_xt_datacache_DIWBI(const int * s, immediate i); +extern void _TIE_xt_datacache_DIWBUI_P(const int * s /*inout*/); +extern void _TIE_xt_datacache_DPFL(const int * s, immediate i); +extern void _TIE_xt_datacache_DPFM_B(const int * s, int i); +extern void _TIE_xt_datacache_DPFM_BF(const int * s, int i); +extern void _TIE_xt_datacache_DPFR(const int * s, immediate i); +extern void _TIE_xt_datacache_DPFRO(const int * s, immediate i); +extern void _TIE_xt_datacache_DPFR_B(const int * s, int i); +extern void _TIE_xt_datacache_DPFR_BF(const int * s, int i); +extern void _TIE_xt_datacache_DPFW(const int * s, immediate i); +extern void _TIE_xt_datacache_DPFWO(const int * s, immediate i); +extern void _TIE_xt_datacache_DPFW_B(const int * s, int i); +extern void _TIE_xt_datacache_DPFW_BF(const int * s, int i); +extern int _TIE_xt_datacache_LDCT(const int * s); +extern int _TIE_xt_datacache_LDCW(const int * s); +extern void _TIE_xt_datacache_PFEND_A(void); +extern void _TIE_xt_datacache_PFEND_O(void); +extern void _TIE_xt_datacache_PFNXT_F(void); +extern void _TIE_xt_datacache_PFWAIT_A(void); +extern void _TIE_xt_datacache_PFWAIT_R(void); +extern void _TIE_xt_datacache_SDCT(int t, int * s); +extern void _TIE_xt_datacache_SDCW(int t, int * s); + +#endif /*__ASSEMBLER__*/ +#endif /*_NOCLANGUAGE*/ +#endif /*_ASMLANGUAGE*/ + +#define XT_DHI _TIE_xt_datacache_DHI +#define XT_DHI_B _TIE_xt_datacache_DHI_B +#define XT_DHU _TIE_xt_datacache_DHU +#define XT_DHWB _TIE_xt_datacache_DHWB +#define XT_DHWBI _TIE_xt_datacache_DHWBI +#define XT_DHWBI_B _TIE_xt_datacache_DHWBI_B +#define XT_DHWB_B _TIE_xt_datacache_DHWB_B +#define XT_DII _TIE_xt_datacache_DII +#define XT_DIU _TIE_xt_datacache_DIU +#define XT_DIWB _TIE_xt_datacache_DIWB +#define XT_DIWBI _TIE_xt_datacache_DIWBI +#define XT_DIWBUI_P _TIE_xt_datacache_DIWBUI_P +#define XT_DPFL _TIE_xt_datacache_DPFL +#define XT_DPFM_B _TIE_xt_datacache_DPFM_B +#define XT_DPFM_BF _TIE_xt_datacache_DPFM_BF +#define XT_DPFR _TIE_xt_datacache_DPFR +#define XT_DPFRO _TIE_xt_datacache_DPFRO +#define XT_DPFR_B _TIE_xt_datacache_DPFR_B +#define XT_DPFR_BF _TIE_xt_datacache_DPFR_BF +#define XT_DPFW _TIE_xt_datacache_DPFW +#define XT_DPFWO _TIE_xt_datacache_DPFWO +#define XT_DPFW_B _TIE_xt_datacache_DPFW_B +#define XT_DPFW_BF _TIE_xt_datacache_DPFW_BF +#define XT_LDCT _TIE_xt_datacache_LDCT +#define XT_LDCW _TIE_xt_datacache_LDCW +#define XT_PFEND_A _TIE_xt_datacache_PFEND_A +#define XT_PFEND_O _TIE_xt_datacache_PFEND_O +#define XT_PFNXT_F _TIE_xt_datacache_PFNXT_F +#define XT_PFWAIT_A _TIE_xt_datacache_PFWAIT_A +#define XT_PFWAIT_R _TIE_xt_datacache_PFWAIT_R +#define XT_SDCT _TIE_xt_datacache_SDCT +#define XT_SDCW _TIE_xt_datacache_SDCW + +#endif /* __XCC__ */ + +#endif /* __XTENSA__ */ + + +/* parasoft-end-suppress ALL "This file not MISRA checked." */ + +#endif /* !_XTENSA_xt_datacache_HEADER */ diff --git a/src/platform/amd/acp_6_3/include/platform/chip_offset_byte.h b/src/platform/amd/acp_6_3/include/platform/chip_offset_byte.h new file mode 100644 index 000000000000..e1877a8d22f4 --- /dev/null +++ b/src/platform/amd/acp_6_3/include/platform/chip_offset_byte.h @@ -0,0 +1,195 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ + +#ifndef _ACP_6_3_OFFSET_HEADER +#define _ACP_6_3_OFFSET_HEADER + +#define PU_REGISTER_BASE (0x9FD00000 - 0x01240000) +#define PU_SCRATCH_REG_BASE (0x9FF00000 - 0x01250000) + +/* Registers from ACP_DMA block */ +#define ACP_DMA_CNTL_0 0x1240000 +#define ACP_DMA_DSCR_STRT_IDX_0 0x1240020 +#define ACP_DMA_DSCR_CNT_0 0x1240040 +#define ACP_DMA_PRIO_0 0x1240060 +#define ACP_DMA_DESC_BASE_ADDR 0x12400E0 +#define ACP_DMA_DESC_MAX_NUM_DSCR 0x12400E4 +#define ACP_DMA_CH_STS 0x12400E8 + +/* Registers from ACP_MISC block */ +#define ACP_CLKMUX_SEL 0x124102C +#define ACP_I2S_196MHZ_CLK_SEL 0x124105C +#define ACP_DSP0_INTR_CNTL 0x1241800 +#define ACP_DSP0_INTR_STAT 0x1241804 +#define ACP_DSP_SW_INTR_CNTL 0x1241808 +#define ACP_DSP_SW_INTR_STAT 0x124180C +#define ACP_SW_INTR_TRIG 0x1241810 +#define DSP_INTERRUPT_ROUTING_CTRL_0 0x1241814 +#define DSP_INTERRUPT_ROUTING_CTRL_1 0x1241818 +#define ACP_AXI2DAGB_SEM_0 0x1241874 +#define ACP_DSP0_INTR_CNTL1 0x1241920 +#define ACP_DSP0_INTR_STAT1 0x1241924 +#define ACP_SRBM_CLIENT_BASE_ADDR 0x12419EC +#define ACP_SRBM_CLIENT_RDDATA 0x12419F0 +#define ACP_SRBM_CYCLE_STS 0x12419F4 +#define ACP_SRBM_CLIENT_CONFIG 0x12419F8 + +/* Registers from ACP_P1_MISC block */ +#define ACP_EXTERNAL_INTR_ENB 0x1241A00 + +/* Registers from ACP_AUDIO_BUFFERS block */ +#define ACP_AUDIO_RX_RINGBUFADDR 0x1242000 +#define ACP_AUDIO_RX_FIFOADDR 0x124200C +#define ACP_AUDIO_TX_FIFOADDR 0x1242030 + +#define ACP_BT_RX_RINGBUFADDR 0x1242048 +#define ACP_BT_RX_RINGBUFSIZE 0x124204C +#define ACP_BT_RX_FIFOADDR 0x1242054 +#define ACP_BT_RX_FIFOSIZE 0x1242058 +#define ACP_BT_RX_DMA_SIZE 0x124205C +#define ACP_BT_RX_LINEARPOSITIONCNTR_HIGH 0x1242060 +#define ACP_BT_RX_LINEARPOSITIONCNTR_LOW 0x1242064 +#define ACP_BT_RX_INTR_WATERMARK_SIZE 0x1242068 +#define ACP_BT_TX_RINGBUFADDR 0x124206C +#define ACP_BT_TX_RINGBUFSIZE 0x1242070 +#define ACP_BT_TX_FIFOADDR 0x1242078 +#define ACP_BT_TX_FIFOSIZE 0x124207C +#define ACP_BT_TX_DMA_SIZE 0x1242080 +#define ACP_BT_TX_LINEARPOSITIONCNTR_HIGH 0x1242084 +#define ACP_BT_TX_LINEARPOSITIONCNTR_LOW 0x1242088 +#define ACP_BT_TX_INTR_WATERMARK_SIZE 0x124208C + +#define ACP_HS_RX_RINGBUFADDR 0x1242090 +#define ACP_HS_RX_RINGBUFSIZE 0x1242094 +#define ACP_HS_RX_FIFOADDR 0x124209C +#define ACP_HS_RX_FIFOSIZE 0x12420A0 +#define ACP_HS_RX_DMA_SIZE 0x12420A4 +#define ACP_HS_RX_LINEARPOSITIONCNTR_HIGH 0x12420A8 +#define ACP_HS_RX_LINEARPOSITIONCNTR_LOW 0x12420AC +#define ACP_HS_RX_INTR_WATERMARK_SIZE 0x12420B0 +#define ACP_HS_TX_RINGBUFADDR 0x12420B4 +#define ACP_HS_TX_RINGBUFSIZE 0x12420B8 +#define ACP_HS_TX_FIFOADDR 0x12420C0 +#define ACP_HS_TX_FIFOSIZE 0x12420C4 +#define ACP_HS_TX_DMA_SIZE 0x12420C8 +#define ACP_HS_TX_LINEARPOSITIONCNTR_HIGH 0x12420CC +#define ACP_HS_TX_LINEARPOSITIONCNTR_LOW 0x12420D0 +#define ACP_HS_TX_INTR_WATERMARK_SIZE 0x12420D4 + +/* Registers from ACP_I2S_TDM block */ +#define ACP_I2STDM_IER 0x1242400 +#define ACP_I2STDM_IRER 0x1242404 +#define ACP_I2STDM_RXFRMT 0x1242408 +#define ACP_I2STDM_ITER 0x124240C +#define ACP_I2STDM_TXFRMT 0x1242410 +#define ACP_I2STDM0_MSTRCLKGEN 0x1242414 +#define ACP_I2STDM2_MSTRCLKGEN 0x124241C + +/* Registers from ACP_BT_TDM block */ +#define ACP_BTTDM_IER 0x1242800 +#define ACP_BTTDM_IRER 0x1242804 +#define ACP_BTTDM_ITER 0x124280C +#define ACP_HSTDM_IER 0x1242814 +#define ACP_HSTDM_IRER 0x1242818 +#define ACP_HSTDM_RXFRMT 0x124281C +#define ACP_HSTDM_ITER 0x1242820 +#define ACP_HSTDM_TXFRMT 0x1242824 + +/* Registers from ACP_WOV block */ +#define ACP_WOV_PDM_ENABLE 0x1242C04 +#define ACP_WOV_PDM_DMA_ENABLE 0x1242C08 +#define ACP_WOV_RX_RINGBUFADDR 0x1242C0C +#define ACP_WOV_RX_RINGBUFSIZE 0x1242C10 +#define ACP_WOV_RX_INTR_WATERMARK_SIZE 0x1242C20 +#define ACP_WOV_PDM_FIFO_FLUSH 0x1242C24 +#define ACP_WOV_PDM_NO_OF_CHANNELS 0x1242C28 +#define ACP_WOV_PDM_DECIMATION_FACTOR 0x1242C2C +#define ACP_WOV_MISC_CTRL 0x1242C5C +#define ACP_WOV_CLK_CTRL 0x1242C60 + +/* Registers from ACP_P1_AUDIO_BUFFERS block */ +#define ACP_P1_I2S_RX_RINGBUFADDR 0x1243A00 +#define ACP_P1_I2S_RX_RINGBUFSIZE 0x1243A04 +#define ACP_P1_I2S_RX_FIFOADDR 0x1243A0C +#define ACP_P1_I2S_RX_FIFOSIZE 0x1243A10 +#define ACP_P1_I2S_RX_DMA_SIZE 0x1243A14 +#define ACP_P1_I2S_RX_LINEARPOSITIONCNTR_HIGH 0x1243A18 +#define ACP_P1_I2S_RX_LINEARPOSITIONCNTR_LOW 0x1243A1C +#define ACP_P1_I2S_RX_INTR_WATERMARK_SIZE 0x1243A20 +#define ACP_P1_I2S_TX_RINGBUFADDR 0x1243A24 +#define ACP_P1_I2S_TX_RINGBUFSIZE 0x1243A28 +#define ACP_P1_I2S_TX_FIFOADDR 0x1243A30 +#define ACP_P1_I2S_TX_FIFOSIZE 0x1243A34 +#define ACP_P1_I2S_TX_DMA_SIZE 0x1243A38 +#define ACP_P1_I2S_TX_LINEARPOSITIONCNTR_HIGH 0x1243A3C +#define ACP_P1_I2S_TX_LINEARPOSITIONCNTR_LOW 0x1243A40 +#define ACP_P1_I2S_TX_INTR_WATERMARK_SIZE 0x1243A44 +#define ACP_P1_BT_RX_RINGBUFADDR 0x1243A48 +#define ACP_P1_BT_RX_RINGBUFSIZE 0x1243A4C +#define ACP_P1_BT_RX_FIFOADDR 0x1243A54 +#define ACP_P1_BT_RX_FIFOSIZE 0x1243A58 +#define ACP_P1_BT_RX_DMA_SIZE 0x1243A5C +#define ACP_P1_BT_RX_LINEARPOSITIONCNTR_HIGH 0x1243A60 +#define ACP_P1_BT_RX_LINEARPOSITIONCNTR_LOW 0x1243A64 +#define ACP_P1_BT_RX_INTR_WATERMARK_SIZE 0x1243A68 +#define ACP_P1_BT_TX_RINGBUFADDR 0x1243A6C +#define ACP_P1_BT_TX_RINGBUFSIZE 0x1243A70 +#define ACP_P1_BT_TX_FIFOADDR 0x1243A78 +#define ACP_P1_BT_TX_FIFOSIZE 0x1243A7C +#define ACP_P1_BT_TX_DMA_SIZE 0x1243A80 +#define ACP_P1_BT_TX_LINEARPOSITIONCNTR_HIGH 0x1243A84 +#define ACP_P1_BT_TX_LINEARPOSITIONCNTR_LOW 0x1243A88 +#define ACP_P1_BT_TX_INTR_WATERMARK_SIZE 0x1243A8C +#define ACP_P1_HS_RX_RINGBUFADDR 0x1243A90 +#define ACP_P1_HS_RX_RINGBUFSIZE 0x1243A94 +#define ACP_P1_HS_RX_FIFOADDR 0x1243A9C +#define ACP_P1_HS_RX_FIFOSIZE 0x1243AA0 +#define ACP_P1_HS_RX_DMA_SIZE 0x1243AA4 +#define ACP_P1_HS_RX_LINEARPOSITIONCNTR_HIGH 0x1243AA8 +#define ACP_P1_HS_RX_LINEARPOSITIONCNTR_LOW 0x1243AAC +#define ACP_P1_HS_RX_INTR_WATERMARK_SIZE 0x1243AB0 +#define ACP_P1_HS_TX_RINGBUFADDR 0x1243AB4 +#define ACP_P1_HS_TX_RINGBUFSIZE 0x1243AB8 +#define ACP_P1_HS_TX_FIFOADDR 0x1243AC0 +#define ACP_P1_HS_TX_FIFOSIZE 0x1243AC4 +#define ACP_P1_HS_TX_DMA_SIZE 0x1243AC8 +#define ACP_P1_HS_TX_LINEARPOSITIONCNTR_HIGH 0x1243ACC +#define ACP_P1_HS_TX_LINEARPOSITIONCNTR_LOW 0x1243AD0 +#define ACP_P1_HS_TX_INTR_WATERMARK_SIZE 0x1243AD4 + +#define MP1_SMN_C2PMSG_69 0x58A14 +#define MP1_SMN_C2PMSG_85 0x58A54 +#define MP1_SMN_C2PMSG_93 0x58A74 + +#define CLK5_ROOTREFCLKMUX_1 0x6c0c8 +#define CLK5_CLK_PLL_REFCLK_RATE_STARTUP 0x6C0D0 +#define CLK5_CLK_PLL_REQ 0x6C0DC +#define CLK5_CLK1_DFS_CNTL 0x6C1B0 +#define CLK5_CLK1_CURRENT_CNT 0x6C348 +#define CLK5_CLK0_DFS_CNTL 0x6C1A4 +#define CLK5_CLK0_CURRENT_CNT 0x6C344 +#define CLK5_CLK0_BYPASS_CNTL 0x6C200 +#define CLK5_CLK1_BYPASS_CNTL 0x6C224 +#define CLK5_CLK0_DFS_STATUS 0x6C1AC +#define CLK5_CLK1_DFS_STATUS 0x6C1B8 +#define CLK5_SPLL_FIELD_2 0x6C114 +#define CLK5_CLK_PLL_PWR_REQ 0x6C2C0 +#define CLK5_CLK_DFSBYPASS_CONTROL 0x6C2C8 +#define CLK5_CLK_FSM_STATUS 0x6C2D4 +#define CLK5_SPLL_FUSE_1 0x6C0F8 +#define CLK5_SPLL_FUSE_2 0x6C0FC +#define CLK5_SPLL_FIELD_7 0x6C128 +#define CLK5_SPLL_FIELD_9 0x6C130 +#define CLK5_SPLL_FIELD_6nm 0x6C138 +#define CLK5_SPLL_FIELD_4 0x6C11C +#define CLK5_SPLL_FIELD_5nm_BUS_CTRL 0x6c140 +#define CLK5_SPLL_FIELD_5nm_BUS_WDATA 0x6c144 +#define CLK5_SPLL_FIELD_5nm_BUS_STATUS 0x6c148 +#define CLK5_CLK_PLL_RESET_STOP_TIMER 0x6C180 + +#endif diff --git a/src/platform/amd/acp_6_3/include/platform/chip_registers.h b/src/platform/amd/acp_6_3/include/platform/chip_registers.h new file mode 100644 index 000000000000..5ea907e2ff5b --- /dev/null +++ b/src/platform/amd/acp_6_3/include/platform/chip_registers.h @@ -0,0 +1,1062 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ +#if !defined(_ACP_6_3_REG_HEADER) +#define _ACP_6_3_REG_HEADER + +typedef union acp_dma_cntl_0 { + struct { + unsigned int dmachrst:1; + unsigned int dmachrun:1; + unsigned int dmachiocen:1; + unsigned int :29; + } bits; + unsigned int u32all; +} acp_dma_cntl_0_t; + +typedef union acp_dma_ch_sts { + struct { + unsigned int dmachrunsts:8; + unsigned int :24; + } bits; + unsigned int u32all; +} acp_dma_ch_sts_t; + +typedef union acp_external_intr_enb { + struct { + unsigned int acpextintrenb:1; + unsigned int :31; + } bits; + unsigned int u32all; +} acp_external_intr_enb_t; + +typedef union acp_dsp0_intr_cntl { + struct { + unsigned int dmaiocmask:8; + unsigned int :8; + unsigned int wov_dma_intr_mask:1; + unsigned int :6; + unsigned int audio_buffer_int_mask:6; + unsigned int :3; + } bits; + unsigned int u32all; +} acp_dsp0_intr_cntl_t; + +typedef union acp_dsp0_intr_stat { + struct { + unsigned int dmaiocstat:8; + unsigned int :8; + unsigned int wov_dma_stat:1; + unsigned int :6; + unsigned int audio_buffer_int_stat:6; + unsigned int :3; + } bits; + unsigned int u32all; +} acp_dsp0_intr_stat_t; + +typedef union acp_dsp0_intr_cntl1 { + struct { + unsigned int acp_fusion_dsp_ext_timer1_timeoutmask :1; + unsigned int fusion_dsp_watchdog_timeoutmask :1; + unsigned int soundwire_mask :1; + unsigned int audio_buffer_int_mask :6; + unsigned int :23; + } bits; + unsigned int u32all; +} acp_dsp0_intr_cntl1_t; + +typedef union acp_dsp0_intr_stat1 { + struct { + unsigned int acp_fusion_dsp_timer1_timeoutstat :1; + unsigned int fusion_dsp_watchdog_timeoutstat :1; + unsigned int soundwire_stat :1; + unsigned int audio_buffer_int_stat :6; + unsigned int :23; + } bits; + unsigned int u32all; +} acp_dsp0_intr_stat1_t; + +typedef union acp_dsp_sw_intr_cntl { + struct { + unsigned int :2; + unsigned int dsp0_to_host_intr_mask:1; + unsigned int :29; + } bits; + unsigned int u32all; +} acp_dsp_sw_intr_cntl_t; + +typedef union acp_dsp_sw_intr_stat { + struct { + unsigned int host_to_dsp0_intr1_stat:1; + unsigned int host_to_dsp0_intr2_stat:1; + unsigned int dsp0_to_host_intr_stat:1; + unsigned int host_to_dsp0_intr3_stat:1; + unsigned int :28; + } bits; + unsigned int u32all; +} acp_dsp_sw_intr_stat_t; + +typedef union acp_sw_intr_trig { + struct { + unsigned int trig_host_to_dsp0_intr1:1; + unsigned int :1; + unsigned int trig_dsp0_to_host_intr:1; + unsigned int :29; + } bits; + unsigned int u32all; +} acp_sw_intr_trig_t; + +typedef union dsp_interrupt_routing_ctrl_0 { + struct { + unsigned int dma_intr_level:3; + unsigned int :18; + unsigned int watchdog_intr_level:3; + unsigned int az_sw_i2s_intr_level:3; + unsigned int sha_intr_level:3; + unsigned int :2; + } bits; + unsigned int u32all; +} dsp_interrupt_routing_ctrl_0_t; + +typedef union dsp_interrupt_routing_ctrl_1 { + struct { + unsigned int host_to_dsp_intr1_level:3; + unsigned int host_to_dsp_intr2_level:3; + unsigned int src_intr_level:3; + unsigned int mailbox_intr_level:3; + unsigned int error_intr_level:3; + unsigned int wov_intr_level:3; + unsigned int fusion_timer1_intr_level:3; + unsigned int fusion_watchdog_intr_level:3; + unsigned int p1_sw_i2s_intr_level:3; + unsigned int :5; + } bits; + unsigned int u32all; +} dsp_interrupt_routing_ctrl_1_t; + +typedef union acp_i2s_rx_ringbufaddr { + struct { + unsigned int i2s_rx_ringbufaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_i2s_rx_ringbufaddr_t; + +typedef union acp_i2s_rx_ringbufsize { + struct { + unsigned int i2s_rx_ringbufsize:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_i2s_rx_ringbufsize_t; + +typedef union acp_i2s_rx_linkpositioncntr { + struct { + unsigned int i2s_rx_linkpositioncntr:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_i2s_rx_linkpositioncntr_t; + +typedef union acp_i2s_rx_fifoaddr { + struct { + unsigned int i2s_rx_fifoaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_i2s_rx_fifoaddr_t; + +typedef union acp_i2s_rx_fifosize { + struct { + unsigned int i2s_rx_fifosize:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_i2s_rx_fifosize_t; + +typedef union acp_i2s_rx_dma_size { + struct { + unsigned int i2s_rx_dma_size:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_i2s_rx_dma_size_t; + +typedef union acp_i2s_rx_linearpositioncntr_high { + struct { + unsigned int i2s_rx_linearpositioncntr_high:32; + } bits; + unsigned int u32all; +} acp_i2s_rx_linearpositioncntr_high_t; + +typedef union acp_i2s_rx_linearpositioncntr_low { + struct { + unsigned int i2s_rx_linearpositioncntr_low:32; + } bits; + unsigned int u32all; +} acp_i2s_rx_linearpositioncntr_low_t; + +typedef union acp_i2s_rx_watermark_size { + struct { + unsigned int i2s_rx_intr_watermark_size:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_i2s_rx_intr_watermark_size_t; + +typedef union acp_i2s_tx_ringbufaddr { + struct { + unsigned int i2s_tx_ringbufaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_i2s_tx_ringbufaddr_t; + +typedef union acp_i2s_tx_ringbufsize { + struct { + unsigned int i2s_tx_ringbufsize:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_i2s_tx_ringbufsize_t; + +typedef union acp_i2s_tx_linkpositioncntr { + struct { + unsigned int i2s_tx_linkpositioncntr:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_i2s_tx_linkpositioncntr_t; + +typedef union acp_i2s_tx_fifoaddr { + struct { + unsigned int i2s_tx_fifoaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_i2s_tx_fifoaddr_t; + +typedef union acp_i2s_tx_fifosize { + struct { + unsigned int i2s_tx_fifosize:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_i2s_tx_fifosize_t; + +typedef union acp_i2s_tx_dma_size { + struct { + unsigned int i2s_tx_dma_size:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_i2s_tx_dma_size_t; + +typedef union acp_i2s_tx_linearpositioncntr_high { + struct { + unsigned int i2s_tx_linearpositioncntr_high:32; + } bits; + unsigned int u32all; +} acp_i2s_tx_linearpositioncntr_hight_t; + +typedef union acp_i2s_tx_linearpositioncntr_low { + struct { + unsigned int i2s_tx_linearpositioncntr_low:32; + } bits; + unsigned int u32all; +} acp_i2s_tx_linearpositioncntr_low_t; + +typedef union acp_i2s_tx_intr_watermark_size { + struct { + unsigned int i2s_tx_intr_watermark_size:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_i2s_tx_intr_watermark_size_t; + +typedef union acp_bt_rx_ringbufaddr { + struct { + unsigned int bt_rx_ringbufaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_bt_rx_ringbufaddr_t; + +typedef union acp_bt_rx_ringbufsize { + struct { + unsigned int bt_rx_ringbufsize:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_bt_rx_ringbufsize_t; + +typedef union acp_bt_rx_linkpositioncntr { + struct { + unsigned int bt_rx_linkpositioncntr:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_bt_rx_linkpositioncntr_t; + +typedef union acp_bt_rx_fifoaddr { + struct { + unsigned int bt_rx_fifoaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_bt_rx_fifoaddr_t; + +typedef union acp_bt_rx_fifosize { + struct { + unsigned int bt_rx_fifosize:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_bt_rx_fifosize_t; + +typedef union acp_bt_rx_dma_size { + struct { + unsigned int bt_rx_dma_size:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_bt_rx_dma_size_t; + +typedef union acp_bt_rx_linearpositioncntr_high { + struct { + unsigned int bt_rx_linearpositioncntr_high:32; + } bits; + unsigned int u32all; +} acp_bt_rx_linearpositioncntr_high_t; + +typedef union acp_bt_rx_linearpositioncntr_low { + struct { + unsigned int bt_rx_linearpositioncntr_low:32; + } bits; + unsigned int u32all; +} acp_bt_rx_linearpositioncntr_low_t; + +typedef union acp_bt_rx_intr_watermark_size { + struct { + unsigned int bt_rx_intr_watermark_size:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_bt_rx_intr_watermark_size_t; + +typedef union acp_bt_tx_ringbufaddr { + struct { + unsigned int bt_tx_ringbufaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_bt_tx_ringbufaddr_t; + +typedef union acp_bt_tx_ringbufsize { + struct { + unsigned int bt_tx_ringbufsize:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_bt_tx_ringbufsize_t; + +typedef union acp_bt_tx_linkpositiontcntr { + struct { + unsigned int bt_tx_linkpositioncntr:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_bt_tx_linkpositiontcntr_t; + +typedef union acp_bt_tx_fifoaddr { + struct { + unsigned int bt_tx_fifoaddr:27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_bt_tx_fifoaddr_t; + +typedef union acp_bt_tx_fifosize { + struct { + unsigned int bt_tx_fifosize:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_bt_tx_fifosize_t; + +typedef union acp_bt_tx_dmasize { + struct { + unsigned int bt_tx_dma_size:13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_bt_tx_dmasize_t; + +typedef union acp_bt_tx_linearpositioncntr_high { + struct { + unsigned int bt_tx_linearpositioncntr_high:32; + } bits; + unsigned int u32all; +} acp_bt_tx_linearpositioncntr_high_t; + +typedef union acp_bt_tx_linearpositioncntr_low { + struct { + unsigned int bt_tx_linearpositioncntr_low:32; + } bits; + unsigned int u32all; +} acp_bt_tx_linearpositioncntr_low_t; + +typedef union acp_bt_tx_intr_watermark_size { + struct { + unsigned int bt_tx_intr_watermark_size:26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_bt_tx_intr_watermark_size_t; + +typedef union acp_i2stdm_ier { + struct { + unsigned int i2stdm_ien:1; + unsigned int :31; + } bits; + unsigned int u32all; +} acp_i2stdm_ier_t; + +typedef union acp_i2stdm_irer { + struct { + unsigned int i2stdm_rx_en:1; + unsigned int i2stdm_rx_protocol_mode:1; + unsigned int i2stdm_rx_data_path_mode:1; + unsigned int i2stdm_rx_samplen:3; + unsigned int i2stdm_rx_status:1; + unsigned int :25; + } bits; + unsigned int u32all; +} acp_i2stdm_irer_t; + +typedef union acp_i2stdm_iter { + struct { + unsigned int i2stdm_txen:1; + unsigned int i2stdm_tx_protocol_mode:1; + unsigned int i2stdm_tx_data_path_mode:1; + unsigned int i2stdm_tx_samp_len:3; + unsigned int i2stdm_tx_status:1; + unsigned int :25; + } bits; + unsigned int u32all; +} acp_i2stdm_iter_t; + +typedef union acp_bttdm_ier { + struct { + unsigned int bttdm_ien:1; + unsigned int :31; + } bits; + unsigned int u32all; +} acp_bttdm_ier_t; + +typedef union acp_bttdm_irer { + struct { + unsigned int bttdm_rx_en:1; + unsigned int bttdm_rx_protocol_mode:1; + unsigned int bttdm_rx_data_path_mode:1; + unsigned int bttdm_rx_samplen:3; + unsigned int bttdm_rx_status:1; + unsigned int :25; + } bits; + unsigned int u32all; +} acp_bttdm_irer_t; + +typedef union acp_bttdm_iter { + struct { + unsigned int bttdm_txen :1; + unsigned int bttdm_tx_protocol_mode :1; + unsigned int bttdm_tx_data_path_mode :1; + unsigned int bttdm_tx_samp_len :3; + unsigned int bttdm_tx_status :1; + unsigned int :25; + } bits; + unsigned int u32all; +} acp_bttdm_iter_t; + +typedef union acp_wov_pdm_dma_enable { + struct { + unsigned int pdm_dma_en :1; + unsigned int pdm_dma_en_status :1; + unsigned int :30; + } bits; +unsigned int u32all; +} acp_wov_pdm_dma_enable_t; + +typedef union acp_wov_rx_ringbufaddr { + struct { + unsigned int rx_ringbufaddr :27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_wov_rx_ringbufaddr_t; + +typedef union acp_wov_rx_ringbufsize { + struct { + unsigned int rx_ringbufsize :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_wov_rx_ringbufsize_t; + +typedef union acp_wov_rx_intr_watermark_size { + struct { + unsigned int rx_intr_watermark_size :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_wov_rx_intr_watermark_size_t; + +typedef union acp_wov_pdm_no_of_channels { + struct { + unsigned int pdm_no_of_channels :2; + unsigned int :30; + } bits; + unsigned int u32all; +} acp_wov_pdm_no_of_channels_t; + +typedef union acp_wov_pdm_decimation_factor { + struct { + unsigned int pdm_decimation_factor :2; + unsigned int :30; + } bits; + unsigned int u32all; +} acp_wov_pdm_decimation_factor_t; + +typedef union acp_wov_misc_ctrl { + struct { + unsigned int :3; + unsigned int pcm_data_shift_ctrl :2; + unsigned int :27; + } bits; + unsigned int u32all; +} acp_wov_misc_ctrl_t; + +typedef union acp_wov_clk_ctrl { + struct { + unsigned int brm_clk_ctrl :4; + unsigned int pdm_vad_clkdiv :2; + unsigned int :26; + } bits; + unsigned int u32all; +} acp_wov_clk_ctrl_t; + +typedef union acp_srbm_cycle_sts { + struct { + unsigned int srbm_clients_sts :1; + unsigned int :7; + } bits; + unsigned int u32all; +} acp_srbm_cycle_sts_t; + +typedef union acp_hs_rx_ringbufaddr { + struct { + unsigned int hs_rx_ringbufaddr :32; + } bits; + unsigned int u32all; +} acp_hs_rx_ringbufaddr_t; + +typedef union acp_hs_rx_ringbufsize { + struct { + unsigned int hs_rx_ringbufsize :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_hs_rx_ringbufsize_t; + +typedef union acp_hs_rx_linkpositioncntr { + struct { + unsigned int hs_rx_linkpositioncntr :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_hs_rx_linkpositioncntr_t; + +typedef union acp_hs_rx_fifoaddr { + struct { + unsigned int hs_rx_fifoaddr :27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_hs_rx_fifoaddr_t; + +typedef union acp_hs_rx_fifosize { + struct { + unsigned int hs_rx_fifosize :13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_hs_rx_fifosize_t; + +typedef union acp_hs_rx_dma_size { + struct { + unsigned int hs_rx_dma_size :13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_hs_rx_dma_size_t; + +typedef union acp_hs_rx_linearpositioncntr_high { + struct { + unsigned int hs_rx_linearpositioncntr_high :32; + } bits; + unsigned int u32all; +} acp_hs_rx_linearpositioncntr_high_t; + +typedef union acp_hs_rx_linearpositioncntr_low { + struct { + unsigned int hs_rx_linearpositioncntr_low :32; + } bits; + unsigned int u32all; +} acp_hs_rx_linearpositioncntr_low_t; + +typedef union acp_hs_rx_intr_watermark_size { + struct { + unsigned int hs_rx_intr_watermark_size :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_hs_rx_intr_watermark_size_t; + +typedef union acp_hs_tx_ringbufaddr { + struct { + unsigned int hs_tx_ringbufaddr :32; + } bits; + unsigned int u32all; +} acp_hs_tx_ringbufaddr_t; + +typedef union acp_hs_tx_ringbufsize { + struct { + unsigned int hs_tx_ringbufsize :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_hs_tx_ringbufsize_t; + +typedef union acp_hs_tx_linkpositioncntr { + struct { + unsigned int hs_tx_linkpositioncntr :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_hs_tx_linkpositioncntr_t; + +typedef union acp_hs_tx_fifoaddr { + struct { + unsigned int hs_tx_fifoaddr :27; + unsigned int :5; + } bits; + unsigned int u32all; +} acp_hs_tx_fifoaddr_t; + +typedef union acp_hs_tx_fifosize { + struct { + unsigned int hs_tx_fifosize :13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_hs_tx_fifosize_t; + +typedef union acp_hs_tx_dma_size { + struct { + unsigned int hs_tx_dma_size :13; + unsigned int :19; + } bits; + unsigned int u32all; +} acp_hs_tx_dma_size_t; + +typedef union acp_hs_tx_linearpositioncntr_high { + struct { + unsigned int hs_tx_linearpositioncntr_high :32; + } bits; + unsigned int u32all; +} acp_hs_tx_linearpositioncntr_high_t; + +typedef union acp_hs_tx_linearpositioncntr_low { + struct { + unsigned int hs_tx_linearpositioncntr_low :32; + } bits; + unsigned int u32all; +} acp_hs_tx_linearpositioncntr_low_t; + +typedef union acp_hs_tx_intr_watermark_size { + struct { + unsigned int hs_tx_intr_watermark_size :26; + unsigned int :6; + } bits; + unsigned int u32all; +} acp_hs_tx_intr_watermark_size_t; + +typedef union acp_i2stdm_rxfrmt { + struct { + unsigned int i2stdm_frame_len :9; + unsigned int :6; + unsigned int i2stdm_num_slots :3; + unsigned int i2stdm_slot_len :5; + unsigned int :9; + } bits; + unsigned int u32all; +} acp_i2stdm_rxfrmt_t; + +typedef union acp_i2stdm_txfrmt { + struct { + unsigned int i2stdm_frame_len :9; + unsigned int :6; + unsigned int i2stdm_num_slots :3; + unsigned int i2stdm_slot_len :5; + unsigned int :9; + } bits; + unsigned int u32all; +} acp_i2stdm_txfrmt_t; + +typedef union acp_hstdm_ier { + struct { + unsigned int hstdm_ien :1; + unsigned int :31; + } bits; + unsigned int u32all; +} acp_hstdm_ier_t; + +typedef union acp_hstdm_irer { + struct { + unsigned int hstdm_rx_en :1; + unsigned int hstdm_rx_protocol_mode :1; + unsigned int hstdm_rx_data_path_mode :1; + unsigned int hstdm_rx_samplen :3; + unsigned int hstdm_rx_status :1; + unsigned int :25; + } bits; + unsigned int u32all; +} acp_hstdm_irer_t; + +typedef union acp_hstdm_rxfrmt { + struct { + unsigned int hstdm_frame_len :9; + unsigned int :6; + unsigned int hstdm_num_slots :3; + unsigned int hstdm_slot_len :5; + unsigned int :9; + } bits; + unsigned int u32all; +} acp_hstdm_rxfrmt_t; + +typedef union acp_hstdm_iter { + struct { + unsigned int hstdm_txen :1; + unsigned int hstdm_tx_protocol_mode :1; + unsigned int hstdm_tx_data_path_mode :1; + unsigned int hstdm_tx_samp_len :3; + unsigned int hstdm_tx_status :1; + unsigned int :25; + } bits; + unsigned int u32all; +} acp_hstdm_iter_t; + +typedef union acp_hstdm_txfrmt { + struct { + unsigned int hstdm_frame_len :9; + unsigned int :6; + unsigned int hstdm_num_slots :3; + unsigned int hstdm_slot_len :5; + unsigned int :9; + } bits; + unsigned int u32all; +} acp_hstdm_txfrmt_t; + +typedef union acp_clkmux_sel { + struct { + unsigned int acp_clkmux_sel : 3; + unsigned int : 13; + unsigned int acp_clkmux_div_value : 16; + } bits; + unsigned int u32all; +} acp_clkmux_sel_t; + +typedef union acp_i2stdm_mstrclkgen { + struct { + unsigned int i2stdm_master_mode : 1; + unsigned int i2stdm_format_mode : 1; + unsigned int i2stdm_lrclk_div_val : 11; + unsigned int i2stdm_bclk_div_val : 11; + unsigned int : 8; + } bits; + unsigned int u32all; +} acp_i2stdm_mstrclkgen_t; + +typedef union clk5_clk1_dfs_cntl_u { + struct { + unsigned int CLK1_DIVIDER : 7; + unsigned int : 25; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_clk1_dfs_cntl_u_t; + +typedef union clk5_clk1_dfs_status_u { + struct { + unsigned int : 16; + unsigned int CLK1_DFS_DIV_REQ_IDLE : 1; + unsigned int : 2; + unsigned int RO_CLK1_DFS_STATE_IDLE : 1; + unsigned int CLK1_CURRENT_DFS_DID : 7; + unsigned int : 5; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_clk1_dfs_status_u_t; + +typedef union clk5_clk1_bypass_cntl_u { + struct { + unsigned int CLK1_BYPASS_SEL : 3; + unsigned int : 13; + unsigned int CLK1_BYPASS_DIV : 4; + unsigned int : 12; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_clk1_bypass_cntl_u_t; + +typedef union clk5_clk_fsm_status_u { + struct { + unsigned int AUTOLAUCH_FSM_FULL_SPEED_IDLE : 1; + unsigned int : 3; + unsigned int AUTOLAUCH_FSM_BYPASS_IDLE : 1; + unsigned int : 3; + unsigned int RO_FSM_PLL_STATUS_STARTED : 1; + unsigned int : 3; + unsigned int RO_FSM_PLL_STATUS_STOPPED : 1; + unsigned int : 3; + unsigned int RO_EARLY_FSM_DONE : 1; + unsigned int : 3; + unsigned int RO_DFS_GAP_ACTIVE : 1; + unsigned int : 3; + unsigned int RO_DID_FSM_IDLE : 1; + unsigned int : 7; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_clk_fsm_status_t; + +typedef union clk5_clk_pll_req_u { + struct { + unsigned int fbmult_int : 9; + unsigned int : 3; + unsigned int pllspinediv : 4; + unsigned int fbmult_frac : 16; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_clk_pll_req_u_t; + +typedef union clk5_clk_pll_refclk_startup { + struct { + unsigned int main_pll_ref_clk_rate_startup : 8; + unsigned int main_pll_cfg_4_startup : 8; + unsigned int main_pll_ref_clk_div_startup : 2; + unsigned int main_pll_cfg_3_startup : 10; + unsigned int : 1; + unsigned int main_pll_refclk_src_mux0_startup : 1; + unsigned int main_pll_refclk_src_mux1_startup : 1; + unsigned int : 1; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_clk_pll_refclk_startup_t; + +typedef union clk5_spll_field_2 { + struct{ + unsigned int : 3; + unsigned int spll_fbdiv_mask_en : 1; + unsigned int spll_fracn_en : 1; + unsigned int spll_freq_jump_en : 1; + unsigned int : 25; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_spll_field_2_t; + +typedef union clk5_clk_dfsbypass_cntl { + struct { + unsigned int enter_dfs_bypass_0 : 1; + unsigned int enter_dfs_bypass_1 : 1; + unsigned int : 14; + unsigned int exit_dfs_bypass_0 : 1; + unsigned int exit_dfs_bypass_1 : 1; + unsigned int : 14; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_clk_dfsbypass_cntl_t; + +typedef union clk5_clk_pll_pwr_req { + struct { + unsigned int PLL_AUTO_START_REQ : 1; + unsigned int : 3; + unsigned int PLL_AUTO_STOP_REQ : 1; + unsigned int : 3; + unsigned int PLL_AUTO_STOP_NOCLK_REQ : 1; + unsigned int : 3; + unsigned int PLL_AUTO_STOP_REFBYPCLK_REQ : 1; + unsigned int : 3; + unsigned int PLL_FORCE_RESET_HIGH : 1; + unsigned int : 15; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_clk_pll_pwr_req_t; + +typedef union clk5_spll_fuse_1 { + struct { + unsigned int : 8; + unsigned int spll_gp_coarse_exp : 4; + unsigned int spll_gp_coarse_mant : 4; + unsigned int : 4; + unsigned int spll_gi_coarse_exp : 4; + unsigned int : 1; + unsigned int spll_gi_coarse_mant : 2; + unsigned int : 5; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_spll_fuse_1_t; + +typedef union clk5_spll_fuse_2 { + struct { + unsigned int spll_tdc_resolution : 8; + unsigned int spll_freq_offset_exp : 4; + unsigned int spll_freq_offset_mant : 5; + unsigned int : 15; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_spll_fuse_2_t; + +typedef union clk5_spll_field_9 { + struct { + unsigned int : 16; + unsigned int spll_dpll_cfg_3 : 10; + unsigned int spll_fll_mode : 1; + unsigned int : 5; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_spll_field_9_t; + +typedef union clk5_spll_field_6nm { + struct { + unsigned int spll_dpll_cfg_4 : 8; + unsigned int spll_reg_tim_exp : 3; + unsigned int spll_reg_tim_mant : 1; + unsigned int spll_ref_tim_exp : 3; + unsigned int spll_ref_tim_mant : 1; + unsigned int spll_vco_pre_div : 2; + unsigned int : 14; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_spll_field_6nm_t; + +typedef union clk5_spll_field_7 { + struct { + unsigned int : 7; + unsigned int spll_pllout_sel : 1; + unsigned int spll_pllout_req : 1; + unsigned int spll_pllout_state : 2; + unsigned int spll_postdiv_ovrd : 4; + unsigned int spll_postdiv_pllout_ovrd : 4; + unsigned int spll_postdiv_sync_enable : 1; + unsigned int : 1; + unsigned int spll_pwr_state : 2; + unsigned int : 1; + unsigned int spll_refclk_rate : 8; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_spll_field_7_t; + +typedef union clk5_spll_field_4 { + struct { + unsigned int spll_fcw0_frac_ovrd : 16; + unsigned int pll_out_sel : 1; + unsigned int : 3; + unsigned int pll_pwr_dn_state : 2; + unsigned int : 2; + unsigned int spll_refclk_div : 2; + unsigned int : 6; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_spll_field_4_t; + +typedef union clk5_spll_field_5nm_bus_ctrl { + struct { + unsigned int bus_spll_async_mode :1; + unsigned int bus_spll_apb_mode :1; + unsigned int bus_spll_addr :8; + unsigned int bus_spll_byte_en :4; + unsigned int bus_spll_rdtr :1; + unsigned int bus_spll_resetb :1; + unsigned int bus_spll_sel :1; + unsigned int bus_spll_wrtr :1; + unsigned int :14; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_spll_field_5nm_bus_ctrl_t; + +typedef union clk5_spll_field_5nm_bus_wdata { + struct { + unsigned int bus_spll_wr_data; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_spll_field_5nm_bus_wdata_t; + +typedef union clk5_rootrefclk_mux_1 { + struct { + unsigned int ROOTREFCLK_MUX_1 : 1; + unsigned int reserved : 31; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_rootrefclk_mux_1_t; + +typedef union clk5_spll_field_5nm_bus_status { + struct { + unsigned int spll_bus_error :1; + unsigned int spll_bus_rd_valid :1; + unsigned int spll_bus_wr_ack :1; + unsigned int :29; + } bitfields, bits; + uint32_t u32all; + int32_t i32all; + float f32all; +} clk5_spll_field_5nm_bus_status_t; + +#endif diff --git a/src/platform/amd/acp_6_3/include/platform/drivers/interrupt.h b/src/platform/amd/acp_6_3/include/platform/drivers/interrupt.h new file mode 100644 index 000000000000..6197427cdf92 --- /dev/null +++ b/src/platform/amd/acp_6_3/include/platform/drivers/interrupt.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ +#ifdef __SOF_DRIVERS_INTERRUPT_H__ + +#ifndef __PLATFORM_DRIVERS_INTERRUPT_H__ +#define __PLATFORM_DRIVERS_INTERRUPT_H__ + +#include +#include +#include + +#define PLATFORM_IRQ_HW_NUM 9 + +#define PLATFORM_IRQ_FIRST_CHILD 5 + +#define PLATFORM_IRQ_CHILDREN 32 + +/* IRQ numbers - wrt Tensilica DSP */ +#define IRQ_NUM_SOFTWARE0 1 /* level 1 */ + +#define IRQ_NUM_TIMER0 0 /* level 1 */ + +#define IRQ_NUM_EXT_LEVEL3 3 /* level 1 */ + +#define IRQ_NUM_TIMER1 6 /* level 2 */ + +#define IRQ_NUM_EXT_LEVEL4 4 /* level 2 */ + +#define IRQ_NUM_EXT_LEVEL5 5 /* level 3 */ + +/* IRQ Masks */ +#define IRQ_MASK_SOFTWARE0 BIT(IRQ_NUM_SOFTWARE0) + +#define IRQ_MASK_TIMER0 BIT(IRQ_NUM_TIMER0) + +#define IRQ_MASK_TIMER1 BIT(IRQ_NUM_TIMER1) + +#define IRQ_MASK_EXT_LEVEL3 BIT(IRQ_NUM_EXT_LEVEL3) + +#define IRQ_MASK_EXT_LEVEL4 BIT(IRQ_NUM_EXT_LEVEL4) + +#define IRQ_MASK_EXT_LEVEL5 BIT(IRQ_NUM_EXT_LEVEL5) + +#define HOST_TO_DSP_INTR 0x1 + +#define _XTSTR(x) # x + +#define XTSTR(x) _XTSTR(x) + +/* Enabling flag */ +#define INTERRUPT_ENABLE 1 + +/* Clearing flag */ +#define INTERRUPT_CLEAR 0 + +/* Disable flag */ +#define INTERRUPT_DISABLE 0 + +/* brief Tensilica Interrupt Levels. */ +typedef enum { + acp_interrupt_level_3 = 0, + + acp_interrupt_level_4, + + acp_interrupt_level_5, + + acp_interrupt_level_nmi, + + acp_interrupt_level_max +} artos_interrupt_levels_t; + +/* brief Tensilica timer control */ +typedef enum { + acp_timer_cntl_disable = 0, + + acp_timer_cntl_oneshot, + + acp_timer_cntl_periodic, + + acp_timer_cntl_max +} artos_timer_control_t; + +/* Disable Host to DSP interrupt */ +void acp_dsp_sw_intr_disable(void); + +void acp_intr_route(void); + +void acp_dsp_to_host_intr_trig(void); + +void acp_ack_intr_from_host(void); + +void acp_dsp_sw_intr_enable(void); + +void acp_intr_enable(void); + +void acp_intr_disable(void); + +#endif /* __PLATFORM_DRIVERS_INTERRUPT_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/drivers/interrupt.h" + +#endif /* __SOF_DRIVERS_INTERRUPT_H__ */ diff --git a/src/platform/amd/acp_6_3/include/platform/fw_scratch_mem.h b/src/platform/amd/acp_6_3/include/platform/fw_scratch_mem.h new file mode 100644 index 000000000000..9f77a7d33383 --- /dev/null +++ b/src/platform/amd/acp_6_3/include/platform/fw_scratch_mem.h @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 AMD. All rights reserved. + * + * Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ +#ifndef __EXT_SCRATCH_MEM_H__ +#define __EXT_SCRATCH_MEM_H__ + +#include + +/* MAX number of DMA descriptors */ +#define MAX_NUM_DMA_DESC_DSCR 64 +#define SCRATCH_REG_OFFSET 0x1250000 +#define ACP_SRAM 0x03800000 +typedef struct acp_atu_grp_pte { + uint32_t low_part; + uint32_t high_part; +} __attribute__((packed, aligned(4))) acp_atu_grp_pte_t; + +typedef union acp_cfg_dma_trns_cnt { + struct{ + uint32_t trns_cnt : 19; + uint32_t reserved : 12; + uint32_t ioc : 1; + } bits; + unsigned int u32all; +} __attribute__((packed, aligned(4))) acp_cfg_dma_trns_cnt_t; + +typedef struct acp_config_dma_descriptor { + uint32_t src_addr; + uint32_t dest_addr; + acp_cfg_dma_trns_cnt_t trns_cnt; + uint32_t reserved; +} __attribute__((packed, aligned(4))) acp_cfg_dma_descriptor_t; + +typedef struct acp_config_dma_misc { + uint32_t channelstatus; + uint32_t channel; + uint32_t flag; +} __attribute__((packed, aligned(4))) acp_cfg_dma_misc_t; + +typedef struct acp_scratch_memory_config { + /* ACP out box buffer */ + uint8_t acp_outbox_buffer[MAILBOX_DSPBOX_SIZE]; + + /* ACP in box buffer */ + uint8_t acp_inbox_buffer[MAILBOX_HOSTBOX_SIZE]; + + /* ACP debug box buffer */ + uint8_t acp_debug_buffer[MAILBOX_DEBUG_SIZE]; + + /* ACP exception box buffer */ + uint8_t acp_except_buffer[MAILBOX_EXCEPTION_SIZE]; + + /* ACP stream buffer */ + uint8_t acp_stream_buffer[MAILBOX_STREAM_SIZE]; + + /* ACP trace buffer */ + uint8_t acp_trace_buffer[MAILBOX_TRACE_SIZE]; + + /* Host msg write flag */ + uint32_t acp_host_msg_write; + + /* Host ack flag */ + uint32_t acp_host_ack_write; + + /* Dsp msg write flag */ + uint32_t acp_dsp_msg_write; + + /* Dsp ack flag */ + uint32_t acp_dsp_ack_write; + + /* ACP pte1 table */ + acp_atu_grp_pte_t acp_atugrp1_pte[16]; + + /* ACP pte2 table */ + acp_atu_grp_pte_t acp_atugrp2_pte[16]; + + /* ACP pte3 table */ + acp_atu_grp_pte_t acp_atugrp3_pte[16]; + + /* ACP pte4 table */ + acp_atu_grp_pte_t acp_atugrp4_pte[16]; + + /* ACP pte5 table */ + acp_atu_grp_pte_t acp_atugrp5_pte[16]; + + /* ACP pte6 table */ + acp_atu_grp_pte_t acp_atugrp6_pte[16]; + + /* ACP pte7 table */ + acp_atu_grp_pte_t acp_atugrp7_pte[16]; + + /* ACP pte8 table */ + acp_atu_grp_pte_t acp_atugrp8_pte[16]; + + /* ACP DMA Descriptor */ + acp_cfg_dma_descriptor_t acp_cfg_dma_descriptor[MAX_NUM_DMA_DESC_DSCR]; + + /* Stream physical offset */ + uint32_t phy_offset[8]; + + /* Stream system memory size */ + uint32_t syst_buff_size[8]; + + /* Fifo buffers are not part of scratch memory on ACP_6_3 */ + /* Added fifo members to align with Driver structure */ + /* ACP transmit fifo buffer */ + uint8_t acp_transmit_fifo_buffer[256] __attribute__((aligned(128))); + + /* ACP receive fifo buffer */ + uint8_t acp_receive_fifo_buffer[256] __attribute__((aligned(128))); + + uint32_t reserve[]; +} __attribute__((packed, aligned(4))) acp_scratch_mem_config_t; + +#endif /* __EXT_SCRATCH_MEM_H__ */ + diff --git a/src/platform/amd/acp_6_3/include/platform/lib/memory.h b/src/platform/amd/acp_6_3/include/platform/lib/memory.h new file mode 100644 index 000000000000..2597b0858715 --- /dev/null +++ b/src/platform/amd/acp_6_3/include/platform/lib/memory.h @@ -0,0 +1,185 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ +#ifdef __SOF_LIB_MEMORY_H__ + +#ifndef __PLATFORM_LIB_MEMORY_H__ +#define __PLATFORM_LIB_MEMORY_H__ + +#include +#include + +/* data cache line alignment */ +#define PLATFORM_DCACHE_ALIGN 128 + +/* physical DSP addresses */ +#define IRAM_BASE 0x7F000000 +#define IRAM_SIZE 0x60000 + +#define DRAM0_BASE 0xE0000000 +#define DRAM0_SIZE 0x10000 +#define SRAM0_BASE 0x9FF00000 + +#define DRAM1_BASE 0xE0010000 +#define DRAM1_SIZE 0x10000 +#define SRAM1_BASE 0x60006000 +#define SRAM1_SIZE 0x27A000 + +#define DMA0_BASE PU_REGISTER_BASE +#define DMA0_SIZE 0x4 + +/* DAI DMA register base address */ +#define DAI_BASE (PU_REGISTER_BASE + ACP_I2S_RX_RINGBUFADDR) +#define DAI_BASE_REM (PU_REGISTER_BASE + ACP_P1_I2S_RX_RINGBUFADDR) +#define DAI_SIZE 0x4 +#define BT_TX_FIFO_OFFST (ACP_P1_BT_TX_FIFOADDR - ACP_P1_I2S_RX_RINGBUFADDR) +#define BT_RX_FIFO_OFFST (ACP_P1_BT_RX_FIFOADDR - ACP_P1_I2S_RX_RINGBUFADDR) + +#define HS_TX_FIFO_OFFST (ACP_P1_HS_TX_FIFOADDR - ACP_P1_I2S_RX_RINGBUFADDR) +#define HS_RX_FIFO_OFFST (ACP_P1_HS_TX_FIFOADDR - ACP_P1_I2S_RX_RINGBUFADDR) +#define SW0_AUDIO_TX_FIFO_OFFST (ACP_AUDIO_TX_FIFOADDR - ACP_AUDIO_RX_RINGBUFADDR) +#define SW0_AUDIO_RX_FIFO_OFFST (ACP_AUDIO_RX_FIFOADDR - ACP_AUDIO_RX_RINGBUFADDR) + +#define BT0_TX_FIFO_OFFST (ACP_BT_TX_FIFOADDR - ACP_AUDIO_RX_RINGBUFADDR) +#define BT0_RX_FIFO_OFFST (ACP_BT_RX_FIFOADDR - ACP_AUDIO_RX_RINGBUFADDR) + +#define HS0_TX_FIFO_OFFST (ACP_HS_TX_FIFOADDR - ACP_AUDIO_RX_RINGBUFADDR) +#define HS0_RX_FIFO_OFFST (ACP_HS_TX_FIFOADDR - ACP_AUDIO_RX_RINGBUFADDR) + +#define UUID_ENTRY_ELF_BASE 0x1FFFA000 +#define UUID_ENTRY_ELF_SIZE 0x6000 + +/* Log buffer base need to be updated properly, these are used in linker scripts */ +#define LOG_ENTRY_ELF_BASE 0x20000000 +#define LOG_ENTRY_ELF_SIZE 0x2000000 + +#define EXT_MANIFEST_ELF_BASE (LOG_ENTRY_ELF_BASE + LOG_ENTRY_ELF_SIZE) +#define EXT_MANIFEST_ELF_SIZE 0x2000000 + +/* Stack configuration */ +#define SOF_STACK_SIZE 0x1000 +#define SOF_STACK_TOTAL_SIZE SOF_STACK_SIZE +#define SOF_STACK_END (DRAM1_BASE + DRAM1_SIZE - SOF_STACK_SIZE) +#define SOF_STACK_BASE (SOF_STACK_END + SOF_STACK_SIZE) + +/* Mailbox configuration */ +#define SRAM_OUTBOX_BASE SRAM0_BASE +#define SRAM_OUTBOX_SIZE 0x400 +#define SRAM_OUTBOX_OFFSET 0 + +#define SRAM_INBOX_BASE (SRAM_OUTBOX_BASE + SRAM_OUTBOX_SIZE) +#define SRAM_INBOX_SIZE 0x400 +#define SRAM_INBOX_OFFSET SRAM_OUTBOX_SIZE + +#define SRAM_DEBUG_BASE (SRAM_INBOX_BASE + SRAM_INBOX_SIZE) +#define SRAM_DEBUG_SIZE 0x400 +#define SRAM_DEBUG_OFFSET (SRAM_INBOX_OFFSET + SRAM_INBOX_SIZE) + +#define SRAM_EXCEPT_BASE (SRAM_DEBUG_BASE + SRAM_DEBUG_SIZE) +#define SRAM_EXCEPT_SIZE 0x400 +#define SRAM_EXCEPT_OFFSET (SRAM_DEBUG_OFFSET + SRAM_DEBUG_SIZE) + +#define SRAM_STREAM_BASE (SRAM_EXCEPT_BASE + SRAM_EXCEPT_SIZE) +#define SRAM_STREAM_SIZE 0x400 +#define SRAM_STREAM_OFFSET (SRAM_EXCEPT_OFFSET + SRAM_EXCEPT_SIZE) + +#define SRAM_TRACE_BASE (SRAM_STREAM_BASE + SRAM_STREAM_SIZE) +#define SRAM_TRACE_SIZE 0x400 +#define SRAM_TRACE_OFFSET (SRAM_STREAM_OFFSET + SRAM_STREAM_SIZE) +#define SOF_MAILBOX_SIZE (SRAM_INBOX_SIZE + SRAM_OUTBOX_SIZE \ + + SRAM_DEBUG_SIZE + SRAM_EXCEPT_SIZE \ + + SRAM_STREAM_SIZE + SRAM_TRACE_SIZE) + +/* Heap section sizes for module pool */ +#define HEAP_RT_COUNT8 0 +#define HEAP_RT_COUNT16 192 +#define HEAP_RT_COUNT32 192 +#define HEAP_RT_COUNT64 128 +#define HEAP_RT_COUNT128 240 +#define HEAP_RT_COUNT256 128 +#define HEAP_RT_COUNT512 16 +#define HEAP_RT_COUNT1024 73 +#define HEAP_RT_COUNT2048 48 + +/* Heap section sizes for system runtime heap */ +#define HEAP_SYS_RT_COUNT64 720 +#define HEAP_SYS_RT_COUNT512 240 +#define HEAP_SYS_RT_COUNT1024 91 + +#define SIZE_OF_MEMORY_FOR_DATA_SECTION 0x60000 + +/* Heap configuration */ +#define HEAP_SYSTEM_BASE (SRAM1_BASE + SIZE_OF_MEMORY_FOR_DATA_SECTION) +#define HEAP_SYSTEM_SIZE 0x40000 +#define HEAP_SYSTEM_0_BASE HEAP_SYSTEM_BASE +#define HEAP_SYS_RUNTIME_BASE (HEAP_SYSTEM_BASE + HEAP_SYSTEM_SIZE) +#define HEAP_SYS_RUNTIME_SIZE (HEAP_SYS_RT_COUNT64 * 64 + HEAP_SYS_RT_COUNT512 * 512 + \ + HEAP_SYS_RT_COUNT1024 * 1024) + +#define HEAP_RUNTIME_BASE (HEAP_SYS_RUNTIME_BASE + HEAP_SYS_RUNTIME_SIZE) +#define HEAP_RUNTIME_SIZE \ + (HEAP_RT_COUNT8 * 8 + HEAP_RT_COUNT16 * 16 + \ + HEAP_RT_COUNT32 * 32 + HEAP_RT_COUNT64 * 64 + \ + HEAP_RT_COUNT128 * 128 + HEAP_RT_COUNT256 * 256 + \ + HEAP_RT_COUNT512 * 512 + HEAP_RT_COUNT1024 * 1024 + \ + HEAP_RT_COUNT2048 * 2048) + +#define HEAP_BUFFER_BASE (HEAP_RUNTIME_BASE + HEAP_RUNTIME_SIZE) +#define HEAP_BUFFER_SIZE (0x60000) +#define HEAP_BUFFER_BLOCK_SIZE 0x180 +#define HEAP_BUFFER_COUNT (HEAP_BUFFER_SIZE / HEAP_BUFFER_BLOCK_SIZE) + +#define PLATFORM_HEAP_SYSTEM 1 +#define PLATFORM_HEAP_SYSTEM_RUNTIME 1 +#define PLATFORM_HEAP_RUNTIME 1 +#define PLATFORM_HEAP_BUFFER 1 + +/* Vector and literal sizes - not in core-isa.h */ +#define SOF_MEM_VECT_LIT_SIZE 0x7 +#define SOF_MEM_VECT_TEXT_SIZE 0x37 +#define SOF_MEM_VECT_SIZE (SOF_MEM_VECT_TEXT_SIZE + SOF_MEM_VECT_LIT_SIZE) + +#define SOF_MEM_RESET_TEXT_SIZE 0x400 +#define SOF_MEM_RESET_LIT_SIZE 0x8 +#define SOF_MEM_VECBASE_LIT_SIZE 0x178 +#define SOF_MEM_WIN_TEXT_SIZE 0x178 + +#define SOF_MEM_RO_SIZE 0x8 + +#define uncache_to_cache(address) address +#define cache_to_uncache(address) address +#define is_uncached(address) 0 + +#define HEAP_BUF_ALIGNMENT PLATFORM_DCACHE_ALIGN + +/* brief EDF task's default stack size in bytes */ +#define PLATFORM_TASK_DEFAULT_STACK_SIZE 3072 + +#if !defined(__ASSEMBLER__) && !defined(LINKER) +struct sof; + +#define SHARED_DATA +void platform_init_memmap(struct sof *sof); + +static inline void *platform_shared_get(void *ptr, int bytes) +{ + return ptr; +} + +static inline void *platform_rfree_prepare(void *ptr) +{ + return ptr; +} +#endif + +#endif /* __PLATFORM_LIB_MEMORY_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/lib/memory.h" + +#endif /* __SOF_LIB_MEMORY_H__ */ diff --git a/src/platform/amd/acp_6_3/include/platform/platform.h b/src/platform/amd/acp_6_3/include/platform/platform.h new file mode 100644 index 000000000000..21d77802fda7 --- /dev/null +++ b/src/platform/amd/acp_6_3/include/platform/platform.h @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 AMD.All rights reserved. + * + * Author: Basavaraj Hiregoudar + * SaiSurya, Ch + */ +#ifdef __SOF_PLATFORM_H__ + +#ifndef __PLATFORM_PLATFORM_H__ +#define __PLATFORM_PLATFORM_H__ + +#if !defined(__ASSEMBLER__) && !defined(LINKER) + +#include +#include +#include +#include +#include +#include +#include + +struct ll_schedule_domain; +struct timer; + +#define PLATFORM_DEFAULT_CLOCK CLK_CPU(0) + +/* IPC Interrupt */ +#define PLATFORM_IPC_INTERRUPT IRQ_EXT_IPC_LEVEL_3 +#define PLATFORM_IPC_INTERRUPT_NAME NULL + +/* Host page size */ +#define HOST_PAGE_SIZE 65536 + +/* pipeline IRQ */ +#define PLATFORM_SCHEDULE_IRQ IRQ_NUM_SOFTWARE0 +#define PLATFORM_SCHEDULE_IRQ_NAME NULL + +/* Platform stream capabilities */ +#define PLATFORM_MAX_CHANNELS 8 +#define PLATFORM_MAX_STREAMS 5 + +/* local buffer size of DMA tracing */ +#define DMA_TRACE_LOCAL_SIZE (16384 + 8192) //8192 + +/* trace bytes flushed during panic */ +#define DMA_FLUSH_TRACE_SIZE (MAILBOX_TRACE_SIZE >> 2) + +/* the interval of DMA trace copying */ +#define DMA_TRACE_PERIOD 500 //1000 //50000 + +/* + * the interval of reschedule DMA trace copying in special case like half + * fullness of local DMA trace buffer + */ +#define DMA_TRACE_RESCHEDULE_TIME 100 + +/* DSP default delay in cycles */ +#define PLATFORM_DEFAULT_DELAY 12 + +/* default dma trace channel */ +#define DMA_TRACE_CHANNEL 7 + +/* debug offset */ +#define ACP_SOF_FW_STATUS 0 + +/* Platform defined panic code */ +static inline void platform_panic(uint32_t p) +{ + acp_sw_intr_trig_t sw_intr_trig; + volatile acp_scratch_mem_config_t *pscratch_mem_cfg = + (volatile acp_scratch_mem_config_t *)(PU_SCRATCH_REG_BASE + SCRATCH_REG_OFFSET); + + pscratch_mem_cfg->acp_dsp_msg_write = p; + mailbox_sw_reg_write(ACP_SOF_FW_STATUS, p); + /* Read the Software Interrupt controller register and update */ + sw_intr_trig = (acp_sw_intr_trig_t)io_reg_read(PU_REGISTER_BASE + ACP_SW_INTR_TRIG); + /* Configures the trigger bit in ACP_DSP_SW_INTR_TRIG register */ + sw_intr_trig.bits.trig_dsp0_to_host_intr = INTERRUPT_ENABLE; + /* Write the Software Interrupt trigger register */ + io_reg_write((PU_REGISTER_BASE + ACP_SW_INTR_TRIG), sw_intr_trig.u32all); +} + +/* + * brief Platform specific CPU entering idle. + * May be power-optimized using platform specific capabilities. + * @param level Interrupt level. + */ +void platform_wait_for_interrupt(int level); + +extern intptr_t _module_init_start; +extern intptr_t _module_init_end; +#endif + +#endif /* __PLATFORM_PLATFORM_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/platform.h" + +#endif /* __SOF_PLATFORM_H__ */ diff --git a/src/platform/amd/acp_6_3/lib/CMakeLists.txt b/src/platform/amd/acp_6_3/lib/CMakeLists.txt new file mode 100644 index 000000000000..271a099cc6a9 --- /dev/null +++ b/src/platform/amd/acp_6_3/lib/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: BSD-3-Clause + +add_local_sources(sof + clk.c + dai.c + dma.c + memory.c +) diff --git a/src/platform/amd/acp_6_3/lib/clk.c b/src/platform/amd/acp_6_3/lib/clk.c new file mode 100644 index 000000000000..566a988df3ef --- /dev/null +++ b/src/platform/amd/acp_6_3/lib/clk.c @@ -0,0 +1,494 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2023 AMD.All rights reserved. +// +// Author: Basavaraj Hiregoudar +// Maruthi Machani +// SaiSurya, Ch +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*b414df09-9e31-4c59-8657-7afc8deba70c*/ +DECLARE_SOF_UUID("acp-clk", acp_clk_uuid, 0xb414df09, 0x9e31, 0x4c59, + 0x86, 0x57, 0x7a, 0xfc, 0x8d, 0xeb, 0xa7, 0x0c); +DECLARE_TR_CTX(acp_clk_tr, SOF_UUID(acp_clk_uuid), LOG_LEVEL_INFO); + +const struct freq_table platform_cpu_freq[] = { + {600000000, 600000 }, +}; + +STATIC_ASSERT(ARRAY_SIZE(platform_cpu_freq) == NUM_CPU_FREQ, + invalid_number_of_cpu_frequencies); + +static SHARED_DATA struct clock_info platform_clocks_info[NUM_CLOCKS]; + +void audio_pll_power_off(void); +void audio_pll_power_on(void); +void clk_dfs_bypassexit(void); +void audio_pll_mode_switch(uint32_t mode, uint32_t fcw_int, uint32_t fcw_frac, uint32_t fcw_denom, + uint32_t pllspinediv); +void clk5_init_vco(void); +void acp_6_3_reg_wait(void); +void acp_6_3_get_boot_ref_clock(float *boot_ref_clk); + +typedef enum { + PLL_MODE_100MHZ_NORMAL, + PLL_MODE_48MHZ_NORMAL, + PLL_MODE_32KHZ_LPPM, + PLL_MODE_48MHZ_LPPM, + PLL_MODE_100MHZ_LPPM +} PLL_MODE; + +/* Enumeration for the Clock Types */ +typedef enum _acp_clock_type_ { + acp_aclk_clock, + acp_sclk_clock, + acp_clock_type_max, + acp_clock_type_force = 0xFF +} acp_clock_type_t; + +static int acp_reg_read_via_smn(uint32_t reg_offset, + uint32_t size) +{ + uint32_t reg_value; + uint32_t delay_cnt = 10000; + uint32_t smn_client_base_addr = (reg_offset >> 10); + uint32_t region_start_addr = (smn_client_base_addr << 10); + uint32_t apertureid = ((reg_offset >> 20) & 0xFFF); + acp_srbm_cycle_sts_t acp_srbm_cycle_sts; + + io_reg_write((PU_REGISTER_BASE + ACP_SRBM_CLIENT_CONFIG), apertureid); + io_reg_write((PU_REGISTER_BASE + ACP_SRBM_CLIENT_BASE_ADDR), smn_client_base_addr); + reg_value = (uint32_t)io_reg_read(PU_REGISTER_BASE + + (ACP_MASTER_REG_ACCESS_ADDRESS + reg_offset - region_start_addr + ACP_FIRST_REG_OFFSET)); + if (reg_value) + reg_value = 0; + acp_srbm_cycle_sts = (acp_srbm_cycle_sts_t)io_reg_read(PU_REGISTER_BASE + + ACP_SRBM_CYCLE_STS); + while (delay_cnt > 0) { + if (!acp_srbm_cycle_sts.bits.srbm_clients_sts) + return (uint32_t)io_reg_read(PU_REGISTER_BASE + ACP_SRBM_CLIENT_RDDATA); + acp_srbm_cycle_sts = (acp_srbm_cycle_sts_t)io_reg_read(PU_REGISTER_BASE + + ACP_SRBM_CYCLE_STS); + delay_cnt--; + } + return -1; +} + +static void acp_reg_write_via_smn(uint32_t reg_offset, + uint32_t value, uint32_t size) +{ + uint32_t delay_cnt = 10000; + uint32_t smn_client_base_addr = (reg_offset >> 10); + uint32_t region_start_addr = (smn_client_base_addr << 10); + uint32_t apertureid = ((reg_offset >> 20) & 0xFFF); + acp_srbm_cycle_sts_t acp_srbm_cycle_sts; + + io_reg_write((PU_REGISTER_BASE + ACP_SRBM_CLIENT_CONFIG), apertureid); + io_reg_write((PU_REGISTER_BASE + ACP_SRBM_CLIENT_BASE_ADDR), smn_client_base_addr); + io_reg_write((PU_REGISTER_BASE + + (ACP_MASTER_REG_ACCESS_ADDRESS + reg_offset - region_start_addr + + ACP_FIRST_REG_OFFSET)), + value); + acp_srbm_cycle_sts = + (acp_srbm_cycle_sts_t)io_reg_read(PU_REGISTER_BASE + ACP_SRBM_CYCLE_STS); + while (delay_cnt > 0) { + acp_srbm_cycle_sts = (acp_srbm_cycle_sts_t)io_reg_read(PU_REGISTER_BASE + + ACP_SRBM_CYCLE_STS); + if (!acp_srbm_cycle_sts.bits.srbm_clients_sts) + return; + delay_cnt--; + } +} + +void acp_6_3_reg_wait(void) +{ + int test_count = 0; + int val = 0; + + for (test_count = 0; test_count < 255; test_count++) { + val = acp_reg_read_via_smn(CLK5_CLK_FSM_STATUS, sizeof(int)); + val = val * 0; + } +} + +void acp_6_3_get_boot_ref_clock(float *boot_ref_clk) +{ + clk5_clk_pll_refclk_startup_t boot_ref_clk_startup; + clk5_clk_pll_req_u_t clk5_clk_pll_req; + clk5_spll_field_2_t clk5_spll_field; + uint32_t spinediv = 1; + float fract_part = 0.0f; + float final_refclk = 0.0f; + + boot_ref_clk_startup.u32all = + acp_reg_read_via_smn(CLK5_CLK_PLL_REFCLK_RATE_STARTUP, sizeof(int)); + + clk5_spll_field_9_t clk_spll_field_9; + + clk_spll_field_9.u32all = 0x0; + clk_spll_field_9.u32all = acp_reg_read_via_smn(CLK5_SPLL_FIELD_9, sizeof(int)); + + if (clk_spll_field_9.bitfields.spll_dpll_cfg_3 == 0x2) + final_refclk = ((32768.0f * 128.0f) / 1000000.0f); + else + final_refclk = (float)boot_ref_clk_startup.bitfields.main_pll_ref_clk_rate_startup; + + clk5_clk_pll_req.u32all = acp_reg_read_via_smn(CLK5_CLK_PLL_REQ, sizeof(int)); + clk5_spll_field.u32all = acp_reg_read_via_smn(CLK5_SPLL_FIELD_2, sizeof(int)); + + spinediv = (1 << clk5_clk_pll_req.bitfields.pllspinediv); + + if (clk5_spll_field.bitfields.spll_fracn_en == 1) + fract_part = (float)(clk5_clk_pll_req.bitfields.fbmult_frac / (float)65536.0f); + + *boot_ref_clk = (float)(((final_refclk) * (clk5_clk_pll_req.bitfields.fbmult_int + + fract_part)) / (float)spinediv); +} + +void acp_change_clock_notify(uint32_t clock_freq) +{ + volatile clk5_clk1_dfs_cntl_u_t dfs_cntl; + volatile clk5_clk1_bypass_cntl_u_t bypass_cntl; + volatile clk5_clk1_dfs_status_u_t dfs_status; + volatile uint32_t updated_clk; + float did = 0.0f; + float fraction_val = 0.0f; + uint32_t int_did_val = 0; + float boot_ref_clk; + acp_clock_type_t clock_type = acp_aclk_clock; + + acp_6_3_get_boot_ref_clock(&boot_ref_clk); + + tr_info(&acp_clk_tr, "acp_change_clock_notify clock_freq : %d clock_type : %d", + clock_freq, clock_type); + + fraction_val = (float)(clock_freq / (float)1000000.0f); + clock_freq = (clock_freq / 1000000); + if (acp_aclk_clock == clock_type) { + bypass_cntl.u32all = acp_reg_read_via_smn(CLK5_CLK1_BYPASS_CNTL, sizeof(int)); + dfs_cntl.u32all = acp_reg_read_via_smn(CLK5_CLK1_DFS_CNTL, sizeof(int)); + } else if (acp_sclk_clock == clock_type) { + bypass_cntl.u32all = acp_reg_read_via_smn(CLK5_CLK0_BYPASS_CNTL, sizeof(int)); + dfs_cntl.u32all = acp_reg_read_via_smn(CLK5_CLK0_DFS_CNTL, sizeof(int)); + } + + bypass_cntl.bitfields.CLK1_BYPASS_DIV = 0; + + if (clock_freq == 6 || clock_freq == 0) { + did = 128; + dfs_cntl.bitfields.CLK1_DIVIDER = 0x7F; + bypass_cntl.bitfields.CLK1_BYPASS_DIV = 0xF; + } else { + did = (float)(boot_ref_clk / (float)fraction_val); + tr_info(&acp_clk_tr, "acp_change_clock_notify CLK Divider : %d boot_ref_clk : %d\n", + (uint32_t)(did * 100), (uint32_t)boot_ref_clk); + + if (did > 62.0f) { + dfs_cntl.bitfields.CLK1_DIVIDER = 0x7F; + } else { + fraction_val = did - (uint8_t)(did); + did = did - fraction_val; + if (did <= 16.00f) + did = (did * 4.0f); + else if ((did > 16.0f) && (did <= 32.0f)) + did = ((did - 16.0f) * 2.0f + 64.0f); + else if ((did > 32.0f) && (did <= 62.0f)) + did = ((did - 32.0f) + 96.0f); + + int_did_val = (uint32_t)(fraction_val * 100.0f); + fraction_val = (float)(int_did_val / 100.0f); + + if (fraction_val == 0.0f) + dfs_cntl.bitfields.CLK1_DIVIDER = (uint8_t)(did); + else if (fraction_val <= 0.25f) + dfs_cntl.bitfields.CLK1_DIVIDER = (uint8_t)(did) + 1; + else if ((fraction_val > 0.25f) && (fraction_val <= 0.5f)) + dfs_cntl.bitfields.CLK1_DIVIDER = (uint8_t)(did) + 2; + else if ((fraction_val > 0.5f) && (fraction_val <= 0.75f)) + dfs_cntl.bitfields.CLK1_DIVIDER = (uint8_t)(did) + 3; + else if ((fraction_val > 0.75f)) + dfs_cntl.bitfields.CLK1_DIVIDER = (uint8_t)(did) + 4; + } + } + + if (acp_aclk_clock == clock_type) { + acp_reg_write_via_smn(CLK5_CLK1_BYPASS_CNTL, bypass_cntl.u32all, sizeof(int)); + acp_reg_write_via_smn(CLK5_CLK1_DFS_CNTL, dfs_cntl.u32all, sizeof(int)); + dfs_status.u32all = acp_reg_read_via_smn(CLK5_CLK1_DFS_STATUS, sizeof(int)); + acp_6_3_reg_wait(); + + do { + dfs_status.u32all = acp_reg_read_via_smn(CLK5_CLK1_DFS_STATUS, sizeof(int)); + tr_info(&acp_clk_tr, "acp_change_clock_notify ACLK1 CLK1_DIVIDER : %d dfsstatus %d ", + dfs_cntl.u32all, dfs_status.u32all); + } while (dfs_status.bitfields.CLK1_DFS_DIV_REQ_IDLE == 0); + updated_clk = acp_reg_read_via_smn(CLK5_CLK1_CURRENT_CNT, sizeof(int)); + acp_6_3_reg_wait(); + + if (updated_clk < (clock_freq * 10)) { + dfs_cntl.bitfields.CLK1_DIVIDER -= 1; + dfs_status.u32all = 0; + acp_reg_write_via_smn(CLK5_CLK1_DFS_CNTL, dfs_cntl.u32all, sizeof(int)); + do { + dfs_status.u32all = + acp_reg_read_via_smn(CLK5_CLK1_DFS_STATUS, + sizeof(int)); + dfs_cntl.u32all = + acp_reg_read_via_smn(CLK5_CLK1_DFS_CNTL, + sizeof(int)); + tr_info(&acp_clk_tr, "acp_change_clock_notify ACLK2 CLK1_DIVIDER:%d dfsstatus %d ", + dfs_cntl.u32all, dfs_status.u32all); + } while (dfs_status.bitfields.CLK1_DFS_DIV_REQ_IDLE == 0); + } + updated_clk = acp_reg_read_via_smn(CLK5_CLK1_CURRENT_CNT, sizeof(int)); + } else if (acp_sclk_clock == clock_type) { + acp_reg_write_via_smn(CLK5_CLK0_BYPASS_CNTL, bypass_cntl.u32all, sizeof(int)); + acp_reg_write_via_smn(CLK5_CLK0_DFS_CNTL, dfs_cntl.u32all, sizeof(int)); + dfs_status.u32all = acp_reg_read_via_smn(CLK5_CLK0_DFS_STATUS, sizeof(int)); + acp_6_3_reg_wait(); + + do { + dfs_status.u32all = acp_reg_read_via_smn(CLK5_CLK0_DFS_STATUS, sizeof(int)); + tr_info(&acp_clk_tr, "acp_change_clock_notify SCLK CLK1_DIVIDER: %d", + dfs_cntl.u32all); + } while (dfs_status.bitfields.CLK1_DFS_DIV_REQ_IDLE == 0); + + updated_clk = acp_reg_read_via_smn(CLK5_CLK0_CURRENT_CNT, sizeof(int)); + } + tr_info(&acp_clk_tr, + "clock_notify:CLK1_DIVIDER :%x boot_ref_clk : %d ClkReq : %d FinalClockValue: %d", + dfs_cntl.u32all, (uint32_t)boot_ref_clk, + clock_freq, updated_clk); +} + +void audio_pll_power_off(void) +{ + volatile clk5_clk_pll_pwr_req_t clk5_clk_pll_pwr_req; + volatile clk5_clk_fsm_status_t clk5_clk_fsm_status; + int count = 0; + + for (count = 0; count < 10; count++) { + clk5_clk_pll_pwr_req.u32all = + acp_reg_read_via_smn(CLK5_CLK_PLL_PWR_REQ, sizeof(int)); + clk5_clk_pll_pwr_req.bitfields.PLL_AUTO_STOP_REQ = 1; + + acp_reg_write_via_smn(CLK5_CLK_PLL_PWR_REQ, + clk5_clk_pll_pwr_req.u32all, sizeof(int)); + acp_6_3_reg_wait(); + + clk5_clk_fsm_status.u32all = acp_reg_read_via_smn(CLK5_CLK_FSM_STATUS, sizeof(int)); + + if (clk5_clk_fsm_status.bitfields.RO_FSM_PLL_STATUS_STOPPED == 1) + break; + } +} + +void audio_pll_power_on(void) +{ + volatile clk5_clk_pll_pwr_req_t clk5_clk_pll_pwr_req; + volatile clk5_clk_fsm_status_t clk5_clk_fsm_status; + int count = 0; + + for (count = 0; count < 10; count++) { + clk5_clk_pll_pwr_req.u32all = + acp_reg_read_via_smn(CLK5_CLK_PLL_PWR_REQ, sizeof(int)); + clk5_clk_pll_pwr_req.bitfields.PLL_AUTO_START_REQ = 1; + + acp_reg_write_via_smn(CLK5_CLK_PLL_PWR_REQ, + clk5_clk_pll_pwr_req.u32all, + sizeof(int)); + acp_6_3_reg_wait(); + + clk5_clk_fsm_status.u32all = acp_reg_read_via_smn(CLK5_CLK_FSM_STATUS, sizeof(int)); + if (clk5_clk_fsm_status.bitfields.RO_FSM_PLL_STATUS_STARTED == 1) + break; + acp_6_3_reg_wait(); + } +} + +void clk_dfs_bypassexit(void) +{ + volatile clk5_clk_dfsbypass_cntl_t clk5_clk_dfsbypass_cntl; + + clk5_clk_dfsbypass_cntl = (clk5_clk_dfsbypass_cntl_t)acp_reg_read_via_smn + (CLK5_CLK_DFSBYPASS_CONTROL, sizeof(int)); + + clk5_clk_dfsbypass_cntl.bitfields.exit_dfs_bypass_0 = 1; + clk5_clk_dfsbypass_cntl.bitfields.exit_dfs_bypass_1 = 1; + + acp_reg_write_via_smn(CLK5_CLK_DFSBYPASS_CONTROL, + clk5_clk_dfsbypass_cntl.u32all, + sizeof(int)); +} + +void audio_pll_mode_switch(uint32_t mode, uint32_t fcw_int, uint32_t fcw_frac, uint32_t fcw_denom, + uint32_t pllspinediv) +{ + volatile clk5_spll_fuse_1_t clk_spll_fuse1; + volatile clk5_spll_fuse_2_t clk_spll_fuse2; + volatile clk5_spll_field_9_t clk_spll_field_9; + volatile clk5_spll_field_6nm_t clk_spll_field_6nm; + volatile clk5_spll_field_7_t clk_spll_field_7; + volatile clk5_spll_field_4_t clk_spll_field_4; + volatile clk5_spll_field_5nm_bus_ctrl_t clk_spll_field_5nm_bus_ctrl; + volatile clk5_spll_field_5nm_bus_wdata_t clk_spll_field_5nm_bus_wdata; + volatile clk5_spll_field_5nm_bus_status_t clk_spll_field_5nm_bus_status; + volatile clk5_rootrefclk_mux_1_t clk_rootrefclkmux; + volatile clk5_spll_field_2_t clk5_spll_field_2; + + clk_spll_fuse1.u32all = 0x0; + clk_spll_fuse2.u32all = 0x0; + clk_spll_field_9.u32all = 0x0; + clk_spll_field_6nm.u32all = 0x0; + clk_spll_field_7.u32all = 0x0; + clk_spll_field_4.u32all = 0x0; + clk_spll_field_5nm_bus_ctrl.u32all = 0x0; + clk_spll_field_5nm_bus_wdata.u32all = 0x0; + clk_spll_field_5nm_bus_status.u32all = 0x0; + clk5_spll_field_2 = + (clk5_spll_field_2_t)acp_reg_read_via_smn(CLK5_SPLL_FIELD_2, sizeof(int)); + + if (clk5_spll_field_2.bitfields.spll_fracn_en == 0) + clk5_spll_field_2.bitfields.spll_fracn_en = 1; + acp_reg_write_via_smn(CLK5_SPLL_FIELD_2, clk5_spll_field_2.u32all, sizeof(int)); + + switch (mode) { + case PLL_MODE_32KHZ_LPPM: + clk_rootrefclkmux.bitfields.ROOTREFCLK_MUX_1 = 0x0; + clk_rootrefclkmux.u32all = acp_reg_read_via_smn(CLK5_ROOTREFCLKMUX_1, sizeof(int)); + + clk_rootrefclkmux.bitfields.ROOTREFCLK_MUX_1 = 1; + acp_reg_write_via_smn(CLK5_ROOTREFCLKMUX_1, clk_rootrefclkmux.u32all, sizeof(int)); + + clk_spll_fuse1.bitfields.spll_gp_coarse_exp = 0x5; + clk_spll_fuse1.bitfields.spll_gp_coarse_mant = 0x0; + clk_spll_fuse1.bitfields.spll_gi_coarse_exp = 0x7; + clk_spll_fuse1.bitfields.spll_gi_coarse_mant = 0x0; + + clk_spll_fuse2.bitfields.spll_tdc_resolution = 0xe8; + clk_spll_fuse2.bitfields.spll_freq_offset_exp = 0xa; + clk_spll_fuse2.bitfields.spll_freq_offset_mant = 0xe; + + clk_spll_field_9.bitfields.spll_dpll_cfg_3 = 2; + clk_spll_field_6nm.bitfields.spll_dpll_cfg_4 = 0x60; + clk_spll_field_6nm.bitfields.spll_vco_pre_div = 3; + clk_spll_field_7.bitfields.spll_refclk_rate = 4; + clk_spll_field_7.bitfields.spll_pwr_state = 1; + clk_spll_field_4.bitfields.spll_refclk_div = 0; + + acp_reg_write_via_smn(CLK5_SPLL_FUSE_1, clk_spll_fuse1.u32all, sizeof(int)); + acp_reg_write_via_smn(CLK5_SPLL_FUSE_2, clk_spll_fuse2.u32all, sizeof(int)); + acp_reg_write_via_smn(CLK5_SPLL_FIELD_9, clk_spll_field_9.u32all, sizeof(int)); + acp_reg_write_via_smn(CLK5_SPLL_FIELD_6nm, clk_spll_field_6nm.u32all, sizeof(int)); + acp_reg_write_via_smn(CLK5_SPLL_FIELD_7, clk_spll_field_7.u32all, sizeof(int)); + acp_reg_write_via_smn(CLK5_SPLL_FIELD_4, clk_spll_field_4.u32all, sizeof(int)); + + clk_spll_field_5nm_bus_wdata.bitfields.bus_spll_wr_data = 0x00400000; + acp_reg_write_via_smn(CLK5_SPLL_FIELD_5nm_BUS_WDATA, + clk_spll_field_5nm_bus_wdata.u32all, + sizeof(int)); + + clk_spll_field_5nm_bus_ctrl.u32all = + acp_reg_read_via_smn(CLK5_SPLL_FIELD_5nm_BUS_CTRL, + sizeof(int)); + clk_spll_field_5nm_bus_ctrl.bitfields.bus_spll_async_mode = 1; + clk_spll_field_5nm_bus_ctrl.bitfields.bus_spll_apb_mode = 0; + clk_spll_field_5nm_bus_ctrl.bitfields.bus_spll_addr = 0xa; + clk_spll_field_5nm_bus_ctrl.bitfields.bus_spll_byte_en = 0xf; + clk_spll_field_5nm_bus_ctrl.bitfields.bus_spll_rdtr = + !clk_spll_field_5nm_bus_ctrl.bitfields.bus_spll_rdtr; + clk_spll_field_5nm_bus_ctrl.bitfields.bus_spll_resetb = 1; + clk_spll_field_5nm_bus_ctrl.bitfields.bus_spll_sel = 1; + clk_spll_field_5nm_bus_ctrl.bitfields.bus_spll_wrtr = 1; + acp_reg_write_via_smn(CLK5_SPLL_FIELD_5nm_BUS_CTRL, + clk_spll_field_5nm_bus_ctrl.u32all, + sizeof(int)); + do { + clk_spll_field_5nm_bus_status.u32all = + acp_reg_read_via_smn(CLK5_SPLL_FIELD_5nm_BUS_STATUS, + sizeof(int)); + } while (clk_spll_field_5nm_bus_status.bitfields.spll_bus_rd_valid != + clk_spll_field_5nm_bus_ctrl.bitfields.bus_spll_rdtr); + + acp_reg_write_via_smn(CLK5_CLK_PLL_RESET_STOP_TIMER, 0xbbb11aa, sizeof(int)); + break; + default: + tr_err(&acp_clk_tr, "ERROR: Invalid PLL Mode"); + return; + } + + clk5_clk_pll_req_u_t clk5_clk_pll_req; + + clk5_clk_pll_req.u32all = 0; + clk5_clk_pll_req = + (clk5_clk_pll_req_u_t)acp_reg_read_via_smn(CLK5_CLK_PLL_REQ, sizeof(int)); + clk5_clk_pll_req.bitfields.fbmult_int = fcw_int; + + if (clk5_spll_field_2.bitfields.spll_fracn_en) + clk5_clk_pll_req.bitfields.fbmult_frac = fcw_frac; + clk5_clk_pll_req.bitfields.pllspinediv = pllspinediv; + acp_reg_write_via_smn(CLK5_CLK_PLL_REQ, clk5_clk_pll_req.u32all, sizeof(int)); +} + +void clk5_init_vco(void) +{ + audio_pll_power_off(); + audio_pll_mode_switch(PLL_MODE_32KHZ_LPPM, 0x125, 0, 0, 0); + + audio_pll_power_on(); + + clk_dfs_bypassexit(); + acp_reg_write_via_smn(CLK5_CLK1_BYPASS_CNTL, 0, sizeof(int)); +} + +void platform_clock_init(struct sof *sof) +{ + int i = 0; + + sof->clocks = platform_clocks_info; + for (i = 0; i < CONFIG_CORE_COUNT; i++) { + sof->clocks[i] = (struct clock_info) { + .freqs_num = NUM_CPU_FREQ, + .freqs = platform_cpu_freq, + .default_freq_idx = CPU_DEFAULT_IDX, + .current_freq_idx = CPU_DEFAULT_IDX, + .notification_id = NOTIFIER_ID_CPU_FREQ, + .notification_mask = NOTIFIER_TARGET_CORE_MASK(i), + .set_freq = NULL, + }; + } + clk5_init_vco(); +} diff --git a/src/platform/amd/acp_6_3/lib/dai.c b/src/platform/amd/acp_6_3/lib/dai.c new file mode 100644 index 000000000000..02ee5c5d4dc3 --- /dev/null +++ b/src/platform/amd/acp_6_3/lib/dai.c @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct dai acp_dmic_dai[] = { + { + .index = 0, + .plat_data = { + .base = DMA0_BASE, + .fifo[SOF_IPC_STREAM_PLAYBACK] = { + .offset = DMA0_BASE, + .depth = 8, + .handshake = 0, + }, + .base = DMA0_BASE, + .fifo[SOF_IPC_STREAM_CAPTURE] = { + .offset = DMA0_BASE, + .depth = 8, + .handshake = 1, + }, + }, + .drv = &acp_dmic_dai_driver, + }, +}; + +static struct dai hsdai[] = { + { + .index = 0, + .plat_data = { + .base = DAI_BASE_REM, + .fifo[SOF_IPC_STREAM_PLAYBACK] = { + .offset = DAI_BASE_REM + HS_TX_FIFO_OFFST, + .depth = 8, + .handshake = 1, + }, + .fifo[SOF_IPC_STREAM_CAPTURE] = { + .offset = DAI_BASE_REM + HS_RX_FIFO_OFFST, + .depth = 8, + .handshake = 0, + }, + }, + .drv = &acp_hsdai_driver, + }, + { + .index = 1, + .plat_data = { + .base = DAI_BASE_REM, + .fifo[SOF_IPC_STREAM_PLAYBACK] = { + .offset = DAI_BASE_REM + HS_TX_FIFO_OFFST, + .depth = 8, + .handshake = 1, + }, + .fifo[SOF_IPC_STREAM_CAPTURE] = { + .offset = DAI_BASE_REM + HS_RX_FIFO_OFFST, + .depth = 8, + .handshake = 0, + }, + }, + .drv = &acp_hsdai_driver, + } +}; + +#ifdef ACP_SP_ENABLE +static struct dai spdai[] = { + { + .index = 0, + .plat_data = { + .base = DAI_BASE, + .fifo[SOF_IPC_STREAM_PLAYBACK] = { + .offset = DAI_BASE + BT_TX_FIFO_OFFST, + .depth = 8, + .handshake = 5, + }, + .fifo[SOF_IPC_STREAM_CAPTURE] = { + .offset = DAI_BASE + BT_RX_FIFO_OFFST, + .depth = 8, + .handshake = 4, + }, + }, + .drv = &acp_spdai_driver, + } +}; + +static struct dai sp_virtual_dai[] = { + { + .index = 1, + .plat_data = { + .base = DAI_BASE, + .fifo[SOF_IPC_STREAM_PLAYBACK] = { + .offset = DAI_BASE + BT_TX_FIFO_OFFST, + .depth = 8, + .handshake = 5, + }, + .fifo[SOF_IPC_STREAM_CAPTURE] = { + .offset = DAI_BASE + BT_RX_FIFO_OFFST, + .depth = 8, + .handshake = 4, + }, + }, + .drv = &acp_sp_virtual_dai_driver, + } +}; +#endif +#ifdef ACP_BT_ENABLE +static struct dai btdai[] = { + { + .index = 0, + .plat_data = { + .base = DAI_BASE, + .fifo[SOF_IPC_STREAM_PLAYBACK] = { + .offset = DAI_BASE + BT_TX_FIFO_OFFST, + .depth = 8, + .handshake = 3, + }, + .fifo[SOF_IPC_STREAM_CAPTURE] = { + .offset = DAI_BASE + BT_RX_FIFO_OFFST, + .depth = 8, + .handshake = 2, + }, + }, + .drv = &acp_btdai_driver, + }, +}; +#endif + +const struct dai_type_info dti[] = { + { + .type = SOF_DAI_AMD_DMIC, + .dai_array = acp_dmic_dai, + .num_dais = ARRAY_SIZE(acp_dmic_dai) + }, + { + .type = SOF_DAI_AMD_HS, + .dai_array = hsdai, + .num_dais = ARRAY_SIZE(hsdai) + }, +#ifdef ACP_SP_ENABLE + { + .type = SOF_DAI_AMD_SP, + .dai_array = spdai, + .num_dais = ARRAY_SIZE(spdai) + }, + { + .type = SOF_DAI_AMD_SP_VIRTUAL, + .dai_array = sp_virtual_dai, + .num_dais = ARRAY_SIZE(sp_virtual_dai) + }, +#endif +#ifdef ACP_BT_ENABLE + { + .type = SOF_DAI_AMD_BT, + .dai_array = btdai, + .num_dais = ARRAY_SIZE(btdai) + }, +#endif +}; + +const struct dai_info lib_dai = { + .dai_type_array = dti, + .num_dai_types = ARRAY_SIZE(dti) +}; + +int dai_init(struct sof *sof) +{ + int i; + + /* initialize spin locks early to enable ref counting */ + for (i = 0; i < ARRAY_SIZE(acp_dmic_dai); i++) + k_spinlock_init(&acp_dmic_dai[i].lock); + for (i = 0; i < ARRAY_SIZE(hsdai); i++) + k_spinlock_init(&hsdai[i].lock); +#ifdef ACP_SP_ENABLE + for (i = 0; i < ARRAY_SIZE(spdai); i++) + k_spinlock_init(&spdai[i].lock); + /* initialize spin locks early to enable ref counting */ + for (i = 0; i < ARRAY_SIZE(sp_virtual_dai); i++) + k_spinlock_init(&sp_virtual_dai[i].lock); +#endif +#ifdef ACP_BT_ENABLE + /* initialize spin locks early to enable ref counting */ + for (i = 0; i < ARRAY_SIZE(btdai); i++) + k_spinlock_init(&btdai[i].lock); +#endif + sof->dai_info = &lib_dai; + return 0; +} diff --git a/src/platform/amd/acp_6_3/lib/dma.c b/src/platform/amd/acp_6_3/lib/dma.c new file mode 100644 index 000000000000..d9dd7f4c474d --- /dev/null +++ b/src/platform/amd/acp_6_3/lib/dma.c @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct dma_ops acp_dma_ops; +extern struct dma_ops acp_dmic_dma_ops; +#ifdef ACP_BT_ENABLE +extern struct dma_ops acp_dai_bt_dma_ops; +#endif +#ifdef ACP_SP_ENABLE +extern struct dma_ops acp_dai_sp_dma_ops; +#endif +extern struct dma_ops acp_dai_hs_dma_ops; + +SHARED_DATA struct dma dma[PLATFORM_NUM_DMACS] = { +{ + .plat_data = { + .id = DMA_ID_DMA0, + .dir = DMA_DIR_LMEM_TO_HMEM | DMA_DIR_HMEM_TO_LMEM, + .devs = DMA_DEV_HOST, + .base = DMA0_BASE, + .chan_size = DMA0_SIZE, + .channels = 8, + .irq = IRQ_NUM_EXT_LEVEL5, + .irq_name = "irqsteer1", + }, + .ops = &acp_dma_ops, +}, +{ + .plat_data = { + .id = DMA_ID_DAI_HS, + .dir = DMA_DIR_DEV_TO_MEM | DMA_DIR_MEM_TO_DEV, + .devs = DMA_DEV_SP, + .caps = DMA_CAP_SP, + .base = DMA0_BASE, + .chan_size = DMA0_SIZE, + .channels = 8, + .irq = IRQ_NUM_EXT_LEVEL5, + .irq_name = "irqsteer1", + }, + .ops = &acp_dai_hs_dma_ops, +}, +{ + .plat_data = { + .id = DMA_ID_DAI_DMIC, + .dir = DMA_DIR_DEV_TO_MEM, + .devs = DMA_DEV_DMIC, + .caps = DMA_CAP_DMIC, + .base = DMA0_BASE, + .chan_size = DMA0_SIZE, + .channels = 8, + .irq = IRQ_NUM_EXT_LEVEL4, + }, + .ops = &acp_dmic_dma_ops, +}, +#ifdef ACP_SP_ENABLE +{ + .plat_data = { + .id = DMA_ID_DAI_SP, + .dir = DMA_DIR_DEV_TO_MEM | DMA_DIR_MEM_TO_DEV, + .devs = DMA_DEV_SP, + .caps = DMA_CAP_SP, + .base = DMA0_BASE, + .chan_size = DMA0_SIZE, + .channels = 8, + .irq = IRQ_NUM_EXT_LEVEL5, + }, + .ops = &acp_dai_sp_dma_ops, +}, +{ + .plat_data = { + .id = DMA_ID_DAI_SP_VIRTUAL, + .dir = DMA_DIR_DEV_TO_MEM | DMA_DIR_MEM_TO_DEV, + .devs = DMA_DEV_SP_VIRTUAL, + .caps = DMA_CAP_SP_VIRTUAL, + .base = DMA0_BASE, + .chan_size = DMA0_SIZE, + .channels = 8, + .irq = IRQ_NUM_EXT_LEVEL5, + }, + .ops = &acp_dai_sp_virtual_dma_ops, +}, +#endif + +#ifdef ACP_BT_ENABLE +{ + .plat_data = { + .id = DMA_ID_DAI, + .dir = DMA_DIR_DEV_TO_MEM | DMA_DIR_MEM_TO_DEV, + .devs = DMA_DEV_BT, + .caps = DMA_CAP_BT, + .base = DMA0_BASE, + .chan_size = DMA0_SIZE, + .channels = 8, + .irq = IRQ_NUM_EXT_LEVEL5, + }, + .ops = &acp_dai_bt_dma_ops, +}, +#endif +}; + +const struct dma_info lib_dma = { + .dma_array = dma, + .num_dmas = ARRAY_SIZE(dma) +}; + +int acp_dma_init(struct sof *sof) +{ + int i; + uint32_t descr_base; + volatile acp_scratch_mem_config_t *pscratch_mem_cfg = + (volatile acp_scratch_mem_config_t *)(PU_SCRATCH_REG_BASE + SCRATCH_REG_OFFSET); + descr_base = (uint32_t)(&pscratch_mem_cfg->acp_cfg_dma_descriptor); + descr_base = (descr_base - 0x9C700000); + io_reg_write((PU_REGISTER_BASE + ACP_DMA_DESC_BASE_ADDR), descr_base); + io_reg_write((PU_REGISTER_BASE + ACP_DMA_DESC_MAX_NUM_DSCR), 0x1); + /* early lock initialization for ref counting */ + for (i = 0; i < ARRAY_SIZE(dma); i++) + k_spinlock_init(&dma[i].lock); + sof->dma_info = &lib_dma; + return 0; +} diff --git a/src/platform/amd/acp_6_3/lib/memory.c b/src/platform/amd/acp_6_3/lib/memory.c new file mode 100644 index 000000000000..94047b7c488a --- /dev/null +++ b/src/platform/amd/acp_6_3/lib/memory.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright 2023 AMD +// +// Author:Basavaraj Hiregoudar + +#include +#include +#include +#include +#include +#include + +/* Heap blocks for system runtime */ +static SHARED_DATA struct block_hdr sys_rt_block64[HEAP_SYS_RT_COUNT64]; +static SHARED_DATA struct block_hdr sys_rt_block512[HEAP_SYS_RT_COUNT512]; +static SHARED_DATA struct block_hdr sys_rt_block1024[HEAP_SYS_RT_COUNT1024]; + +/* Heap memory for system runtime */ +static SHARED_DATA struct block_map sys_rt_heap_map[] = { + BLOCK_DEF(64, HEAP_SYS_RT_COUNT64, sys_rt_block64), + BLOCK_DEF(512, HEAP_SYS_RT_COUNT512, sys_rt_block512), + BLOCK_DEF(1024, HEAP_SYS_RT_COUNT1024, sys_rt_block1024), +}; + +/* Heap blocks for modules */ +static SHARED_DATA struct block_hdr mod_block16[HEAP_RT_COUNT16]; +static SHARED_DATA struct block_hdr mod_block32[HEAP_RT_COUNT32]; +static SHARED_DATA struct block_hdr mod_block64[HEAP_RT_COUNT64]; +static SHARED_DATA struct block_hdr mod_block128[HEAP_RT_COUNT128]; +static SHARED_DATA struct block_hdr mod_block256[HEAP_RT_COUNT256]; +static SHARED_DATA struct block_hdr mod_block512[HEAP_RT_COUNT512]; +static SHARED_DATA struct block_hdr mod_block1024[HEAP_RT_COUNT1024]; +static SHARED_DATA struct block_hdr mod_block2048[HEAP_RT_COUNT2048]; + +/* Heap memory map for modules */ +static SHARED_DATA struct block_map rt_heap_map[] = { + BLOCK_DEF(16, HEAP_RT_COUNT16, mod_block16), + BLOCK_DEF(32, HEAP_RT_COUNT32, mod_block32), + BLOCK_DEF(64, HEAP_RT_COUNT64, mod_block64), + BLOCK_DEF(128, HEAP_RT_COUNT128, mod_block128), + BLOCK_DEF(256, HEAP_RT_COUNT256, mod_block256), + BLOCK_DEF(512, HEAP_RT_COUNT512, mod_block512), + BLOCK_DEF(1024, HEAP_RT_COUNT1024, mod_block1024), + BLOCK_DEF(2048, HEAP_RT_COUNT2048, mod_block2048), +}; + +/* Heap blocks for buffers */ +static SHARED_DATA struct block_hdr buf_block[HEAP_BUFFER_COUNT]; + +/* Heap memory map for buffers */ +static SHARED_DATA struct block_map buf_heap_map[] = { + BLOCK_DEF(HEAP_BUFFER_BLOCK_SIZE, HEAP_BUFFER_COUNT, buf_block), +}; + +static SHARED_DATA struct mm memmap = { + .system[0] = { + .heap = HEAP_SYSTEM_BASE, + .size = HEAP_SYSTEM_SIZE, + .info = {.free = HEAP_SYSTEM_SIZE,}, + .caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA, + }, + .system_runtime[0] = { + .blocks = ARRAY_SIZE(sys_rt_heap_map), + .map = sys_rt_heap_map, + .heap = HEAP_SYS_RUNTIME_BASE, + .size = HEAP_SYS_RUNTIME_SIZE, + .info = {.free = HEAP_SYS_RUNTIME_SIZE,}, + .caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA, + }, + .runtime[0] = { + .blocks = ARRAY_SIZE(rt_heap_map), + .map = rt_heap_map, + .heap = HEAP_RUNTIME_BASE, + .size = HEAP_RUNTIME_SIZE, + .info = {.free = HEAP_RUNTIME_SIZE,}, + .caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA, + }, + .buffer[0] = { + .blocks = ARRAY_SIZE(buf_heap_map), + .map = buf_heap_map, + .heap = HEAP_BUFFER_BASE, + .size = HEAP_BUFFER_SIZE, + .info = {.free = HEAP_BUFFER_SIZE,}, + .caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA | SOF_MEM_CAPS_CACHE | SOF_MEM_CAPS_HP, + }, + .total = {.free = HEAP_SYSTEM_SIZE + HEAP_SYS_RUNTIME_SIZE + + HEAP_RUNTIME_SIZE + HEAP_BUFFER_SIZE,}, +}; + +void platform_init_memmap(struct sof *sof) +{ + /* memmap has been initialized statically as a part of .data */ + sof->memory_map = &memmap; +} diff --git a/src/platform/amd/acp_6_3/platform.c b/src/platform/amd/acp_6_3/platform.c new file mode 100644 index 000000000000..66aac4c054e1 --- /dev/null +++ b/src/platform/amd/acp_6_3/platform.c @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +//Copyright(c) 2023 AMD. All rights reserved. +// +//Author: Basavaraj Hiregoudar +// SaiSurya, Ch + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct sof; +static const struct sof_ipc_fw_ready ready + __attribute__((section(".fw_ready"))) = { + .hdr = { + .cmd = SOF_IPC_FW_READY, + .size = sizeof(struct sof_ipc_fw_ready), + }, + /* dspbox is for DSP initiated IPC, hostbox is for host initiated IPC */ + .version = { + .hdr.size = sizeof(struct sof_ipc_fw_version), + .micro = SOF_MICRO, + .minor = SOF_MINOR, + .major = SOF_MAJOR, +#ifdef DEBUG_BUILD + /* only added in debug for reproducibility in releases */ + .build = SOF_BUILD, + .date = __DATE__, + .time = __TIME__, +#endif + .tag = SOF_TAG, + .abi_version = SOF_ABI_VERSION, + }, + .flags = DEBUG_SET_FW_READY_FLAGS, +}; + +#define NUM_ACP_WINDOWS 6 + +const struct ext_man_windows xsram_window + __aligned(EXT_MAN_ALIGN) __section(".fw_metadata") __unused = { + .hdr = { + .type = EXT_MAN_ELEM_WINDOW, + .elem_size = ALIGN_UP_COMPILE(sizeof(struct ext_man_windows), EXT_MAN_ALIGN), + }, + .window = { + .ext_hdr = { + .hdr.cmd = SOF_IPC_FW_READY, + .hdr.size = sizeof(struct sof_ipc_window), + .type = SOF_IPC_EXT_WINDOW, + }, + .num_windows = NUM_ACP_WINDOWS, + .window = { + { + .type = SOF_IPC_REGION_UPBOX, + .id = 0, + .flags = 0, + .size = MAILBOX_DSPBOX_SIZE, + .offset = MAILBOX_DSPBOX_OFFSET, + }, + { + .type = SOF_IPC_REGION_DOWNBOX, + .id = 0, + .flags = 0, + .size = MAILBOX_HOSTBOX_SIZE, + .offset = MAILBOX_HOSTBOX_OFFSET, + }, + { + .type = SOF_IPC_REGION_DEBUG, + .id = 0, + .flags = 0, + .size = MAILBOX_DEBUG_SIZE, + .offset = MAILBOX_DEBUG_OFFSET, + }, + { + .type = SOF_IPC_REGION_TRACE, + .id = 0, + .flags = 0, + .size = MAILBOX_TRACE_SIZE, + .offset = MAILBOX_TRACE_OFFSET, + }, + { + .type = SOF_IPC_REGION_STREAM, + .id = 0, + .flags = 0, + .size = MAILBOX_STREAM_SIZE, + .offset = MAILBOX_STREAM_OFFSET, + }, + { + .type = SOF_IPC_REGION_EXCEPTION, + .id = 0, + .flags = 0, + .size = MAILBOX_EXCEPTION_SIZE, + .offset = MAILBOX_EXCEPTION_OFFSET, + }, + }, + }, +}; + +static SHARED_DATA struct timer timer = { + .id = TIMER0, + .irq = IRQ_NUM_TIMER0, +}; + +int platform_init(struct sof *sof) +{ + int ret; + + sof->platform_timer = &timer; + sof->cpu_timers = &timer; + /* to view system memory */ + interrupt_init(sof); + platform_interrupt_init(); + platform_clock_init(sof); + scheduler_init_edf(); + /* init low latency domains and schedulers */ + /* CONFIG_SYSTICK_PERIOD set as PLATFORM_DEFAULT_CLOCK */ + sof->platform_timer_domain = + timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK); + scheduler_init_ll(sof->platform_timer_domain); + platform_timer_start(sof->platform_timer); + /*CONFIG_SYSTICK_PERIOD hardcoded as 200000*/ + sa_init(sof, 200000); + clock_set_freq(CLK_CPU(cpu_get_id()), CLK_MAX_CPU_HZ); + /* init DMA */ + ret = acp_dma_init(sof); + if (ret < 0) + return -ENODEV; + /* Init DMA platform domain */ + sof->platform_dma_domain = + dma_multi_chan_domain_init(&sof->dma_info->dma_array[0], + sizeof(sof->dma_info->dma_array), + PLATFORM_DEFAULT_CLOCK, true); + sof->platform_dma_domain->full_sync = true; + scheduler_init_ll(sof->platform_dma_domain); + /* initialize the host IPC mechanisms */ + ipc_init(sof); + /* initialize the DAI mechanisms */ + ret = dai_init(sof); + if (ret < 0) + return -ENODEV; +#if CONFIG_TRACE + /* Initialize DMA for Trace*/ + trace_point(TRACE_BOOT_PLATFORM_DMA_TRACE); + sof->dmat->config.elem_array.elems = + rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, + sizeof(struct dma_sg_elem) * 1); + sof->dmat->config.elem_array.count = 1; + sof->dmat->config.elem_array.elems->dest = 0x03800000; + sof->dmat->config.elem_array.elems->size = 65536; + sof->dmat->config.scatter = 0; + dma_trace_init_complete(sof->dmat); +#endif + /* show heap status */ + heap_trace_all(1); + return 0; +} + +int platform_boot_complete(uint32_t boot_message) +{ + acp_sw_intr_trig_t swintrtrig; + + volatile acp_scratch_mem_config_t *pscratch_mem_cfg = + (volatile acp_scratch_mem_config_t *)(PU_SCRATCH_REG_BASE + SCRATCH_REG_OFFSET); + mailbox_dspbox_write(0, &ready, sizeof(ready)); + pscratch_mem_cfg->acp_dsp_msg_write = 1; + acp_dsp_to_host_intr_trig(); + /* Configures the trigger bit in ACP_DSP_SW_INTR_TRIG register */ + swintrtrig = (acp_sw_intr_trig_t)io_reg_read(PU_REGISTER_BASE + ACP_SW_INTR_TRIG); + swintrtrig.bits.trig_dsp0_to_host_intr = INTERRUPT_DISABLE; + io_reg_write((PU_REGISTER_BASE + ACP_SW_INTR_TRIG), swintrtrig.u32all); + clock_set_freq(CLK_CPU(cpu_get_id()), CLK_DEFAULT_CPU_HZ); + return 0; +} + +int platform_context_save(struct sof *sof) +{ + return 0; +} + +void platform_wait_for_interrupt(int level) +{ + arch_wait_for_interrupt(level); +} diff --git a/src/platform/imx8m/include/platform/lib/memory.h b/src/platform/imx8m/include/platform/lib/memory.h index 7d285dbfc463..6b2c00f89bad 100644 --- a/src/platform/imx8m/include/platform/lib/memory.h +++ b/src/platform/imx8m/include/platform/lib/memory.h @@ -59,6 +59,9 @@ #define SAI_7_BASE 0x30c80000 #define SAI_7_SIZE 0x00010000 +#define MICFIL_BASE 0x30ca0000 +#define MICFIL_SIZE 0x00010000 + #define UUID_ENTRY_ELF_BASE 0x1FFFA000 #define UUID_ENTRY_ELF_SIZE 0x6000 diff --git a/src/platform/imx8m/lib/dai.c b/src/platform/imx8m/lib/dai.c index 1096740e4f58..1293cdc6fd7f 100644 --- a/src/platform/imx8m/lib/dai.c +++ b/src/platform/imx8m/lib/dai.c @@ -6,6 +6,8 @@ #include #include +#include + #include #include #include @@ -142,12 +144,38 @@ static SHARED_DATA struct dai sai[] = { }; +static SHARED_DATA struct dai micfil[] = { +{ + .index = 2, + .plat_data = { + .base = MICFIL_BASE, + .fifo[SOF_IPC_STREAM_PLAYBACK] = { + .offset = 0, /* No playback */ + .handshake = 0, + }, + .fifo[SOF_IPC_STREAM_CAPTURE] = { + .offset = MICFIL_BASE + REG_MICFIL_DATACH0, + .handshake = 24, + .depth = 32, /* in 4 bytes words */ + }, + }, + + .drv = &micfil_driver, +}, +}; + const struct dai_type_info dti[] = { { .type = SOF_DAI_IMX_SAI, .dai_array = cache_to_uncache_init((struct dai *)sai), .num_dais = ARRAY_SIZE(sai) }, + { + .type = SOF_DAI_IMX_MICFIL, + .dai_array = cache_to_uncache_init((struct dai *)micfil), + .num_dais = ARRAY_SIZE(micfil) + }, + }; const struct dai_info lib_dai = { diff --git a/src/platform/imx8m/lib/dma.c b/src/platform/imx8m/lib/dma.c index 12403f92809e..ca02d52904ad 100644 --- a/src/platform/imx8m/lib/dma.c +++ b/src/platform/imx8m/lib/dma.c @@ -31,7 +31,7 @@ static SHARED_DATA struct dma dma[PLATFORM_NUM_DMACS] = { * enabled as it is unneeded */ .dir = DMA_DIR_MEM_TO_DEV | DMA_DIR_DEV_TO_MEM, - .devs = DMA_DEV_SAI, + .devs = DMA_DEV_SAI | DMA_DEV_MICFIL, .base = SDMA3_BASE, .channels = 32, .irq = SDMA3_IRQ, diff --git a/src/platform/library/include/platform/drivers/idc.h b/src/platform/library/include/platform/drivers/idc.h index 8738c87324dd..e538884bbb5f 100644 --- a/src/platform/library/include/platform/drivers/idc.h +++ b/src/platform/library/include/platform/drivers/idc.h @@ -5,7 +5,7 @@ * Author: Tomasz Lauda */ -#if defined(__XTOS_RTOS_IDC_H__) || defined(__ZEPHYR_RTOS_IDC_H__) +#ifdef __POSIX_RTOS_IDC_H__ #ifndef __PLATFORM_DRIVERS_IDC_H__ #define __PLATFORM_DRIVERS_IDC_H__ diff --git a/src/platform/library/include/platform/lib/clk.h b/src/platform/library/include/platform/lib/clk.h index 7c089ebac4f9..6d389a6152af 100644 --- a/src/platform/library/include/platform/lib/clk.h +++ b/src/platform/library/include/platform/lib/clk.h @@ -18,6 +18,22 @@ #define NUM_CLOCKS 2 +#define CPU_WOVCRO_FREQ_IDX 0 + +#define CPU_LPRO_FREQ_IDX 1 + +#define CPU_HPRO_FREQ_IDX 2 + +#define CPU_LOWEST_FREQ_IDX CPU_WOVCRO_FREQ_IDX + +#define CPU_DEFAULT_IDX CPU_HPRO_FREQ_IDX + +#define SSP_DEFAULT_IDX 1 + +#define NUM_CPU_FREQ 3 + +#define NUM_SSP_FREQ 3 + #endif /* __PLATFORM_LIB_CLK_H__ */ #else diff --git a/src/platform/library/include/platform/lib/dai.h b/src/platform/library/include/platform/lib/dai.h index 45065e86c3b9..5fb740e32270 100644 --- a/src/platform/library/include/platform/lib/dai.h +++ b/src/platform/library/include/platform/lib/dai.h @@ -10,6 +10,22 @@ #ifndef __PLATFORM_LIB_DAI_H__ #define __PLATFORM_LIB_DAI_H__ +#define DAI_NUM_SSP_BASE 6 + +/** \brief Number of HD/A Link Outputs */ +#define DAI_NUM_HDA_OUT 6 + +/** \brief Number of HD/A Link Inputs */ +#define DAI_NUM_HDA_IN 7 + +/* ALH */ + +/** \brief Number of ALH bi-directional links */ +#define DAI_NUM_ALH_BI_DIR_LINKS 16 + +/** \brief Number of contiguous ALH bi-dir links */ +#define DAI_NUM_ALH_BI_DIR_LINKS_GROUP 4 + #endif /* __PLATFORM_LIB_DAI_H__ */ #else diff --git a/src/platform/library/include/platform/lib/mailbox.h b/src/platform/library/include/platform/lib/mailbox.h index fbfbc3719b96..04470a43e66e 100644 --- a/src/platform/library/include/platform/lib/mailbox.h +++ b/src/platform/library/include/platform/lib/mailbox.h @@ -52,6 +52,13 @@ static inline void mailbox_sw_reg_write(size_t offset, uint32_t src) { } +static inline void mailbox_sw_regs_write(size_t offset, const void *src, size_t bytes) {} + +static inline uint32_t mailbox_sw_reg_read(size_t offset) +{ + return 0; +} + #endif /* __PLATFORM_LIB_MAILBOX_H__ */ #else diff --git a/src/platform/library/include/platform/lib/memory.h b/src/platform/library/include/platform/lib/memory.h index f57e31617da3..fafb3df303f7 100644 --- a/src/platform/library/include/platform/lib/memory.h +++ b/src/platform/library/include/platform/lib/memory.h @@ -182,6 +182,8 @@ static inline uint32_t arch_get_stack_size(void) #define host_to_local(addr) (addr) #define local_to_host(addr) (addr) +#define IMR_BOOT_LDR_MANIFEST_BASE NULL + #endif /* __PLATFORM_LIB_MEMORY_H__ */ #else diff --git a/src/platform/library/include/platform/platform.h b/src/platform/library/include/platform/platform.h index b1912049d4ec..2b1b4f31fa0c 100644 --- a/src/platform/library/include/platform/platform.h +++ b/src/platform/library/include/platform/platform.h @@ -56,6 +56,8 @@ struct timer; */ #define DMA_TRACE_RESCHEDULE_TIME 100 +#define HW_CFG_VERSION 0 + static inline void platform_panic(uint32_t p) {} /** diff --git a/src/platform/library/lib/trace.c b/src/platform/library/lib/trace.c index fdd00b7777b6..7ca847afabec 100644 --- a/src/platform/library/lib/trace.c +++ b/src/platform/library/lib/trace.c @@ -12,8 +12,7 @@ #include /* enable trace by default in testbench */ -int test_bench_trace = 1; -int debug; +int host_trace_level = LOG_LEVEL_ERROR; /* look up subsystem class name from table */ char *get_trace_class(uint32_t trace_class) diff --git a/src/platform/lunarlake/include/platform/lib/clk.h b/src/platform/lunarlake/include/platform/lib/clk.h index fe8f140ff0a6..77e72d8c6ccd 100644 --- a/src/platform/lunarlake/include/platform/lib/clk.h +++ b/src/platform/lunarlake/include/platform/lib/clk.h @@ -14,21 +14,19 @@ #include -#define CLK_MAX_CPU_HZ 400000000 +#define CLK_MAX_CPU_HZ CONFIG_XTENSA_CCOUNT_HZ #define CPU_WOVCRO_FREQ_IDX 0 -#define CPU_LPRO_FREQ_IDX 1 - -#define CPU_HPRO_FREQ_IDX 2 +#define CPU_IPLL_FREQ_IDX 1 #define CPU_LOWEST_FREQ_IDX CPU_WOVCRO_FREQ_IDX -#define CPU_DEFAULT_IDX CPU_HPRO_FREQ_IDX +#define CPU_DEFAULT_IDX CPU_IPLL_FREQ_IDX #define SSP_DEFAULT_IDX 1 -#define NUM_CPU_FREQ 3 +#define NUM_CPU_FREQ 2 #define NUM_SSP_FREQ 3 diff --git a/src/platform/lunarlake/include/platform/lib/memory.h b/src/platform/lunarlake/include/platform/lib/memory.h index 5f7ced26f922..e23fd7556482 100644 --- a/src/platform/lunarlake/include/platform/lib/memory.h +++ b/src/platform/lunarlake/include/platform/lib/memory.h @@ -56,7 +56,7 @@ /** * size of HPSRAM system heap */ -#define HEAPMEM_SIZE 0x40000 +#define HEAPMEM_SIZE 0xF0000 #endif /* __PLATFORM_LIB_MEMORY_H__ */ diff --git a/src/platform/lunarlake/lib/clk.c b/src/platform/lunarlake/lib/clk.c index ed2936b5efc4..7ad664c94118 100644 --- a/src/platform/lunarlake/lib/clk.c +++ b/src/platform/lunarlake/lib/clk.c @@ -9,9 +9,8 @@ #include static const struct freq_table platform_cpu_freq[] = { - { 38400000, 38400 }, - { 120000000, 120000 }, - { CLK_MAX_CPU_HZ, 400000 }, + { CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000 }, + { CLK_MAX_CPU_HZ, CLK_MAX_CPU_HZ / 1000 }, }; STATIC_ASSERT(ARRAY_SIZE(platform_cpu_freq) == NUM_CPU_FREQ, invalid_number_of_cpu_frequencies); diff --git a/src/platform/meteorlake/include/platform/lib/clk.h b/src/platform/meteorlake/include/platform/lib/clk.h index 2eb1732aad55..fec0a582ab7e 100644 --- a/src/platform/meteorlake/include/platform/lib/clk.h +++ b/src/platform/meteorlake/include/platform/lib/clk.h @@ -14,21 +14,19 @@ #include -#define CLK_MAX_CPU_HZ 400000000 +#define CLK_MAX_CPU_HZ CONFIG_XTENSA_CCOUNT_HZ #define CPU_WOVCRO_FREQ_IDX 0 -#define CPU_LPRO_FREQ_IDX 1 - -#define CPU_HPRO_FREQ_IDX 2 +#define CPU_IPLL_FREQ_IDX 1 #define CPU_LOWEST_FREQ_IDX CPU_WOVCRO_FREQ_IDX -#define CPU_DEFAULT_IDX CPU_HPRO_FREQ_IDX +#define CPU_DEFAULT_IDX CPU_IPLL_FREQ_IDX #define SSP_DEFAULT_IDX 1 -#define NUM_CPU_FREQ 3 +#define NUM_CPU_FREQ 2 #define NUM_SSP_FREQ 3 diff --git a/src/platform/meteorlake/include/platform/lib/memory.h b/src/platform/meteorlake/include/platform/lib/memory.h index a741d0fb1025..77e8b7c1b25b 100644 --- a/src/platform/meteorlake/include/platform/lib/memory.h +++ b/src/platform/meteorlake/include/platform/lib/memory.h @@ -56,7 +56,7 @@ /** * size of HPSRAM system heap */ -#define HEAPMEM_SIZE 0xD0000 +#define HEAPMEM_SIZE 0xF0000 #endif /* __PLATFORM_LIB_MEMORY_H__ */ diff --git a/src/platform/meteorlake/lib/clk.c b/src/platform/meteorlake/lib/clk.c index 227bc9fd9366..20221b89d790 100644 --- a/src/platform/meteorlake/lib/clk.c +++ b/src/platform/meteorlake/lib/clk.c @@ -9,9 +9,8 @@ #include static const struct freq_table platform_cpu_freq[] = { - { 38400000, 38400 }, - { 120000000, 120000 }, - { CLK_MAX_CPU_HZ, 400000 }, + { CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000 }, + { CLK_MAX_CPU_HZ, CLK_MAX_CPU_HZ / 1000 }, }; STATIC_ASSERT(ARRAY_SIZE(platform_cpu_freq) == NUM_CPU_FREQ, invalid_number_of_cpu_frequencies); diff --git a/src/platform/mt8186/include/platform/lib/memory.h b/src/platform/mt8186/include/platform/lib/memory.h index c3532b103cda..65148c9c348d 100644 --- a/src/platform/mt8186/include/platform/lib/memory.h +++ b/src/platform/mt8186/include/platform/lib/memory.h @@ -115,7 +115,7 @@ #define HEAP_RT_COUNT64 32 #define HEAP_RT_COUNT128 32 #define HEAP_RT_COUNT256 32 -#define HEAP_RT_COUNT512 4 +#define HEAP_RT_COUNT512 32 #define HEAP_RT_COUNT1024 4 #define HEAP_RT_COUNT2048 2 #define HEAP_RT_COUNT4096 2 diff --git a/src/platform/mt8188/include/platform/lib/memory.h b/src/platform/mt8188/include/platform/lib/memory.h index c3532b103cda..65148c9c348d 100644 --- a/src/platform/mt8188/include/platform/lib/memory.h +++ b/src/platform/mt8188/include/platform/lib/memory.h @@ -115,7 +115,7 @@ #define HEAP_RT_COUNT64 32 #define HEAP_RT_COUNT128 32 #define HEAP_RT_COUNT256 32 -#define HEAP_RT_COUNT512 4 +#define HEAP_RT_COUNT512 32 #define HEAP_RT_COUNT1024 4 #define HEAP_RT_COUNT2048 2 #define HEAP_RT_COUNT4096 2 diff --git a/src/platform/mt8195/include/platform/lib/memory.h b/src/platform/mt8195/include/platform/lib/memory.h index 33e0e1e74f1a..47bb91202bfb 100644 --- a/src/platform/mt8195/include/platform/lib/memory.h +++ b/src/platform/mt8195/include/platform/lib/memory.h @@ -103,7 +103,7 @@ #define HEAP_RT_COUNT64 32 #define HEAP_RT_COUNT128 32 #define HEAP_RT_COUNT256 32 -#define HEAP_RT_COUNT512 4 +#define HEAP_RT_COUNT512 32 #define HEAP_RT_COUNT1024 4 #define HEAP_RT_COUNT2048 2 #define HEAP_RT_COUNT4096 2 diff --git a/src/platform/posix/include/platform/lib/clk.h b/src/platform/posix/include/platform/lib/clk.h index 3c9ff3b96950..7d396330a0cb 100644 --- a/src/platform/posix/include/platform/lib/clk.h +++ b/src/platform/posix/include/platform/lib/clk.h @@ -5,6 +5,7 @@ #define CLK_MAX_CPU_HZ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC #define CPU_LPRO_FREQ_IDX 1 +#define CPU_LOWEST_FREQ_IDX CPU_LPRO_FREQ_IDX /* This is not a platform function, it's defined in src/lib/clk.c. * But the declaration has historically been in the platform layer, so diff --git a/src/probe/probe.c b/src/probe/probe.c index 91344e08c56a..933cea584f6d 100644 --- a/src/probe/probe.c +++ b/src/probe/probe.c @@ -841,7 +841,7 @@ static void kick_probe_task(struct probe_pdata *_probe) } #if CONFIG_LOG_BACKEND_SOF_PROBE -static void probe_logging_hook(uint8_t *buffer, size_t length) +void probe_logging_hook(uint8_t *buffer, size_t length) { struct probe_pdata *_probe = probe_get(); uint64_t checksum; @@ -879,7 +879,7 @@ static void probe_cb_produce(void *arg, enum notify_id type, void *data) { struct probe_pdata *_probe = probe_get(); struct buffer_cb_transact *cb_data = data; - struct comp_buffer __sparse_cache *buffer = cb_data->buffer; + struct comp_buffer *buffer = cb_data->buffer; struct probe_dma_ext *dma; uint32_t buffer_id; uint32_t head, tail; @@ -1066,7 +1066,6 @@ static bool probe_purpose_needs_ext_dma(uint32_t purpose) static struct comp_buffer *ipc4_get_buffer(struct ipc_comp_dev *dev, probe_point_id_t probe_point) { struct comp_buffer *buf; - struct comp_buffer __sparse_cache *buf_c; struct list_item *sink_list, *source_list; unsigned int queue_id; @@ -1074,9 +1073,7 @@ static struct comp_buffer *ipc4_get_buffer(struct ipc_comp_dev *dev, probe_point case PROBE_TYPE_INPUT: list_for_item(source_list, &dev->cd->bsource_list) { buf = container_of(source_list, struct comp_buffer, sink_list); - buf_c = buffer_acquire(buf); - queue_id = IPC4_SRC_QUEUE_ID(buf_c->id); - buffer_release(buf_c); + queue_id = IPC4_SRC_QUEUE_ID(buf->id); if (queue_id == probe_point.fields.index) return buf; @@ -1085,9 +1082,7 @@ static struct comp_buffer *ipc4_get_buffer(struct ipc_comp_dev *dev, probe_point case PROBE_TYPE_OUTPUT: list_for_item(sink_list, &dev->cd->bsink_list) { buf = container_of(sink_list, struct comp_buffer, source_list); - buf_c = buffer_acquire(buf); - queue_id = IPC4_SINK_QUEUE_ID(buf_c->id); - buffer_release(buf_c); + queue_id = IPC4_SINK_QUEUE_ID(buf->id); if (queue_id == probe_point.fields.index) return buf; diff --git a/src/samples/audio/detect_test.c b/src/samples/audio/detect_test.c index 55058f6ca047..88a32301cf2a 100644 --- a/src/samples/audio/detect_test.c +++ b/src/samples/audio/detect_test.c @@ -101,7 +101,7 @@ struct comp_data { struct ipc_msg *msg; /**< host notification */ void (*detect_func)(struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, uint32_t frames); + const struct audio_stream *source, uint32_t frames); struct sof_ipc_comp_event event; #if CONFIG_AMS @@ -209,7 +209,7 @@ void detect_test_notify(const struct comp_dev *dev) } static void default_detect_test(struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, + const struct audio_stream *source, uint32_t frames) { struct comp_data *cd = comp_get_drvdata(dev); @@ -797,7 +797,6 @@ static int test_keyword_params(struct comp_dev *dev, { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *sourceb; - struct comp_buffer __sparse_cache *source_c; unsigned int channels, rate; enum sof_ipc_frame frame_fmt; int err; @@ -815,11 +814,9 @@ static int test_keyword_params(struct comp_dev *dev, /* keyword components will only ever have 1 source */ sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - source_c = buffer_acquire(sourceb); - channels = audio_stream_get_channels(&source_c->stream); - frame_fmt = audio_stream_get_frm_fmt(&source_c->stream); - rate = audio_stream_get_rate(&source_c->stream); - buffer_release(source_c); + channels = audio_stream_get_channels(&sourceb->stream); + frame_fmt = audio_stream_get_frm_fmt(&sourceb->stream); + rate = audio_stream_get_rate(&sourceb->stream); if (channels != 1) { comp_err(dev, "test_keyword_params(): only single-channel supported"); @@ -881,7 +878,6 @@ static int test_keyword_copy(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *source; - struct comp_buffer __sparse_cache *source_c; uint32_t frames; comp_dbg(dev, "test_keyword_copy()"); @@ -889,23 +885,18 @@ static int test_keyword_copy(struct comp_dev *dev) /* keyword components will only ever have 1 source */ source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - source_c = buffer_acquire(source); - if (!audio_stream_get_avail(&source_c->stream)) { - buffer_release(source_c); + if (!audio_stream_get_avail(&source->stream)) return PPL_STATUS_PATH_STOP; - } - frames = audio_stream_get_avail_frames(&source_c->stream); + frames = audio_stream_get_avail_frames(&source->stream); /* copy and perform detection */ - buffer_stream_invalidate(source_c, audio_stream_get_avail_bytes(&source_c->stream)); - cd->detect_func(dev, &source_c->stream, frames); + buffer_stream_invalidate(source, audio_stream_get_avail_bytes(&source->stream)); + cd->detect_func(dev, &source->stream, frames); /* calc new available */ - comp_update_buffer_consume(source_c, audio_stream_get_avail_bytes(&source_c->stream)); - - buffer_release(source_c); + comp_update_buffer_consume(source, audio_stream_get_avail_bytes(&source->stream)); return 0; } diff --git a/src/samples/audio/kwd_nn_detect_test.c b/src/samples/audio/kwd_nn_detect_test.c index df0a8c80af98..ef71a441580b 100644 --- a/src/samples/audio/kwd_nn_detect_test.c +++ b/src/samples/audio/kwd_nn_detect_test.c @@ -35,7 +35,7 @@ static int kwd_nn_detect_postprocess(uint8_t confidences[KWD_NN_CONFIDENCES_SIZE } void kwd_nn_detect_test(struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, + const struct audio_stream *source, uint32_t frames) { void *src; diff --git a/src/samples/audio/smart_amp_test_ipc3.c b/src/samples/audio/smart_amp_test_ipc3.c index b2056c6cb7d0..ce03381d5bbe 100644 --- a/src/samples/audio/smart_amp_test_ipc3.c +++ b/src/samples/audio/smart_amp_test_ipc3.c @@ -28,8 +28,8 @@ DECLARE_TR_CTX(smart_amp_comp_tr, SOF_UUID(smart_amp_comp_uuid), LOG_LEVEL_INFO); typedef int(*smart_amp_proc)(struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, uint32_t frames, + const struct audio_stream *source, + const struct audio_stream *sink, uint32_t frames, int8_t *chan_map); struct smart_amp_data { @@ -316,9 +316,7 @@ static int smart_amp_trigger(struct comp_dev *dev, int cmd) case COMP_TRIGGER_START: case COMP_TRIGGER_RELEASE: if (sad->feedback_buf) { - struct comp_buffer __sparse_cache *buf = buffer_acquire(sad->feedback_buf); - buffer_zero(buf); - buffer_release(buf); + buffer_zero(sad->feedback_buf); } break; case COMP_TRIGGER_PAUSE: @@ -332,8 +330,8 @@ static int smart_amp_trigger(struct comp_dev *dev, int cmd) } static int smart_amp_process_s16(struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + const struct audio_stream *sink, uint32_t frames, int8_t *chan_map) { struct smart_amp_data *sad = comp_get_drvdata(dev); @@ -364,8 +362,8 @@ static int smart_amp_process_s16(struct comp_dev *dev, } static int smart_amp_process_s32(struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink, + const struct audio_stream *source, + const struct audio_stream *sink, uint32_t frames, int8_t *chan_map) { struct smart_amp_data *sad = comp_get_drvdata(dev); @@ -397,7 +395,7 @@ static int smart_amp_process_s32(struct comp_dev *dev, } static smart_amp_proc get_smart_amp_process(struct comp_dev *dev, - struct comp_buffer __sparse_cache *buf) + struct comp_buffer *buf) { switch (audio_stream_get_frm_fmt(&buf->stream)) { case SOF_IPC_FRAME_S16_LE: @@ -414,8 +412,8 @@ static smart_amp_proc get_smart_amp_process(struct comp_dev *dev, static int smart_amp_copy(struct comp_dev *dev) { struct smart_amp_data *sad = comp_get_drvdata(dev); - struct comp_buffer __sparse_cache *source_buf = buffer_acquire(sad->source_buf); - struct comp_buffer __sparse_cache *sink_buf = buffer_acquire(sad->sink_buf); + struct comp_buffer *source_buf = sad->source_buf; + struct comp_buffer *sink_buf = sad->sink_buf; uint32_t avail_passthrough_frames; uint32_t avail_feedback_frames; uint32_t avail_frames = 0; @@ -431,7 +429,7 @@ static int smart_amp_copy(struct comp_dev *dev) &sink_buf->stream); if (sad->feedback_buf) { - struct comp_buffer __sparse_cache *buf = buffer_acquire(sad->feedback_buf); + struct comp_buffer *buf = sad->feedback_buf; if (buf->source && comp_get_state(dev, buf->source) == dev->state) { /* feedback */ @@ -454,8 +452,6 @@ static int smart_amp_copy(struct comp_dev *dev) comp_update_buffer_consume(buf, feedback_bytes); } - - buffer_release(buf); } if (!avail_frames) @@ -477,9 +473,6 @@ static int smart_amp_copy(struct comp_dev *dev) comp_update_buffer_consume(source_buf, source_bytes); comp_update_buffer_produce(sink_buf, sink_bytes); - buffer_release(sink_buf); - buffer_release(source_buf); - return 0; } @@ -496,7 +489,6 @@ static int smart_amp_prepare(struct comp_dev *dev) { struct smart_amp_data *sad = comp_get_drvdata(dev); struct comp_buffer *source_buffer; - struct comp_buffer __sparse_cache *buffer_c; struct list_item *blist; int ret; @@ -513,43 +505,33 @@ static int smart_amp_prepare(struct comp_dev *dev) list_for_item(blist, &dev->bsource_list) { source_buffer = container_of(blist, struct comp_buffer, sink_list); - buffer_c = buffer_acquire(source_buffer); /* FIXME: how often can this loop be run? */ - if (buffer_c->source->ipc_config.type == SOF_COMP_DEMUX) + if (source_buffer->source->ipc_config.type == SOF_COMP_DEMUX) sad->feedback_buf = source_buffer; else sad->source_buf = source_buffer; - - buffer_release(buffer_c); } sad->sink_buf = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - buffer_c = buffer_acquire(sad->sink_buf); - sad->out_channels = audio_stream_get_channels(&buffer_c->stream); - buffer_release(buffer_c); + sad->out_channels = audio_stream_get_channels(&sad->sink_buf->stream); - buffer_c = buffer_acquire(sad->source_buf); - sad->in_channels = audio_stream_get_channels(&buffer_c->stream); + sad->in_channels = audio_stream_get_channels(&sad->source_buf->stream); if (sad->feedback_buf) { - struct comp_buffer __sparse_cache *buf = buffer_acquire(sad->feedback_buf); - - audio_stream_set_channels(&buf->stream, sad->config.feedback_channels); - audio_stream_set_rate(&buf->stream, audio_stream_get_rate(&buffer_c->stream)); - buffer_release(buf); + audio_stream_set_channels(&sad->feedback_buf->stream, + sad->config.feedback_channels); + audio_stream_set_rate(&sad->feedback_buf->stream, + audio_stream_get_rate(&sad->source_buf->stream)); } - sad->process = get_smart_amp_process(dev, buffer_c); + sad->process = get_smart_amp_process(dev, sad->source_buf); if (!sad->process) { comp_err(dev, "smart_amp_prepare(): get_smart_amp_process failed"); ret = -EINVAL; } - - buffer_release(buffer_c); - return ret; } diff --git a/src/samples/audio/smart_amp_test_ipc4.c b/src/samples/audio/smart_amp_test_ipc4.c index a256de9c3d28..c743513b1ad5 100644 --- a/src/samples/audio/smart_amp_test_ipc4.c +++ b/src/samples/audio/smart_amp_test_ipc4.c @@ -92,7 +92,6 @@ static void smart_amp_set_params(struct processing_module *mod) struct comp_dev *dev = mod->dev; struct smart_amp_data *sad = module_get_private_data(mod); struct comp_buffer *sink; - struct comp_buffer __sparse_cache *sink_c; ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); @@ -102,11 +101,9 @@ static void smart_amp_set_params(struct processing_module *mod) struct ipc4_audio_format out_fmt = sink_fmt->audio_fmt; sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sink); - ipc4_update_buffer_format(sink_c, &out_fmt); - params->frame_fmt = audio_stream_get_frm_fmt(&sink_c->stream); - buffer_release(sink_c); + ipc4_update_buffer_format(sink, &out_fmt); + params->frame_fmt = audio_stream_get_frm_fmt(&sink->stream); } } @@ -196,8 +193,8 @@ static int smart_amp_process_s16(struct processing_module *mod, uint32_t frames, int8_t *chan_map) { struct smart_amp_data *sad = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int16_t *src; int16_t *dest; uint32_t in_frag = 0; @@ -229,8 +226,8 @@ static int smart_amp_process_s32(struct processing_module *mod, uint32_t frames, int8_t *chan_map) { struct smart_amp_data *sad = module_get_private_data(mod); - struct audio_stream __sparse_cache *source = bsource->data; - struct audio_stream __sparse_cache *sink = bsink->data; + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t *src; int32_t *dest; uint32_t in_frag = 0; @@ -258,7 +255,7 @@ static int smart_amp_process_s32(struct processing_module *mod, } static smart_amp_proc get_smart_amp_process(struct comp_dev *dev, - struct comp_buffer __sparse_cache *buf) + struct comp_buffer *buf) { switch (audio_stream_get_frm_fmt(&buf->stream)) { case SOF_IPC_FRAME_S16_LE: @@ -278,9 +275,8 @@ static int smart_amp_process(struct processing_module *mod, { struct smart_amp_data *sad = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - struct comp_buffer __sparse_cache *fb_buf_c; - struct comp_buffer __sparse_cache *buf; - struct module_source_info __sparse_cache *mod_source_info; + struct comp_buffer *fb_buf_c; + struct comp_buffer *buf; struct input_stream_buffer *fb_input = NULL; /* if there is only one input stream, it should be the source input */ struct input_stream_buffer *src_input = &input_buffers[0]; @@ -289,13 +285,9 @@ static int smart_amp_process(struct processing_module *mod, uint32_t sink_bytes; uint32_t i; - mod_source_info = module_source_info_acquire(mod->source_info); - if (num_input_buffers == SMART_AMP_NUM_IN_PINS) for (i = 0; i < num_input_buffers; i++) { - buf = attr_container_of(input_buffers[i].data, - struct comp_buffer __sparse_cache, - stream, __sparse_cache); + buf = container_of(input_buffers[i].data, struct comp_buffer, stream); if (IPC4_SINK_QUEUE_ID(buf->id) == SOF_SMART_AMP_FEEDBACK_QUEUE_ID) { fb_input = &input_buffers[i]; @@ -331,7 +323,6 @@ static int smart_amp_process(struct processing_module *mod, output_buffers[0].size = sink_bytes; - module_source_info_release(mod_source_info); return 0; } @@ -345,14 +336,13 @@ static int smart_amp_reset(struct processing_module *mod) } static int smart_amp_prepare(struct processing_module *mod, - struct sof_source __sparse_cache **sources, int num_of_sources, - struct sof_sink __sparse_cache **sinks, int num_of_sinks) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct smart_amp_data *sad = module_get_private_data(mod); struct comp_dev *dev = mod->dev; struct comp_buffer *source_buffer; struct comp_buffer *sink_buffer; - struct comp_buffer __sparse_cache *buffer_c; struct list_item *blist; int ret; @@ -365,22 +355,19 @@ static int smart_amp_prepare(struct processing_module *mod, list_for_item(blist, &dev->bsource_list) { source_buffer = container_of(blist, struct comp_buffer, sink_list); - buffer_c = buffer_acquire(source_buffer); - audio_stream_init_alignment_constants(1, 1, &buffer_c->stream); - if (IPC4_SINK_QUEUE_ID(buffer_c->id) == SOF_SMART_AMP_FEEDBACK_QUEUE_ID) { - audio_stream_set_channels(&buffer_c->stream, sad->config.feedback_channels); - audio_stream_set_rate(&buffer_c->stream, + audio_stream_init_alignment_constants(1, 1, &source_buffer->stream); + if (IPC4_SINK_QUEUE_ID(source_buffer->id) == SOF_SMART_AMP_FEEDBACK_QUEUE_ID) { + audio_stream_set_channels(&source_buffer->stream, + sad->config.feedback_channels); + audio_stream_set_rate(&source_buffer->stream, mod->priv.cfg.base_cfg.audio_fmt.sampling_frequency); } - buffer_release(buffer_c); } sink_buffer = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - buffer_c = buffer_acquire(sink_buffer); - sad->out_channels = audio_stream_get_channels(&buffer_c->stream); - audio_stream_init_alignment_constants(1, 1, &buffer_c->stream); - sad->process = get_smart_amp_process(dev, buffer_c); - buffer_release(buffer_c); + sad->out_channels = audio_stream_get_channels(&sink_buffer->stream); + audio_stream_init_alignment_constants(1, 1, &sink_buffer->stream); + sad->process = get_smart_amp_process(dev, sink_buffer); if (!sad->process) { comp_err(dev, "smart_amp_prepare(): get_smart_amp_process failed"); @@ -389,8 +376,8 @@ static int smart_amp_prepare(struct processing_module *mod, return ret; } -static struct module_interface smart_amp_interface = { - .init = smart_amp_init, +static const struct module_interface smart_amp_interface = { + .init = smart_amp_init, .prepare = smart_amp_prepare, .process_audio_stream = smart_amp_process, .set_configuration = smart_amp_set_config, diff --git a/src/schedule/zephyr_domain.c b/src/schedule/zephyr_domain.c index 1605dd6ded63..7fb9b4ae0465 100644 --- a/src/schedule/zephyr_domain.c +++ b/src/schedule/zephyr_domain.c @@ -50,6 +50,11 @@ struct zephyr_domain { struct k_timer timer; struct zephyr_domain_thread domain_thread[CONFIG_CORE_COUNT]; struct ll_schedule_domain *ll_domain; +#if CONFIG_CROSS_CORE_STREAM + atomic_t block; + struct k_mutex block_mutex; + struct k_condvar block_condvar; +#endif }; /* perf measurement windows size 2^x */ @@ -67,6 +72,26 @@ static void zephyr_domain_thread_fn(void *p1, void *p2, void *p3) /* immediately go to sleep, waiting to be woken up by the timer */ k_sem_take(&dt->sem, K_FOREVER); +#if CONFIG_CROSS_CORE_STREAM + /* + * If zephyr_domain->block is set -- block LL scheduler from starting its + * next cycle. + * Mutex locking might be somewhat expensive, hence first check for + * zephyr_domain->block value is made without locking the mutex. If + * zephyr_domain->block is not set -- no need to do anything. Otherwise, + * usual condvar procedure is performed: mutex is locked to properly check + * zephyr_domain->block value again to avoid race with unblocking procedure + * (clearing zephyr_domain->block and broadcasting the condvar). + */ + if (atomic_get(&zephyr_domain->block)) { + k_mutex_lock(&zephyr_domain->block_mutex, K_FOREVER); + if (atomic_get(&zephyr_domain->block)) + k_condvar_wait(&zephyr_domain->block_condvar, + &zephyr_domain->block_mutex, K_FOREVER); + k_mutex_unlock(&zephyr_domain->block_mutex); + } +#endif + cycles0 = k_cycle_get_32(); dt->handler(dt->arg); cycles1 = k_cycle_get_32(); @@ -221,9 +246,38 @@ static int zephyr_domain_unregister(struct ll_schedule_domain *domain, return 0; } +#if CONFIG_CROSS_CORE_STREAM +static void zephyr_domain_block(struct ll_schedule_domain *domain) +{ + struct zephyr_domain *zephyr_domain = ll_sch_domain_get_pdata(domain); + + tr_dbg(&ll_tr, "Blocking LL scheduler"); + + k_mutex_lock(&zephyr_domain->block_mutex, K_FOREVER); + atomic_set(&zephyr_domain->block, 1); + k_mutex_unlock(&zephyr_domain->block_mutex); +} + +static void zephyr_domain_unblock(struct ll_schedule_domain *domain) +{ + struct zephyr_domain *zephyr_domain = ll_sch_domain_get_pdata(domain); + + tr_dbg(&ll_tr, "Unblocking LL scheduler"); + + k_mutex_lock(&zephyr_domain->block_mutex, K_FOREVER); + atomic_set(&zephyr_domain->block, 0); + k_condvar_broadcast(&zephyr_domain->block_condvar); + k_mutex_unlock(&zephyr_domain->block_mutex); +} +#endif + static const struct ll_schedule_domain_ops zephyr_domain_ops = { .domain_register = zephyr_domain_register, .domain_unregister = zephyr_domain_unregister, +#if CONFIG_CROSS_CORE_STREAM + .domain_block = zephyr_domain_block, + .domain_unblock = zephyr_domain_unblock, +#endif }; struct ll_schedule_domain *zephyr_domain_init(int clk) @@ -239,6 +293,12 @@ struct ll_schedule_domain *zephyr_domain_init(int clk) zephyr_domain->ll_domain = domain; +#if CONFIG_CROSS_CORE_STREAM + atomic_set(&zephyr_domain->block, 0); + k_mutex_init(&zephyr_domain->block_mutex); + k_condvar_init(&zephyr_domain->block_condvar); +#endif + ll_sch_domain_set_pdata(domain, zephyr_domain); return domain; diff --git a/src/schedule/zephyr_dp_schedule.c b/src/schedule/zephyr_dp_schedule.c index a51304e9a6db..cdc5e6a8ad32 100644 --- a/src/schedule/zephyr_dp_schedule.c +++ b/src/schedule/zephyr_dp_schedule.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -29,15 +30,15 @@ DECLARE_TR_CTX(dp_tr, SOF_UUID(dp_sched_uuid), LOG_LEVEL_INFO); struct scheduler_dp_data { struct list_item tasks; /* list of active dp tasks */ - struct task task; /* LL task - source of DP tick */ + struct task ll_tick_src; /* LL task - source of DP tick */ }; struct task_dp_pdata { k_tid_t thread_id; /* zephyr thread ID */ + uint32_t period_clock_ticks; /* period the task should be scheduled in Zephyr ticks */ k_thread_stack_t __sparse_cache *p_stack; /* pointer to thread stack */ - uint32_t ticks_period; /* period the task should be scheduled in LL ticks */ - uint32_t ticks_to_trigger; /* number of ticks the task should be triggered after */ struct k_sem sem; /* semaphore for task scheduling */ + struct processing_module *mod; /* the module to be scheduled */ }; /* Single CPU-wide lock @@ -63,9 +64,154 @@ static enum task_state scheduler_dp_ll_tick_dummy(void *data) /* * function called after every LL tick * - * TODO: - * the scheduler should here calculate deadlines of all task and tell Zephyr about them - * Currently there's an assumption that the task is always ready to run + * This function checks if the queued DP tasks are ready to processing (meaning + * the module run by the task has enough data at all sources and enough free space + * on all sinks) + * + * if the task becomes ready, a deadline is set allowing Zephyr to schedule threads + * in right order + * + * TODO: currently there's a limitation - DP module must be surrounded by LL modules. + * it simplifies algorithm - there's no need to browse through DP chains calculating + * deadlines for each module in function of all modules execution status. + * Now is simple - modules deadline is its start + tick time. + * + * example: + * Lets assume we do have a pipeline: + * + * LL1 -> DP1 -> LL2 -> DP2 -> LL3 -> DP3 -> LL4 + * + * all LLs starts in 1ms tick + * + * for simplification lets assume + * - all LLs are on primary core, all DPs on secondary (100% CPU is for DP) + * - context switching requires 0 cycles + * + * DP1 - starts every 1ms, needs 0.5ms to finish processing + * DP2 - starts every 2ms, needs 0.6ms to finish processing + * DP3 - starts every 10ms, needs 0.3ms to finish processing + * + * TICK0 + * only LL1 is ready to run + * LL1 processing (producing data chunk for DP1) + * + * TICK1 + * LL1 is ready to run + * DP1 is ready tu run (has data from LL1) set deadline to TICK2 + * LL1 processing (producing second data chunk for DP1) + * DP1 processing for 0.5ms (consuming first data chunk, producing data chunk for LL2) + * CPU is idle for 0.5ms + * + * TICK2 + * LL1 is ready to run + * DP1 is ready tu run set deadline to TICK3 + * LL2 is ready to run + * LL1 processing (producing data chunk for DP1) + * LL2 processing (producing 50% data chunk for DP2) + * DP1 processing for 0.5ms (producing data chunk for LL2) + * CPU is idle for 0.5ms + * + * TICK3 + * LL1 is ready to run + * DP1 is ready tu run set deadline to TICK4 + * LL2 is ready to run + * LL1 processing (producing data chunk for DP1) + * LL2 processing (producing rest of data chunk for DP2) + * DP1 processing for 0.5ms (producing data chunk for LL2) + * CPU is idle for 0.5ms + * + * TICK4 + * LL1 is ready to run + * DP1 is ready tu run set deadline to TICK5 + * LL2 is ready to run + * DP2 is ready to run set deadline to TICK6 + * LL1 processing (producing data chunk for DP1) + * LL2 processing (producing 50% of second data chunk for DP2) + * DP1 processing for 0.5ms (producing data chunk for LL2) + * DP2 processing for 0.5ms (no data produced as DP2 has 0.1ms to go) + * 100% CPU used + * + * !!!!!! Note here - DP1 must do before DP2 as it MUST finish in this tick. DP2 can wait + * >>>>>>> this is what we call EDF - EARIEST DEADLINE FIRST <<<<<< + * + * TICK5 + * LL1 is ready to run + * DP1 is ready tu run set deadline to TICK6 + * LL2 is ready to run + * DP2 is in progress, deadline is set to TICK6 + * LL1 processing (producing data chunk for DP1) + * LL2 processing (producing rest of second data chunk for DP2) + * DP1 processing for 0.5ms (producing data chunk for LL2) + * DP2 processing for 0.1ms (producing TWO data chunks for LL3) + * CPU is idle for 0.4ms (60% used) + * + * TICK6 + * LL1 is ready to run + * DP1 is ready tu run set deadline to TICK7 + * LL2 is ready to run + * DP2 is ready to run set deadline to TICK8 + * LL3 is ready to run + * LL1 processing (producing data chunk for DP1) + * LL2 processing (producing 50% of second data chunk for DP2) + * LL3 processing (producing 10% of first data chunk for DP3) + * DP1 processing for 0.5ms (producing data chunk for LL2) + * DP2 processing for 0.5ms (no data produced as DP2 has 0.1ms to go) + * 100% CPU used + * + * + * + * (........ 9 more cycles - LL3 procuces 100% of data for DP3......) + * + * + * TICK15 + * LL1 is ready to run + * DP1 is ready tu run set deadline to TICK16 + * LL2 is ready to run + * DP2 is ready to run set deadline to TICK17 + * LL3 is ready to run + * DP3 is ready to run set deadline to TICK25 + * LL1 processing (producing data chunk for DP1) + * LL2 processing (producing 50% of data chunk for DP2) + * LL3 processing (producing 10% of second data chunk for DP3) + * DP1 processing for 0.5ms (producing data chunk for LL2) + * DP2 processing for 0.5ms (no data produced as DP2 has 0.1ms to go) + * 100% CPU used - + * !!! note that DP3 is ready but has no chance to get CPU in this cycle + * + * TICK16 + * LL1 is ready to run set deadline to TICK17 + * DP1 is ready tu run + * LL2 is ready to run + * DP2 is in progress, deadline is set to TICK17 + * LL3 is ready to run + * DP3 is in progress, deadline is set to TICK25 + * LL1 processing (producing data chunk for DP1) + * LL2 processing (producing rest of data chunk for DP2) + * LL3 processing (producing 10% of second data chunk for DP3) + * DP1 processing for 0.5ms (producing data chunk for LL2) + * DP2 processing for 0.1ms (producing data) + * DP3 processing for 0.2ms (producing 10 data chunks for LL4) + * 90% CPU used + * + * TICK17 + * LL1 is ready to run + * DP1 is ready tu run + * LL2 is ready to run + * DP2 is ready to run + * LL3 is ready to run + * LL4 is ready to run + * !! NOTE that DP3 is not ready - it will be ready again in TICK25 + * LL1 processing (producing data chunk for DP1) + * LL2 processing (producing rest of data chunk for DP2) + * LL3 processing (producing next 10% of second data chunk for DP3) + * LL4 processing (consuming 10% of data prepared by DP3) + * DP1 processing for 0.5ms (producing data chunk for LL2) + * DP2 processing for 0.5ms (no data produced as DP2 has 0.1ms to go) + * 100% CPU used + * + * + * Now - pipeline is in stable state, CPU used almost in 100% (it would be 100% if DP3 + * needed 1.2ms for processing - but the example would be too complicated) */ void scheduler_dp_ll_tick(void *receiver_data, enum notify_id event_type, void *caller_data) { @@ -81,20 +227,25 @@ void scheduler_dp_ll_tick(void *receiver_data, enum notify_id event_type, void * lock_key = scheduler_dp_lock(); list_for_item(tlist, &dp_sch->tasks) { curr_task = container_of(tlist, struct task, list); - pdata = curr_task->priv_data; - if (pdata->ticks_to_trigger == 0) { - if (curr_task->state == SOF_TASK_STATE_QUEUED) { - /* set new trigger time, start the thread */ - pdata->ticks_to_trigger = pdata->ticks_period; + /* step 1 - check if the module is ready for processing */ + if (curr_task->state == SOF_TASK_STATE_QUEUED) { + pdata = curr_task->priv_data; + struct processing_module *mod = pdata->mod; + bool mod_ready; + + mod_ready = module_is_ready_to_process(mod, mod->sources, + mod->num_of_sources, + mod->sinks, + mod->num_of_sinks); + if (mod_ready) { + /* set a deadline for given num of ticks, starting now */ + k_thread_deadline_set(pdata->thread_id, pdata->period_clock_ticks); + + /* trigger the task */ curr_task->state = SOF_TASK_STATE_RUNNING; k_sem_give(&pdata->sem); } - } else { - if (curr_task->state == SOF_TASK_STATE_QUEUED || - curr_task->state == SOF_TASK_STATE_RUNNING) - /* decrease num of ticks to re-schedule */ - pdata->ticks_to_trigger--; } } scheduler_dp_unlock(lock_key); @@ -103,6 +254,7 @@ void scheduler_dp_ll_tick(void *receiver_data, enum notify_id event_type, void * static int scheduler_dp_task_cancel(void *data, struct task *task) { unsigned int lock_key; + struct scheduler_dp_data *dp_sch = (struct scheduler_dp_data *)data; /* this is asyn cancel - mark the task as canceled and remove it from scheduling */ lock_key = scheduler_dp_lock(); @@ -110,6 +262,10 @@ static int scheduler_dp_task_cancel(void *data, struct task *task) task->state = SOF_TASK_STATE_CANCEL; list_item_del(&task->list); + /* if there're no more DP task, stop LL tick source */ + if (list_is_empty(&dp_sch->tasks)) + schedule_task_cancel(&dp_sch->ll_tick_src); + scheduler_dp_unlock(lock_key); return 0; @@ -117,18 +273,12 @@ static int scheduler_dp_task_cancel(void *data, struct task *task) static int scheduler_dp_task_free(void *data, struct task *task) { - unsigned int lock_key; struct task_dp_pdata *pdata = task->priv_data; + scheduler_dp_task_cancel(data, task); + /* abort the execution of the thread */ k_thread_abort(pdata->thread_id); - - lock_key = scheduler_dp_lock(); - list_item_del(&task->list); - task->priv_data = NULL; - task->state = SOF_TASK_STATE_FREE; - scheduler_dp_unlock(lock_key); - /* free task stack */ rfree((__sparse_force void *)pdata->p_stack); @@ -202,6 +352,7 @@ static int scheduler_dp_task_shedule(void *data, struct task *task, uint64_t sta struct scheduler_dp_data *dp_sch = (struct scheduler_dp_data *)data; struct task_dp_pdata *pdata = task->priv_data; unsigned int lock_key; + uint64_t period_clock_ticks; lock_key = scheduler_dp_lock(); @@ -212,27 +363,24 @@ static int scheduler_dp_task_shedule(void *data, struct task *task, uint64_t sta return -EINVAL; } - /* calculate period and start time in LL ticks */ - pdata->ticks_period = period / LL_TIMER_PERIOD_US; + /* if there's no DP tasks scheduled yet, run ll tick source task */ + if (list_is_empty(&dp_sch->tasks)) + schedule_task(&dp_sch->ll_tick_src, 0, 0); /* add a task to DP scheduler list */ + task->state = SOF_TASK_STATE_QUEUED; list_item_prepend(&task->list, &dp_sch->tasks); - if (start == SCHEDULER_DP_RUN_TASK_IMMEDIATELY) { - /* trigger the task immediately, don't wait for LL tick */ - pdata->ticks_to_trigger = 0; - task->state = SOF_TASK_STATE_RUNNING; - k_sem_give(&pdata->sem); - } else { - /* wait for tick */ - pdata->ticks_to_trigger = start / LL_TIMER_PERIOD_US; - task->state = SOF_TASK_STATE_QUEUED; - } + period_clock_ticks = period * CONFIG_SYS_CLOCK_TICKS_PER_SEC; + /* period is in us - convert to seconds in next step + * or it always will be zero because of fixed point calculation + */ + period_clock_ticks /= 1000000; + pdata->period_clock_ticks = period_clock_ticks; scheduler_dp_unlock(lock_key); - /* start LL task - run DP tick start and period are irrelevant for LL (that's bad)*/ - schedule_task(&dp_sch->task, 0, 0); + tr_dbg(&dp_tr, "DP task scheduled with period %u [us]", (uint32_t)period); return 0; } @@ -255,7 +403,7 @@ int scheduler_dp_init(void) scheduler_init(SOF_SCHEDULE_DP, &schedule_dp_ops, dp_sch); /* init src of DP tick */ - ret = schedule_task_init_ll(&dp_sch->task, + ret = schedule_task_init_ll(&dp_sch->ll_tick_src, SOF_UUID(dp_sched_uuid), SOF_SCHEDULE_LL_TIMER, 0, scheduler_dp_ll_tick_dummy, dp_sch, @@ -272,7 +420,7 @@ int scheduler_dp_init(void) int scheduler_dp_task_init(struct task **task, const struct sof_uuid_entry *uid, const struct task_ops *ops, - void *data, + struct processing_module *mod, uint16_t core, size_t stack_size, uint32_t task_priority) @@ -335,7 +483,7 @@ int scheduler_dp_task_init(struct task **task, /* internal SOF task init */ ret = schedule_task_init(&task_memory->task, uid, SOF_SCHEDULE_DP, 0, ops->run, - data, core, 0); + mod, core, 0); if (ret < 0) { tr_err(&dp_tr, "zephyr_dp_task_init(): schedule_task_init failed"); goto err; @@ -354,6 +502,7 @@ int scheduler_dp_task_init(struct task **task, task_memory->task.priv_data = &task_memory->pdata; task_memory->pdata.thread_id = thread_id; task_memory->pdata.p_stack = p_stack; + task_memory->pdata.mod = mod; *task = &task_memory->task; /* start the thread - it will immediately stop at a semaphore */ diff --git a/test/cmocka/src/audio/buffer/buffer_copy.c b/test/cmocka/src/audio/buffer/buffer_copy.c index 1983d92edfdf..be1500cb66f0 100644 --- a/test/cmocka/src/audio/buffer/buffer_copy.c +++ b/test/cmocka/src/audio/buffer/buffer_copy.c @@ -29,8 +29,8 @@ static void test_audio_buffer_copy_underrun(void **state) .size = 256 }; - struct comp_buffer *src = buffer_new(&test_buf_desc); - struct comp_buffer *snk = buffer_new(&test_buf_desc); + struct comp_buffer *src = buffer_new(&test_buf_desc, false); + struct comp_buffer *snk = buffer_new(&test_buf_desc, false); assert_non_null(src); assert_non_null(snk); @@ -56,8 +56,8 @@ static void test_audio_buffer_copy_overrun(void **state) .size = 256 }; - struct comp_buffer *src = buffer_new(&test_buf_desc); - struct comp_buffer *snk = buffer_new(&test_buf_desc); + struct comp_buffer *src = buffer_new(&test_buf_desc, false); + struct comp_buffer *snk = buffer_new(&test_buf_desc, false); assert_non_null(src); assert_non_null(snk); @@ -85,8 +85,8 @@ static void test_audio_buffer_copy_success(void **state) .size = 256 }; - struct comp_buffer *src = buffer_new(&test_buf_desc); - struct comp_buffer *snk = buffer_new(&test_buf_desc); + struct comp_buffer *src = buffer_new(&test_buf_desc, false); + struct comp_buffer *snk = buffer_new(&test_buf_desc, false); assert_non_null(src); assert_non_null(snk); @@ -111,8 +111,8 @@ static void test_audio_buffer_copy_fit_space_constraint(void **state) .size = 256 }; - struct comp_buffer *src = buffer_new(&test_buf_desc); - struct comp_buffer *snk = buffer_new(&test_buf_desc); + struct comp_buffer *src = buffer_new(&test_buf_desc, false); + struct comp_buffer *snk = buffer_new(&test_buf_desc, false); assert_non_null(src); assert_non_null(snk); @@ -139,8 +139,8 @@ static void test_audio_buffer_copy_fit_no_space_constraint(void **state) .size = 256 }; - struct comp_buffer *src = buffer_new(&test_buf_desc); - struct comp_buffer *snk = buffer_new(&test_buf_desc); + struct comp_buffer *src = buffer_new(&test_buf_desc, false); + struct comp_buffer *snk = buffer_new(&test_buf_desc, false); assert_non_null(src); assert_non_null(snk); diff --git a/test/cmocka/src/audio/buffer/buffer_new.c b/test/cmocka/src/audio/buffer/buffer_new.c index 2f78033a5fc1..e2ce0c274b57 100644 --- a/test/cmocka/src/audio/buffer/buffer_new.c +++ b/test/cmocka/src/audio/buffer/buffer_new.c @@ -27,7 +27,7 @@ static void test_audio_buffer_new(void **state) .size = 256 }; - struct comp_buffer *buf = buffer_new(&test_buf_desc); + struct comp_buffer *buf = buffer_new(&test_buf_desc, false); assert_non_null(buf); assert_int_equal(audio_stream_get_avail_bytes(&buf->stream), 0); diff --git a/test/cmocka/src/audio/buffer/buffer_wrap.c b/test/cmocka/src/audio/buffer/buffer_wrap.c index 210bce1a2ef0..b0c7d11ce555 100644 --- a/test/cmocka/src/audio/buffer/buffer_wrap.c +++ b/test/cmocka/src/audio/buffer/buffer_wrap.c @@ -27,7 +27,7 @@ static void test_audio_buffer_write_fill_10_bytes_and_write_5(void **state) .size = 10 }; - struct comp_buffer *buf = buffer_new(&test_buf_desc); + struct comp_buffer *buf = buffer_new(&test_buf_desc, false); assert_non_null(buf); assert_int_equal(audio_stream_get_avail_bytes(&buf->stream), 0); diff --git a/test/cmocka/src/audio/buffer/buffer_write.c b/test/cmocka/src/audio/buffer/buffer_write.c index 8c4fc185c2db..8c3e437d612a 100644 --- a/test/cmocka/src/audio/buffer/buffer_write.c +++ b/test/cmocka/src/audio/buffer/buffer_write.c @@ -28,7 +28,7 @@ static void test_audio_buffer_write_10_bytes_out_of_256_and_read_back .size = 256 }; - struct comp_buffer *buf = buffer_new(&test_buf_desc); + struct comp_buffer *buf = buffer_new(&test_buf_desc, false); assert_non_null(buf); assert_int_equal(audio_stream_get_avail_bytes(&buf->stream), 0); @@ -63,7 +63,7 @@ static void test_audio_buffer_fill_10_bytes(void **state) .size = 10 }; - struct comp_buffer *buf = buffer_new(&test_buf_desc); + struct comp_buffer *buf = buffer_new(&test_buf_desc, false); assert_non_null(buf); assert_int_equal(audio_stream_get_avail_bytes(&buf->stream), 0); diff --git a/test/cmocka/src/audio/eq_fir/CMakeLists.txt b/test/cmocka/src/audio/eq_fir/CMakeLists.txt index af9fa80d0b60..3369f2b97b06 100644 --- a/test/cmocka/src/audio/eq_fir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_fir/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(audio_for_eq_fir STATIC ${PROJECT_SOURCE_DIR}/src/math/fir_hifi3.c ${PROJECT_SOURCE_DIR}/src/math/numbers.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c + ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c diff --git a/test/cmocka/src/audio/eq_iir/CMakeLists.txt b/test/cmocka/src/audio/eq_iir/CMakeLists.txt index a72903d1c1df..8f00dbedc750 100644 --- a/test/cmocka/src/audio/eq_iir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_iir/CMakeLists.txt @@ -13,6 +13,8 @@ add_compile_options(-DUNIT_TEST) add_library(audio_for_eq_iir STATIC ${PROJECT_SOURCE_DIR}/src/audio/eq_iir/eq_iir.c + ${PROJECT_SOURCE_DIR}/src/audio/eq_iir/eq_iir_generic.c + ${PROJECT_SOURCE_DIR}/src/audio/eq_iir/eq_iir_ipc3.c ${PROJECT_SOURCE_DIR}/src/math/iir_df1.c ${PROJECT_SOURCE_DIR}/src/math/iir_df1_generic.c ${PROJECT_SOURCE_DIR}/src/math/iir_df1_hifi3.c @@ -21,6 +23,7 @@ add_library(audio_for_eq_iir STATIC ${PROJECT_SOURCE_DIR}/src/math/iir_df2t_hifi3.c ${PROJECT_SOURCE_DIR}/src/math/numbers.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c + ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c diff --git a/test/cmocka/src/audio/eq_iir/eq_iir_process.c b/test/cmocka/src/audio/eq_iir/eq_iir_process.c index b960a6997b14..529d4328f580 100644 --- a/test/cmocka/src/audio/eq_iir/eq_iir_process.c +++ b/test/cmocka/src/audio/eq_iir/eq_iir_process.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include "../../util.h" diff --git a/test/cmocka/src/audio/mixer/CMakeLists.txt b/test/cmocka/src/audio/mixer/CMakeLists.txt index e422dd6ebf96..01aebc99223e 100644 --- a/test/cmocka/src/audio/mixer/CMakeLists.txt +++ b/test/cmocka/src/audio/mixer/CMakeLists.txt @@ -11,6 +11,7 @@ cmocka_test(mixer ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c + ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c diff --git a/test/cmocka/src/audio/mux/CMakeLists.txt b/test/cmocka/src/audio/mux/CMakeLists.txt index 59e3752599fc..c6f67ae89127 100644 --- a/test/cmocka/src/audio/mux/CMakeLists.txt +++ b/test/cmocka/src/audio/mux/CMakeLists.txt @@ -23,6 +23,7 @@ add_library( ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c + ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ) sof_append_relative_path_definitions(audio_mux) diff --git a/test/cmocka/src/audio/volume/CMakeLists.txt b/test/cmocka/src/audio/volume/CMakeLists.txt index a1cd1fd8cab2..f6530bc2b3b0 100644 --- a/test/cmocka/src/audio/volume/CMakeLists.txt +++ b/test/cmocka/src/audio/volume/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(audio_for_volume STATIC ${PROJECT_SOURCE_DIR}/src/audio/volume/volume_hifi3_with_peakvol.c ${PROJECT_SOURCE_DIR}/src/audio/volume/volume_hifi4_with_peakvol.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c + ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c diff --git a/test/cmocka/src/common_mocks.c b/test/cmocka/src/common_mocks.c index 180c2028b019..630bdd0a0d13 100644 --- a/test/cmocka/src/common_mocks.c +++ b/test/cmocka/src/common_mocks.c @@ -41,6 +41,8 @@ WEAK struct tr_ctx buffer_tr; WEAK struct tr_ctx comp_tr; WEAK struct tr_ctx ipc_tr; +int host_trace_level = 1; + void WEAK *rballoc_align(uint32_t flags, uint32_t caps, size_t bytes, uint32_t alignment) { diff --git a/test/cmocka/src/math/fft/fft.c b/test/cmocka/src/math/fft/fft.c index 653212c7bfc2..cfb2ec8d98bb 100644 --- a/test/cmocka/src/math/fft/fft.c +++ b/test/cmocka/src/math/fft/fft.c @@ -265,8 +265,8 @@ static void test_math_fft_256(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 256 * 2 * sizeof(int32_t), }; - struct comp_buffer *source = buffer_new(&test_buf_desc); - struct comp_buffer *sink = buffer_new(&test_buf_desc); + struct comp_buffer *source = buffer_new(&test_buf_desc, false); + struct comp_buffer *sink = buffer_new(&test_buf_desc, false); struct icomplex32 *out = (struct icomplex32 *)sink->stream.addr; int32_t *in = (int32_t *)source->stream.addr; int fft_size = 256; @@ -307,8 +307,8 @@ static void test_math_fft_512(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 512 * 2 * sizeof(int32_t), }; - struct comp_buffer *source = buffer_new(&test_buf_desc); - struct comp_buffer *sink = buffer_new(&test_buf_desc); + struct comp_buffer *source = buffer_new(&test_buf_desc, false); + struct comp_buffer *sink = buffer_new(&test_buf_desc, false); struct icomplex32 *out = (struct icomplex32 *)sink->stream.addr; int32_t *in = (int32_t *)source->stream.addr; int fft_size = 512; @@ -349,8 +349,8 @@ static void test_math_fft_1024(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 1024 * 2 * sizeof(int32_t), }; - struct comp_buffer *source = buffer_new(&test_buf_desc); - struct comp_buffer *sink = buffer_new(&test_buf_desc); + struct comp_buffer *source = buffer_new(&test_buf_desc, false); + struct comp_buffer *sink = buffer_new(&test_buf_desc, false); struct icomplex32 *out = (struct icomplex32 *)sink->stream.addr; int32_t *in = (int32_t *)source->stream.addr; int fft_size = 1024; @@ -391,9 +391,9 @@ static void test_math_fft_1024_ifft(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 1024 * 4 * 2, }; - struct comp_buffer *source = buffer_new(&test_buf_desc); - struct comp_buffer *intm = buffer_new(&test_buf_desc); - struct comp_buffer *sink = buffer_new(&test_buf_desc); + struct comp_buffer *source = buffer_new(&test_buf_desc, false); + struct comp_buffer *intm = buffer_new(&test_buf_desc, false); + struct comp_buffer *sink = buffer_new(&test_buf_desc, false); struct icomplex32 *out = (struct icomplex32 *)sink->stream.addr; float db; int64_t signal = 0; @@ -432,9 +432,9 @@ static void test_math_fft_512_2ch(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 512 * 4 * 2, }; - struct comp_buffer *source = buffer_new(&test_buf_desc); - struct comp_buffer *sink1 = buffer_new(&test_buf_desc); - struct comp_buffer *sink2 = buffer_new(&test_buf_desc); + struct comp_buffer *source = buffer_new(&test_buf_desc, false); + struct comp_buffer *sink1 = buffer_new(&test_buf_desc, false); + struct comp_buffer *sink2 = buffer_new(&test_buf_desc, false); struct icomplex32 *out1 = (struct icomplex32 *)sink1->stream.addr; struct icomplex32 *out2 = (struct icomplex32 *)sink2->stream.addr; uint32_t fft_size = 512; @@ -625,8 +625,8 @@ static void test_math_fft_256_16(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 256 * 2 * sizeof(int16_t), }; - struct comp_buffer *source = buffer_new(&test_buf_desc); - struct comp_buffer *sink = buffer_new(&test_buf_desc); + struct comp_buffer *source = buffer_new(&test_buf_desc, false); + struct comp_buffer *sink = buffer_new(&test_buf_desc, false); struct icomplex16 *out = (struct icomplex16 *)sink->stream.addr; int16_t *in = (int16_t *)source->stream.addr; int fft_size = 256; @@ -667,8 +667,8 @@ static void test_math_fft_512_16(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 512 * 2 * sizeof(int16_t), }; - struct comp_buffer *source = buffer_new(&test_buf_desc); - struct comp_buffer *sink = buffer_new(&test_buf_desc); + struct comp_buffer *source = buffer_new(&test_buf_desc, false); + struct comp_buffer *sink = buffer_new(&test_buf_desc, false); struct icomplex16 *out = (struct icomplex16 *)sink->stream.addr; int16_t *in = (int16_t *)source->stream.addr; int fft_size = 512; @@ -709,8 +709,8 @@ static void test_math_fft_1024_16(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 1024 * 2 * sizeof(int16_t), }; - struct comp_buffer *source = buffer_new(&test_buf_desc); - struct comp_buffer *sink = buffer_new(&test_buf_desc); + struct comp_buffer *source = buffer_new(&test_buf_desc, false); + struct comp_buffer *sink = buffer_new(&test_buf_desc, false); struct icomplex16 *out = (struct icomplex16 *)sink->stream.addr; int16_t *in = (int16_t *)source->stream.addr; int fft_size = 1024; @@ -751,9 +751,9 @@ static void test_math_fft_1024_ifft_16(void **state) struct sof_ipc_buffer test_buf_desc = { .size = 1024 * 2 * sizeof(int16_t), }; - struct comp_buffer *source = buffer_new(&test_buf_desc); - struct comp_buffer *intm = buffer_new(&test_buf_desc); - struct comp_buffer *sink = buffer_new(&test_buf_desc); + struct comp_buffer *source = buffer_new(&test_buf_desc, false); + struct comp_buffer *intm = buffer_new(&test_buf_desc, false); + struct comp_buffer *sink = buffer_new(&test_buf_desc, false); struct icomplex16 *out = (struct icomplex16 *)sink->stream.addr; float db; int64_t signal = 0; diff --git a/test/cmocka/src/util.h b/test/cmocka/src/util.h index be540359395c..5ef231ceba64 100644 --- a/test/cmocka/src/util.h +++ b/test/cmocka/src/util.h @@ -23,7 +23,7 @@ static inline struct comp_buffer *create_test_sink(struct comp_dev *dev, }, .size = buffer_size, }; - struct comp_buffer *buffer = buffer_new(&desc); + struct comp_buffer *buffer = buffer_new(&desc, false); memset(buffer->stream.addr, 0, buffer_size); @@ -58,7 +58,7 @@ static inline struct comp_buffer *create_test_source(struct comp_dev *dev, }, .size = buffer_size, }; - struct comp_buffer *buffer = buffer_new(&desc); + struct comp_buffer *buffer = buffer_new(&desc, false); memset(buffer->stream.addr, 0, buffer_size); diff --git a/tools/logger/CMakeLists.txt b/tools/logger/CMakeLists.txt index 0c7b2d8d914b..271f54e559c9 100644 --- a/tools/logger/CMakeLists.txt +++ b/tools/logger/CMakeLists.txt @@ -35,7 +35,7 @@ target_compile_options(sof-logger PRIVATE target_include_directories(sof-logger PRIVATE "${SOF_ROOT_SOURCE_DIRECTORY}/src/include" - "${SOF_ROOT_SOURCE_DIRECTORY}/rimage/src/include" + "${SOF_ROOT_SOURCE_DIRECTORY}/tools/rimage/src/include" "${SOF_ROOT_SOURCE_DIRECTORY}" ) diff --git a/tools/logger/convert.c b/tools/logger/convert.c index 417d3ee6e8b4..e393f828e1b1 100644 --- a/tools/logger/convert.c +++ b/tools/logger/convert.c @@ -60,8 +60,7 @@ struct proc_ldc_entry { uintptr_t params[TRACE_MAX_PARAMS_COUNT]; }; -static const char *BAD_PTR_STR = ""; - +#define BAD_PTR_STR "" #define UUID_LOWER "%s%s%s<%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x>%s%s%s" #define UUID_UPPER "%s%s%s<%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X>%s%s%s" @@ -325,7 +324,7 @@ static unsigned int timestamp_width(unsigned int precision) * gcc 9.3, this avoids a very long precision causing snprintf() * to truncate time_fmt */ - assert(precision >= 0 && precision < 20); + assert(precision < 20); /* * 12 digits for units is enough for 1M seconds = 11 days which * should be enough for most test runs. @@ -339,7 +338,6 @@ static inline void print_table_header(void) { FILE *out_fd = global_config->out_fd; int hide_location = global_config->hide_location; - char time_fmt[32]; char date_string[64]; const time_t epoc_secs = time(NULL); @@ -349,16 +347,14 @@ static inline void print_table_header(void) if (gettime_ret) { log_err("clock_gettime() failed: %s\n", - strerror(gettime_ret)); + strerror(errno)); exit(1); } if (global_config->time_precision >= 0) { - const unsigned int ts_width = - timestamp_width(global_config->time_precision); - snprintf(time_fmt, sizeof(time_fmt), "%%-%ds(us)%%%ds ", - ts_width, ts_width); - fprintf(out_fd, time_fmt, " TIMESTAMP", "DELTA"); + const unsigned int ts_width = timestamp_width(global_config->time_precision); + + fprintf(out_fd, "%*s(us)%*s ", -ts_width, " TIMESTAMP", ts_width, "DELTA"); } fprintf(out_fd, "%2s %-18s ", "C#", "COMPONENT"); @@ -476,7 +472,6 @@ static void print_entry_params(const struct log_entry_header *dma_log, char ids[TRACE_MAX_IDS_STR]; float dt = to_usecs(dma_log->timestamp - last_timestamp); struct proc_ldc_entry proc_entry; - static char time_fmt[64]; int ret; if (raw_output) @@ -517,13 +512,7 @@ static void print_entry_params(const struct log_entry_header *dma_log, ids[0] = '\0'; if (raw_output) { /* "raw" means script-friendly (not all hex) */ - const char *entry_fmt = "%s%u %u %s%s%s "; - - if (time_precision >= 0) - snprintf(time_fmt, sizeof(time_fmt), "%%.%df %%.%df ", - time_precision, time_precision); - - fprintf(out_fd, entry_fmt, + fprintf(out_fd, "%s%u %u %s%s%s ", entry->header.level == use_colors ? (LOG_LEVEL_CRITICAL ? KRED : KNRM) : "", dma_log->core_id, @@ -531,9 +520,12 @@ static void print_entry_params(const struct log_entry_header *dma_log, get_component_name(entry->header.component_class, dma_log->uid), raw_output && strlen(ids) ? "-" : "", ids); + if (time_precision >= 0) - fprintf(out_fd, time_fmt, - to_usecs(dma_log->timestamp - timestamp_origin), dt); + fprintf(out_fd, "%.*f %.*f ", + time_precision, to_usecs(dma_log->timestamp - timestamp_origin), + time_precision, dt); + if (!hide_location) fprintf(out_fd, "(%s:%u) ", format_file_name(entry->file_name, raw_output), @@ -542,13 +534,11 @@ static void print_entry_params(const struct log_entry_header *dma_log, if (time_precision >= 0) { const unsigned int ts_width = timestamp_width(time_precision); - snprintf(time_fmt, sizeof(time_fmt), - "%%s[%%%d.%df] (%%%d.%df)%%s ", - ts_width, time_precision, ts_width, time_precision); - - fprintf(out_fd, time_fmt, + fprintf(out_fd, "%s[%*.*f] (%*.*f)%s ", use_colors ? KGRN : "", - to_usecs(dma_log->timestamp - timestamp_origin), dt, + ts_width, time_precision, + to_usecs(dma_log->timestamp - timestamp_origin), + ts_width, time_precision, dt, use_colors ? KNRM : ""); } @@ -624,7 +614,13 @@ static int read_entry_from_ldc_file(struct ldc_entry *entry, uint32_t log_entry_ entry->params = NULL; /* set file position to beginning of processed entry */ - fseek(global_config->ldc_fd, entry_offset, SEEK_SET); + ret = fseek(global_config->ldc_fd, entry_offset, SEEK_SET); + if (ret) { + log_err("Failed to seek to entry header for offset 0x%x in dictionary.\n", + entry_offset); + ret = -errno; + goto out; + } /* fetching elf header params */ ret = fread(&entry->header, sizeof(entry->header), 1, global_config->ldc_fd); @@ -640,7 +636,7 @@ static int read_entry_from_ldc_file(struct ldc_entry *entry, uint32_t log_entry_ ret = -EINVAL; goto out; } - entry->file_name = (char *)malloc(entry->header.file_name_len); + entry->file_name = (char *)malloc(entry->header.file_name_len + 1); if (!entry->file_name) { log_err("can't allocate %d byte for entry.file_name\n", @@ -651,6 +647,8 @@ static int read_entry_from_ldc_file(struct ldc_entry *entry, uint32_t log_entry_ ret = fread(entry->file_name, sizeof(char), entry->header.file_name_len, global_config->ldc_fd); + entry->file_name[entry->header.file_name_len] = '\0'; + if (ret != entry->header.file_name_len) { log_err("Failed to read source filename for offset 0x%x in dictionary.\n", entry_offset); @@ -664,7 +662,7 @@ static int read_entry_from_ldc_file(struct ldc_entry *entry, uint32_t log_entry_ ret = -EINVAL; goto out; } - entry->text = (char *)malloc(entry->header.text_len); + entry->text = (char *)malloc(entry->header.text_len + 1); if (!entry->text) { log_err("can't allocate %d byte for entry.text\n", entry->header.text_len); ret = -ENOMEM; @@ -677,6 +675,7 @@ static int read_entry_from_ldc_file(struct ldc_entry *entry, uint32_t log_entry_ ret = -1; goto out; } + entry->text[entry->header.text_len] = '\0'; return 0; @@ -915,8 +914,13 @@ static int logger_read(void) /* When the address is not correct, move forward by one DWORD (not * entire struct dma_log) */ - fseek(global_config->in_fd, -(sizeof(dma_log) - sizeof(uint32_t)), - SEEK_CUR); + ret = fseek(global_config->in_fd, -(sizeof(dma_log) - sizeof(uint32_t)), + SEEK_CUR); + if (ret) { + log_err("fetch_entry() failed on seek, aborting\n"); + ret = -errno; + break; + } skipped_dwords++; continue; @@ -1013,7 +1017,7 @@ static int dump_ldc_info(void) if (global_config->version_fd) { struct sof_ipc_fw_version ver; - if (fread(&ver, sizeof(ver), 1, global_config->version_fd)) + if (fread(&ver, sizeof(ver), 1, global_config->version_fd) == 1) fprintf(out_fd, "Loaded FW expects checksum\t0x%08x\n", ver.src_hash); } @@ -1101,7 +1105,12 @@ int convert(void) } /* read uuid section header */ - fseek(config->ldc_fd, logs_hdr->data_offset + logs_hdr->data_length, SEEK_SET); + ret = fseek(config->ldc_fd, logs_hdr->data_offset + logs_hdr->data_length, SEEK_SET); + if (ret) { + log_err("Error while seeking to uuids header from %s.\n", config->ldc_file); + return -errno; + } + count = fread(&uids_hdr, sizeof(uids_hdr), 1, config->ldc_fd); if (!count) { log_err("Error while reading uuids header from %s.\n", config->ldc_file); diff --git a/tools/logger/logger.c b/tools/logger/logger.c index 14f3fc88f657..b6c2b26bd629 100644 --- a/tools/logger/logger.c +++ b/tools/logger/logger.c @@ -104,8 +104,8 @@ static int snapshot(const char *name) for (i = 0; i < ARRAY_SIZE(debugfs); i++) { - sprintf(pinname, "%s/%s", path, debugfs[i]); - sprintf(poutname, "%s.%s.txt", name, debugfs[i]); + snprintf(pinname, sizeof(pinname), "%s/%s", path, debugfs[i]); + snprintf(poutname, sizeof(poutname), "%s.%s.txt", name, debugfs[i]); /* open debugfs for reading */ in_fd = fopen(pinname, "rb"); @@ -132,9 +132,14 @@ static int snapshot(const char *name) if (count != 4) break; - sprintf(buffer, "0x%6.6x: 0x%8.8x\n", addr, val); + snprintf(buffer, sizeof(buffer), "0x%6.6x: 0x%8.8x\n", addr, val); - count = fwrite(buffer, 1, strlen(buffer), out_fd); + i = strlen(buffer); + count = fwrite(buffer, 1, i, out_fd); + if (count != i) { + fprintf(stderr, "error: an error occurred during write to %s: %s\n", + poutname, strerror(errno)); + } addr += 4; } @@ -164,7 +169,12 @@ static int configure_uart(const char *file, unsigned int baud) tio.c_cc[VMIN] = 1; ret = tcsetattr(fd, TCSANOW, &tio); - return ret < 0 ? -errno : fd; + if (ret < 0) { + close(fd); + return -errno; + } + + return fd; } /* Concantenate `config->filter_config` with `input` + `\n` */ @@ -220,17 +230,15 @@ static void *wait_open(const char *watched_dir, const char *expected_file) const int dwatch = inotify_add_watch(iqueue, watched_dir, IN_CREATE); struct stat expected_stat; void *ret_stream = NULL; - - char * const fpath = malloc(strlen(watched_dir) + 1 + strlen(expected_file) + 1); + const int fpath_len = strlen(watched_dir) + 1 + strlen(expected_file) + 1; + char * const fpath = malloc(fpath_len); if (!fpath) { fprintf(stderr, "error: can't allocate memory\n"); exit(EXIT_FAILURE); } - strcpy(fpath, watched_dir); - strcat(fpath, "/"); - strcat(fpath, expected_file); + snprintf(fpath, fpath_len, "%s/%s", watched_dir, expected_file); /* Not racy because the inotify watch was set first. */ if (!access(fpath, F_OK)) @@ -268,7 +276,9 @@ static void *wait_open(const char *watched_dir, const char *expected_file) } fopenit: - stat(fpath, &expected_stat); + if (stat(fpath, &expected_stat)) + goto cleanup; + if ((expected_stat.st_mode & S_IFMT) == S_IFDIR) ret_stream = opendir(fpath); else @@ -364,7 +374,8 @@ int main(int argc, char *argv[]) if (i < 0 || 1 < i) { fprintf(stderr, "%s: invalid option: -e %s\n", APP_NAME, optarg); - return -EINVAL; + ret = -EINVAL; + goto out; } config.relative_timestamps = i; break; @@ -373,7 +384,8 @@ int main(int argc, char *argv[]) config.time_precision = atoi(optarg); if (config.time_precision < 0) { usage(); - return -EINVAL; + ret = -EINVAL; + goto out; } break; case 'g': @@ -403,8 +415,10 @@ int main(int argc, char *argv[]) usage(); } - if (snapshot_file) - return baud ? EINVAL : -snapshot(snapshot_file); + if (snapshot_file) { + ret = baud ? EINVAL : -snapshot(snapshot_file); + goto out; + } if (!config.ldc_file) { fprintf(stderr, "error: Missing ldc file\n"); diff --git a/tools/plugin/CMakeLists.txt b/tools/plugin/CMakeLists.txt new file mode 100644 index 000000000000..f5a8ade5f8cc --- /dev/null +++ b/tools/plugin/CMakeLists.txt @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.13) + +project(SOF_PLUGIN C) + +include(../../scripts/cmake/misc.cmake) +include(CheckCCompilerFlag) + +set(sof_source_directory "${PROJECT_SOURCE_DIR}/../..") +set(sof_install_directory "${PROJECT_BINARY_DIR}/sof_ep/install") +set(sof_binary_directory "${PROJECT_BINARY_DIR}/sof_ep/build") + +set(config_h ${sof_binary_directory}/library_autoconfig.h) + +set(parser_source_directory "${PROJECT_SOURCE_DIR}/../tplg_parser") +set(parser_install_dir "${PROJECT_BINARY_DIR}/sof_parser/install") + +message("ipc4 build") +set(tplg_ipc plugin_ipc4_defconfig) + +include(ExternalProject) + +# External project for SOF library +ExternalProject_Add(sof_ep + DOWNLOAD_COMMAND "" + SOURCE_DIR "${sof_source_directory}" + PREFIX "${PROJECT_BINARY_DIR}/sof_ep" + BINARY_DIR "${sof_binary_directory}" + CMAKE_ARGS -DCONFIG_LIBRARY=ON + -DCMAKE_INSTALL_PREFIX=${sof_install_directory} + -DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE} + -DINIT_CONFIG=${tplg_ipc} + -DCONFIG_H_PATH=${config_h} + -DCONFIG_LIBRARY_STATIC=ON + -DOPTIMIZE_FOR_DEBUG=ON + BUILD_ALWAYS 1 + BUILD_BYPRODUCTS "${sof_install_directory}/lib/libsof.a" +) + +add_library(sof_library STATIC IMPORTED) +set_target_properties(sof_library PROPERTIES IMPORTED_LOCATION "${sof_install_directory}/lib/libsof.a") +add_dependencies(sof_library sof_ep) + +# External project for topology parser +ExternalProject_Add(parser_ep + SOURCE_DIR "${parser_source_directory}" + PREFIX "${PROJECT_BINARY_DIR}/sof_parser" + BINARY_DIR "${PROJECT_BINARY_DIR}/sof_parser/build" + CMAKE_ARGS -DCONFIG_LIBRARY=ON + -DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/sof_parser/install + -DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE} + -DCONFIG_LIBRARY_STATIC=ON + -DOPTIMIZE_FOR_DEBUG=ON + BUILD_ALWAYS 1 + BUILD_BYPRODUCTS "${parser_install_dir}/lib/libsof_tplg_parser.a" +) + +add_library(sof_parser_lib STATIC IMPORTED) +set_target_properties(sof_parser_lib PROPERTIES IMPORTED_LOCATION "${parser_install_dir}/lib/libsof_tplg_parser.a") +add_dependencies(sof_parser_lib parser_ep) + +add_subdirectory(alsaconf) +add_subdirectory(alsaplug) +add_subdirectory(modules) +add_subdirectory(pipe) + +add_dependencies(asound_module_pcm_sof sof_parser_lib) +add_dependencies(asound_module_ctl_sof sof_parser_lib) + +add_dependencies(sof-pipe sof_mod_shm) +add_dependencies(sof-pipe sof_mod_alsa) diff --git a/tools/plugin/README.md b/tools/plugin/README.md new file mode 100644 index 000000000000..0d4822388e70 --- /dev/null +++ b/tools/plugin/README.md @@ -0,0 +1,83 @@ +##ALSA Plugin + +The SOF ALSA plugin allows SOF topologies to be run on the host. The plugin +is still WIP with many rough edges that need refined before production +deployment, however the plugin is usable today as a rapid development +framework for SOF infrastructure and processing. + +#Features + * aplay & arecord usage working today + * alsamixer & amixer usage not working today + * modules are loaded as SO shared libraries. + * topology is parsed by the plugin and pipelines associated with the requested PCM ID are loaded + * pipelines run as individual userspace threads + * pipelines can be pinned to efficency cores + * pipelines can use realtime priority. + * alsa sink and alsa source modules available. + * pipelines can block (non blocking and mmap todo) + +#License +Code is a mixture of LGPL and BSD 3c. + +#Usage +Please build as cmake project, for IPC4 (functional) +IPC3 is not functional and not supported + +``` +cd sof +mkdir build_plugin +cd build_plugin +cmake ../tools/plugin -DPLUGIN_IPC4=ON +``` +then (use default ALSA prefix atm) + +``` +sudo make install + +Make sure to set the LD_LIBRARY_PATH to include directory where the SOF modules are installed +Ex: "~/work/sof/sof/build_plugin/sof_ep/install/lib:~/work/sof/sof/build_plugin/modules/" +And set the environment variable SOF_PLUGIN_TOPOLOGY_PATH to point to the directory containing the topology binary +``` + +Code can then be run by starting sof-pipe with your desired topology + +``` + ./sof-pipe -T sof-tgl-nocodec.tplg +``` + +At this point the sof-pipe daemon is waiting for IPC. Audio applications can now invoke sof-pipe processing via + +``` +aplay -Dsof:tgl-nocodec:1:default:default:48k2c16b -f dat some48kHz.wav +``` +The command line is parsed as follows: +- "sof" is the plugin name +- "tgl-nocodec" is the topology name. The "sof-" prefix and ".tplg" suffix will be appended by the plugin +- "1" is the PCM ID for render/capture +- "default": The first default is the card name +- "default": The second default is the device name +- "48k2c16b" is the config name for 48K, stereo, 16bit + +This renders audio to the sof-pipe daemon using the tgl-nocodec topology playback PCM ID 1. +The above example needs to be 48k as example pipe has no SRC/ASRC. + +Likewise + +``` +arecord -Dsof:tgl-nocodec:1:default:default:48k2c16b -f dat file.wav +``` +Will record audio using the tgl-nocodec topology and PCM ID 1. + +Mixer settings can be adjusted for bdw-nocodec by (Not functional yet) + +``` +alsamixer -Dsof:tgl-nocodec:1 +``` + +#TODO Items (and T-shirt size) for single pipeline E2E audio + * IPC4 support in tplg parser (M) + * IPC4 support in plugin (pipe/ipc4.c) (M) + * Fix ALSA -Dhw: device support (S), currently only default ALSA device works + * Deprecate POSIX message queues for IPC and use UNIX sockets.(S) + * Make better build system for modules i.e. remove hack-install.sh (S) + * Need a simpler aplay/arecord cmd line. diff --git a/tools/plugin/alsaconf/50-sof.conf b/tools/plugin/alsaconf/50-sof.conf new file mode 100644 index 000000000000..4d0232ecc596 --- /dev/null +++ b/tools/plugin/alsaconf/50-sof.conf @@ -0,0 +1,84 @@ +# Invoke a SOF pipeline and route it to a sound card or another plugin +# To use the PCM 0 on the SOF "volume" topology and route it to hw:1,2 then run +# aplay -Dsof:volume:0,hw,1,2 +# tplg:pipe:[pipe:card:dev:config[pipe:card:dev:config]...] +# +# TPLG SOF topology configuration (mandatory) + +pcm.sof { + @args [ TPLG ] + @args.TPLG { + type string + default "passthrough" + } + + type sof + tplg $TPLG + + hint { + show { + @func refer + name defaults.namehint.basic + } + description "SOF Topology and PCM" + } + + config.48k2c16b { + rate 48000 + channels 2 + format S16_LE + period_time 0 + period_frames 48 + buffer_time 0 + buffer_frames 192 + } + + config.48k8c16b { + rate 48000 + channels 8 + format S16_LE + period_time 0 + period_frames 1024 + buffer_time 0 + buffer_frames 5120 + } + + config.8k8c16b { + rate 8000 + channels 8 + format S16_LE + period_time 0 + period_frames 1024 + buffer_time 0 + buffer_frames 5120 + } + + config.48k2c32b { + rate 48000 + channels 2 + format S32_LE + period_time 0 + period_frames 6000 + buffer_time 0 + buffer_frames 24000 + } +} + +ctl.sof { + @args [ TPLG ] + @args.TPLG { + type string + default "passthrough" + } + + type sof + tplg $TPLG + + hint { + show { + @func refer + name defaults.namehint.basic + } + description "SOF Topology" + } +} diff --git a/tools/plugin/alsaconf/CMakeLists.txt b/tools/plugin/alsaconf/CMakeLists.txt new file mode 100644 index 000000000000..3a58c514f522 --- /dev/null +++ b/tools/plugin/alsaconf/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: BSD-3-Clause + +install(FILES 50-sof.conf DESTINATION /usr/share/alsa/alsa.conf.d) +# HACK needs to link to above +install(FILES 50-sof.conf DESTINATION /etc/alsa/conf.d) diff --git a/tools/plugin/alsaplug/CMakeLists.txt b/tools/plugin/alsaplug/CMakeLists.txt new file mode 100644 index 000000000000..c982d90d6106 --- /dev/null +++ b/tools/plugin/alsaplug/CMakeLists.txt @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: BSD-3-Clause + +# PCM ALSA module +add_library(asound_module_pcm_sof MODULE + pcm.c + plugin.c + ../common.c + tplg.c +) + +sof_append_relative_path_definitions(asound_module_pcm_sof) + +target_include_directories(asound_module_pcm_sof PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${sof_source_directory}/src/audio) + +target_compile_options(asound_module_pcm_sof PRIVATE -DPIC -g -O3 -Wl,-EL -Wmissing-prototypes + -Wimplicit-fallthrough -DCONFIG_LIBRARY -imacros${config_h}) + +install(TARGETS asound_module_pcm_sof DESTINATION /usr/lib/x86_64-linux-gnu/alsa-lib) + +target_link_options(asound_module_pcm_sof PRIVATE -Wl,--export-dynamic,--no-undefined) +target_link_libraries(asound_module_pcm_sof PRIVATE sof_library) +target_link_libraries(asound_module_pcm_sof PRIVATE sof_parser_lib) +target_link_libraries(asound_module_pcm_sof PRIVATE pthread) +target_link_libraries(asound_module_pcm_sof PRIVATE -lasound -ldl -lm -lasound -lrt) + +target_include_directories(asound_module_pcm_sof PRIVATE ${sof_install_directory}/include) +target_include_directories(asound_module_pcm_sof PRIVATE ${parser_install_dir}/include) + +set_target_properties(asound_module_pcm_sof + PROPERTIES + INSTALL_RPATH "${sof_install_directory}/alsa-lib" + INSTALL_RPATH_USE_LINK_PATH TRUE +) + +# CTL ALSA module +add_library(asound_module_ctl_sof MODULE + ctl.c + plugin.c + ../common.c +) +sof_append_relative_path_definitions(asound_module_ctl_sof) +target_include_directories(asound_module_ctl_sof PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${sof_source_directory}/src/audio) + +target_compile_options(asound_module_ctl_sof PRIVATE -DPIC -g -O3 -Wl,-EL -Wmissing-prototypes + -Wimplicit-fallthrough -Wall -Werror -DCONFIG_LIBRARY -imacros${config_h}) + +install(TARGETS asound_module_ctl_sof DESTINATION /usr/lib/x86_64-linux-gnu/alsa-lib) + +target_link_options(asound_module_ctl_sof PRIVATE -Wl,--export-dynamic,--no-undefined) +target_link_libraries(asound_module_ctl_sof PRIVATE sof_library) +target_link_libraries(asound_module_ctl_sof PRIVATE sof_parser_lib) +target_link_libraries(asound_module_ctl_sof PRIVATE pthread) +target_link_libraries(asound_module_ctl_sof PRIVATE -lasound -ldl -lm -lasound -lrt) + +target_include_directories(asound_module_ctl_sof PRIVATE ${sof_install_directory}/include) +target_include_directories(asound_module_ctl_sof PRIVATE ${parser_install_dir}/include) + +set_target_properties(asound_module_ctl_sof + PROPERTIES + INSTALL_RPATH "${sof_install_directory}/alsa-lib" + INSTALL_RPATH_USE_LINK_PATH TRUE +) diff --git a/tools/plugin/alsaplug/conf.c b/tools/plugin/alsaplug/conf.c new file mode 100644 index 000000000000..5b259bf6885a --- /dev/null +++ b/tools/plugin/alsaplug/conf.c @@ -0,0 +1,47 @@ +/*-*- linux-c -*-*/ + +/* + * ALSA <-> SOF Config plugin + * + * Copyright(c) 2022 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + */ + +#include +#include +#include "plugin.h" + +/* Not actually part of the alsa api.... */ +extern int +snd_config_hook_load(snd_config_t *root, snd_config_t *config, + snd_config_t **dst, snd_config_t *private_data); + +/* manifest file could be loaded as a hook */ +int sofplug_load_hook(snd_config_t *root, snd_config_t *config, + snd_config_t **dst, snd_config_t *private_data) +{ + int ret = 0; + + *dst = NULL; + + /* TODO: load hook when SOF ready */ + return snd_config_hook_load(root, config, dst, private_data); +} + +SND_DLSYM_BUILD_VERSION(sofplug_load_hook, + SND_CONFIG_DLSYM_VERSION_HOOK); diff --git a/tools/plugin/alsaplug/ctl.c b/tools/plugin/alsaplug/ctl.c new file mode 100644 index 000000000000..7e4f34e4cbda --- /dev/null +++ b/tools/plugin/alsaplug/ctl.c @@ -0,0 +1,685 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. +// +// Author: Liam Girdwood + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// TODO remove parsing and read ctls from sof-pipe SHM glb context +#include + +#include +#include + +#include "plugin.h" +#include "common.h" + +typedef struct snd_sof_ctl { + struct plug_shm_glb_state *glb; + snd_ctl_ext_t ext; + struct plug_mq_desc ipc; + struct plug_shm_desc shm_ctx; + int subscribed; + int updated[MAX_CTLS]; + +} snd_sof_ctl_t; + +#define CTL_GET_TPLG_HDR(_ctl, _key) \ + (&_ctl->glb->ctl[_key].mixer_ctl.hdr) + +#define CTL_GET_TPLG_MIXER(_ctl, _key) \ + (&_ctl->glb->ctl[_key].mixer_ctl) + +#define CTL_GET_TPLG_ENUM(_ctl, _key) \ + (&_ctl->glb->ctl[_key].enum_ctl) + +#define CTL_GET_TPLG_BYTES(_ctl, _key) \ + (&_ctl->glb->ctl[_key].bytes_ctl) + +/* number of ctls */ +static int plug_ctl_elem_count(snd_ctl_ext_t *ext) +{ + snd_sof_ctl_t *ctl = ext->private_data; + + /* TODO: get count of elems from topology */ + return ctl->glb->num_ctls; +} + +static int plug_ctl_elem_list(snd_ctl_ext_t *ext, unsigned int offset, snd_ctl_elem_id_t *id) +{ + snd_sof_ctl_t *ctl = ext->private_data; + struct snd_soc_tplg_ctl_hdr *hdr; + + if (offset >= ctl->glb->num_ctls) + return -EINVAL; + + hdr = CTL_GET_TPLG_HDR(ctl, offset); + + snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); + snd_ctl_elem_id_set_name(id, hdr->name); + + return 0; +} + +static snd_ctl_ext_key_t plug_ctl_find_elem(snd_ctl_ext_t *ext, const snd_ctl_elem_id_t *id) +{ + snd_sof_ctl_t *ctl = ext->private_data; + unsigned int numid; + + numid = snd_ctl_elem_id_get_numid(id); + + if (numid > ctl->glb->num_ctls) + return SND_CTL_EXT_KEY_NOT_FOUND; + + return numid - 1; +} + +static int plug_ctl_get_attribute(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, + int *type, unsigned int *acc, unsigned int *count) +{ + snd_sof_ctl_t *ctl = ext->private_data; + struct snd_soc_tplg_ctl_hdr *hdr = CTL_GET_TPLG_HDR(ctl, key); + struct snd_soc_tplg_mixer_control *mixer_ctl; + struct snd_soc_tplg_enum_control *enum_ctl; + struct snd_soc_tplg_bytes_control *bytes_ctl; + int err = 0; + + switch (hdr->type) { + case SND_SOC_TPLG_CTL_VOLSW: + case SND_SOC_TPLG_CTL_VOLSW_SX: + case SND_SOC_TPLG_CTL_VOLSW_XR_SX: + mixer_ctl = (struct snd_soc_tplg_mixer_control *)hdr; + + /* check for type - boolean should be binary values */ + if (mixer_ctl->max == 1 && mixer_ctl->min == 0) + *type = SND_CTL_ELEM_TYPE_BOOLEAN; + else + *type = SND_CTL_ELEM_TYPE_INTEGER; + *count = 2;//mixer_ctl->num_channels; ///// WRONG is 0 !!! + + //printf("mixer %d %d\n", __LINE__, mixer_ctl->num_channels); + break; + case SND_SOC_TPLG_CTL_ENUM: + case SND_SOC_TPLG_CTL_ENUM_VALUE: + enum_ctl = (struct snd_soc_tplg_enum_control *)hdr; + *type = SND_CTL_ELEM_TYPE_ENUMERATED; + *count = enum_ctl->num_channels; + break; + case SND_SOC_TPLG_CTL_RANGE: + case SND_SOC_TPLG_CTL_STROBE: + // TODO: ?? + break; + case SND_SOC_TPLG_CTL_BYTES: + printf("%s %d\n", __func__, __LINE__); + bytes_ctl = (struct snd_soc_tplg_bytes_control *)hdr; + *type = SND_CTL_ELEM_TYPE_BYTES; + *count = bytes_ctl->size; // Not sure if size is correct + break; + } + + *acc = hdr->access; + + /* access needs the callback to decode the data */ + if ((hdr->access & SND_CTL_EXT_ACCESS_TLV_READ) || + (hdr->access & SND_CTL_EXT_ACCESS_TLV_WRITE)) + *acc |= SND_CTL_EXT_ACCESS_TLV_CALLBACK; + return err; +} + +/* + * Integer ops + */ +static int plug_ctl_get_integer_info(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, long *imin, + long *imax, long *istep) +{ + snd_sof_ctl_t *ctl = ext->private_data; + struct snd_soc_tplg_ctl_hdr *hdr = CTL_GET_TPLG_HDR(ctl, key); + struct snd_soc_tplg_mixer_control *mixer_ctl = + CTL_GET_TPLG_MIXER(ctl, key); + int err = 0; + + switch (hdr->type) { + case SND_SOC_TPLG_CTL_VOLSW: + case SND_SOC_TPLG_CTL_VOLSW_SX: + case SND_SOC_TPLG_CTL_VOLSW_XR_SX: + /* TLV uses the fields differently */ + if ((hdr->access & SND_CTL_EXT_ACCESS_TLV_READ) || + (hdr->access & SND_CTL_EXT_ACCESS_TLV_WRITE)) { + *istep = mixer_ctl->hdr.tlv.scale.step; + *imin = (int32_t)mixer_ctl->hdr.tlv.scale.min; + *imax = mixer_ctl->max; + } else { + *istep = 1; + *imin = mixer_ctl->min; + *imax = mixer_ctl->max; + } + break; + default: + SNDERR("invalid ctl type for integer using key %d", key); + err = -EINVAL; + break; + } + + return err; +} + +static int plug_ctl_read_integer(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, long *value) +{ + snd_sof_ctl_t *ctl = ext->private_data; + struct snd_soc_tplg_mixer_control *mixer_ctl = + CTL_GET_TPLG_MIXER(ctl, key); + struct sof_ipc_ctrl_data *ctl_data; + struct sof_ipc_ctrl_value_chan *chanv; + int err, i; + + // TODO: set generic max size + ctl_data = calloc(IPC3_MAX_MSG_SIZE, 1); + if (!ctl_data) + return -ENOMEM; + chanv = ctl_data->chanv; + + /* setup the IPC message */ + ctl_data->comp_id = ctl->glb->ctl[key].comp_id; + ctl_data->cmd = SOF_CTRL_CMD_VOLUME; + ctl_data->type = SOF_CTRL_TYPE_VALUE_COMP_GET; + ctl_data->rhdr.hdr.cmd = SOF_IPC_GLB_COMP_MSG | SOF_IPC_COMP_GET_VALUE; + ctl_data->rhdr.hdr.size = sizeof(ctl_data); + ctl_data->num_elems = mixer_ctl->num_channels; + + /* send message and wait for reply */ + err = plug_mq_cmd(&ctl->ipc, ctl_data, IPC3_MAX_MSG_SIZE, ctl_data, IPC3_MAX_MSG_SIZE); + if (err < 0) { + SNDERR("error: can't read CTL %d message\n", + ctl_data->comp_id); + return err; + } + + /* did IPC succeed ? */ + if (ctl_data->rhdr.error != 0) { + SNDERR("error: can't read CTL %d failed: error %d\n", + ctl_data->comp_id, ctl_data->rhdr.error); + return ctl_data->rhdr.error; + } + + /* get data from IPC */ + for (i = 0; i < mixer_ctl->num_channels; i++) + value[i] = chanv[i].value; + + free(ctl_data); + + return err; +} + +static int plug_ctl_write_integer(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, long *value) +{ + snd_sof_ctl_t *ctl = ext->private_data; + struct snd_soc_tplg_mixer_control *mixer_ctl = + CTL_GET_TPLG_MIXER(ctl, key); + struct sof_ipc_ctrl_data *ctl_data; + struct sof_ipc_ctrl_value_chan *chanv; + int err; + int i; + + // TODO: set generic max size + ctl_data = calloc(IPC3_MAX_MSG_SIZE, 1); + if (!ctl_data) + return -ENOMEM; + chanv = ctl_data->chanv; + + /* setup the IPC message */ + ctl_data->comp_id = ctl->glb->ctl[key].comp_id; + ctl_data->cmd = SOF_CTRL_CMD_VOLUME; + ctl_data->type = SOF_CTRL_TYPE_VALUE_COMP_SET; + ctl_data->rhdr.hdr.cmd = SOF_IPC_GLB_COMP_MSG | SOF_IPC_COMP_SET_VALUE; + ctl_data->rhdr.hdr.size = sizeof(ctl_data); + ctl_data->num_elems = mixer_ctl->num_channels; + + /* set data for IPC */ + for (i = 0; i < mixer_ctl->num_channels; i++) + chanv[i].value = value[i]; + + err = plug_mq_cmd(&ctl->ipc, ctl_data, IPC3_MAX_MSG_SIZE, + ctl_data, IPC3_MAX_MSG_SIZE); + if (err < 0) { + SNDERR("error: can't write CTL %d message\n", ctl_data->comp_id); + return err; + } + + /* did IPC succeed ? */ + if (ctl_data->rhdr.error != 0) { + SNDERR("error: can't write CTL %d failed: error %d\n", + ctl_data->comp_id, ctl_data->rhdr.error); + return ctl_data->rhdr.error; + } + + free(ctl_data); + + return err; +} + +/* + * Enum ops + */ +static int plug_ctl_get_enumerated_info(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, + unsigned int *items) +{ + snd_sof_ctl_t *ctl = ext->private_data; + struct snd_soc_tplg_ctl_hdr *hdr = CTL_GET_TPLG_HDR(ctl, key); + struct snd_soc_tplg_enum_control *enum_ctl = + (struct snd_soc_tplg_enum_control *)hdr; + int err = 0; + + switch (hdr->type) { + case SND_SOC_TPLG_CTL_ENUM: + case SND_SOC_TPLG_CTL_ENUM_VALUE: + *items = enum_ctl->items; + break; + default: + SNDERR("invalid ctl type for enum using key %d", key); + err = -EINVAL; + break; + } + + return err; +} + +static int plug_ctl_get_enumerated_name(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, + unsigned int item, char *name, size_t name_max_len) +{ + snd_sof_ctl_t *ctl = ext->private_data; + struct snd_soc_tplg_ctl_hdr *hdr = CTL_GET_TPLG_HDR(ctl, key); + struct snd_soc_tplg_enum_control *enum_ctl = + (struct snd_soc_tplg_enum_control *)hdr; + + printf("%s %d\n", __func__, __LINE__); + + if (item >= enum_ctl->count) { + SNDERR("invalid item %d for enum using key %d", item, key); + return -EINVAL; + } + + strncpy(name, enum_ctl->texts[item], name_max_len); + return 0; +} + +static int plug_ctl_read_enumerated(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, + unsigned int *items) +{ + snd_sof_ctl_t *ctl = ext->private_data; + struct snd_soc_tplg_enum_control *enum_ctl = + CTL_GET_TPLG_ENUM(ctl, key); + struct sof_ipc_ctrl_data *ctl_data; + struct sof_ipc_ctrl_value_comp *compv; + int err, i; + + // TODO: set generic max size + ctl_data = calloc(IPC3_MAX_MSG_SIZE, 1); + if (!ctl_data) + return -ENOMEM; + compv = ctl_data->compv; + + /* setup the IPC message */ + ctl_data->comp_id = ctl->glb->ctl[key].comp_id; + ctl_data->cmd = SOF_CTRL_CMD_ENUM; + ctl_data->type = SOF_CTRL_TYPE_VALUE_COMP_GET; + ctl_data->rhdr.hdr.cmd = SOF_IPC_GLB_COMP_MSG | SOF_IPC_COMP_GET_VALUE; + ctl_data->rhdr.hdr.size = sizeof(ctl_data); + + /* send message and wait for reply */ + err = plug_mq_cmd(&ctl->ipc, ctl_data, IPC3_MAX_MSG_SIZE, + ctl_data, IPC3_MAX_MSG_SIZE); + if (err < 0) { + SNDERR("error: can't read CTL %d message\n", ctl_data->comp_id); + return err; + } + + /* did IPC succeed ? */ + if (ctl_data->rhdr.error != 0) { + SNDERR("error: can't read CTL %d failed: error %d\n", + ctl_data->comp_id, ctl_data->rhdr.error); + return ctl_data->rhdr.error; + } + + /* get data from IPC */ + for (i = 0; i < enum_ctl->num_channels; i++) + items[i] = compv[i].uvalue; + + free(ctl_data); + + return err; +} + +static int plug_ctl_write_enumerated(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, + unsigned int *items) +{ + snd_sof_ctl_t *ctl = ext->private_data; + struct snd_soc_tplg_enum_control *enum_ctl = + CTL_GET_TPLG_ENUM(ctl, key); + struct sof_ipc_ctrl_data *ctl_data; + struct sof_ipc_ctrl_value_comp *compv; + int err, i; + + // TODO: set generic max size + ctl_data = calloc(IPC3_MAX_MSG_SIZE, 1); + if (!ctl_data) + return -ENOMEM; + compv = ctl_data->compv; + + printf("%s %d\n", __func__, __LINE__); + + /* setup the IPC message */ + ctl_data->comp_id = ctl->glb->ctl[key].comp_id; + ctl_data->cmd = SOF_CTRL_CMD_ENUM; + ctl_data->type = SOF_CTRL_TYPE_VALUE_COMP_SET; + ctl_data->rhdr.hdr.cmd = SOF_IPC_GLB_COMP_MSG | SOF_IPC_COMP_SET_VALUE; + ctl_data->rhdr.hdr.size = sizeof(ctl_data); + + /* set data for IPC */ + for (i = 0; i < enum_ctl->num_channels; i++) + compv[i].uvalue = items[i]; + + /* send message and wait for reply */ + err = plug_mq_cmd(&ctl->ipc, ctl_data, IPC3_MAX_MSG_SIZE, + ctl_data, IPC3_MAX_MSG_SIZE); + if (err < 0) { + SNDERR("error: can't read CTL %d message\n", ctl_data->comp_id); + goto out; + } + + /* did IPC succeed ? */ + if (ctl_data->rhdr.error != 0) { + SNDERR("error: can't read CTL %d failed: error %d\n", + ctl_data->comp_id, ctl_data->rhdr.error); + err = ctl_data->rhdr.error; + } + +out: + free(ctl_data); + return err; +} + +/* + * Bytes ops - TODO handle large blobs + */ + +static int plug_ctl_read_bytes(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, + unsigned char *data, size_t max_bytes) +{ + snd_sof_ctl_t *ctl = ext->private_data; + struct snd_soc_tplg_bytes_control *binary_ctl = + CTL_GET_TPLG_BYTES(ctl, key); + struct sof_ipc_ctrl_data *ctl_data; + int err; + + // TODO: set generic max size + ctl_data = calloc(IPC3_MAX_MSG_SIZE, 1); + if (!ctl_data) + return -ENOMEM; + + /* setup the IPC message */ + ctl_data->comp_id = ctl->glb->ctl[key].comp_id; + ctl_data->cmd = SOF_CTRL_CMD_BINARY; + ctl_data->type = SOF_CTRL_TYPE_VALUE_COMP_GET; + ctl_data->rhdr.hdr.cmd = SOF_IPC_GLB_COMP_MSG | SOF_IPC_COMP_GET_VALUE; + ctl_data->rhdr.hdr.size = sizeof(ctl_data); + + /* send message and wait for reply */ + err = plug_mq_cmd(&ctl->ipc, ctl_data, IPC3_MAX_MSG_SIZE, + ctl_data, IPC3_MAX_MSG_SIZE); + if (err < 0) { + SNDERR("error: can't read CTL %d message\n", ctl_data->comp_id); + return err; + } + + /* did IPC succeed ? */ + if (ctl_data->rhdr.error != 0) { + SNDERR("error: can't read CTL %d failed: error %d\n", + ctl_data->comp_id, ctl_data->rhdr.error); + return ctl_data->rhdr.error; + } + + /* get data for IPC */ + memcpy(data, &ctl_data->data, MIN(binary_ctl->max, max_bytes)); + free(ctl_data); + + return err; +} + +static int plug_ctl_write_bytes(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, + unsigned char *data, size_t max_bytes) +{ + snd_sof_ctl_t *ctl = ext->private_data; + struct snd_soc_tplg_bytes_control *binary_ctl = + CTL_GET_TPLG_BYTES(ctl, key); + struct sof_ipc_ctrl_data *ctl_data; + int err; + + // TODO: set generic max size + ctl_data = calloc(IPC3_MAX_MSG_SIZE, 1); + if (!ctl_data) + return -ENOMEM; + + printf("%s %d\n", __func__, __LINE__); + + /* setup the IPC message */ + ctl_data->comp_id = ctl->glb->ctl[key].comp_id; + ctl_data->cmd = SOF_CTRL_CMD_BINARY; + ctl_data->type = SOF_CTRL_TYPE_VALUE_COMP_SET; + ctl_data->rhdr.hdr.cmd = SOF_IPC_GLB_COMP_MSG | SOF_IPC_COMP_SET_VALUE; + ctl_data->rhdr.hdr.size = sizeof(ctl_data); + + /* set data for IPC */ + memcpy(&ctl_data->data, data, MIN(binary_ctl->max, max_bytes)); + + /* send message and wait for reply */ + err = plug_mq_cmd(&ctl->ipc, ctl_data, IPC3_MAX_MSG_SIZE, + ctl_data, IPC3_MAX_MSG_SIZE); + if (err < 0) { + SNDERR("error: can't read CTL %d message\n", ctl_data->comp_id); + return err; + } + + /* did IPC succeed ? */ + if (ctl_data->rhdr.error != 0) { + SNDERR("error: can't read CTL %d failed: error %d\n", + ctl_data->comp_id, ctl_data->rhdr.error); + return ctl_data->rhdr.error; + } + + free(ctl_data); + + return err; +} + +/* + * TLV ops + * + * The format of an array of \a tlv argument is: + * tlv[0]: Type. One of SND_CTL_TLVT_XXX. + * tlv[1]: Length. The length of value in units of byte. + * tlv[2..]: Value. Depending on the type. + */ +static int plug_tlv_rw(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, int op_flag, + unsigned int numid, unsigned int *tlv, unsigned int tlv_size) +{ + snd_sof_ctl_t *ctl = ext->private_data; + struct snd_soc_tplg_ctl_hdr *hdr = CTL_GET_TPLG_HDR(ctl, key); + + //TODO: alsamixer showing wrong dB scales + tlv[0] = hdr->tlv.type; + tlv[1] = hdr->tlv.size - sizeof(uint32_t) * 2; + memcpy(&tlv[2], hdr->tlv.data, hdr->tlv.size - sizeof(uint32_t) * 2); + + return 0; +} + +static void plug_ctl_subscribe_events(snd_ctl_ext_t *ext, int subscribe) +{ + snd_sof_ctl_t *ctl = ext->private_data; + + ctl->subscribed = !!(subscribe & SND_CTL_EVENT_MASK_VALUE); +} + +static int plug_ctl_read_event(snd_ctl_ext_t *ext, snd_ctl_elem_id_t *id, + unsigned int *event_mask) +{ + snd_sof_ctl_t *ctl = ext->private_data; + int numid; + int err = 0; + + numid = snd_ctl_elem_id_get_numid(id); + + // TODO: we need a notify() or listening thread to take async/volatile ctl + // notifications from sof-pipe and notify userspace via events of the ctl change. + if (!ctl->updated[numid - 1] || !ctl->subscribed) { + err = -EAGAIN; + goto out; + } + + *event_mask = SND_CTL_EVENT_MASK_VALUE; +out: + return err; +} + +static int plug_ctl_poll_revents(snd_ctl_ext_t *ext, struct pollfd *pfd, + unsigned int nfds, unsigned short *revents) +{ + snd_sof_ctl_t *ctl = ext->private_data; + int i; + + *revents = 0; + + for (i = 0; i < ctl->glb->num_ctls; i++) { + if (ctl->updated[i]) { + *revents = POLLIN; + break; + } + } + + return 0; +} + +static void plug_ctl_close(snd_ctl_ext_t *ext) +{ + snd_sof_ctl_t *ctl = ext->private_data; + + /* TODO: munmap */ + free(ctl); +} + +static const snd_ctl_ext_callback_t sof_ext_callback = { + .elem_count = plug_ctl_elem_count, + .elem_list = plug_ctl_elem_list, + .find_elem = plug_ctl_find_elem, + .get_attribute = plug_ctl_get_attribute, + .get_integer_info = plug_ctl_get_integer_info, + .read_integer = plug_ctl_read_integer, + .write_integer = plug_ctl_write_integer, + .get_enumerated_info = plug_ctl_get_enumerated_info, + .get_enumerated_name = plug_ctl_get_enumerated_name, + .read_enumerated = plug_ctl_read_enumerated, + .write_enumerated = plug_ctl_write_enumerated, + .read_bytes = plug_ctl_read_bytes, + .write_bytes = plug_ctl_write_bytes, + .subscribe_events = plug_ctl_subscribe_events, + .read_event = plug_ctl_read_event, + .poll_revents = plug_ctl_poll_revents, + .close = plug_ctl_close, +}; + +SND_CTL_PLUGIN_DEFINE_FUNC(sof) +{ + snd_sof_plug_t *plug; + int err; + snd_sof_ctl_t *ctl; + + /* create context */ + plug = calloc(1, sizeof(*plug)); + if (!plug) + return -ENOMEM; + + ctl = calloc(1, sizeof(*ctl)); + if (!ctl) + return -ENOMEM; + plug->module_prv = ctl; + + /* parse the ALSA configuration file for sof plugin */ + err = plug_parse_conf(plug, name, root, conf); + if (err < 0) { + SNDERR("failed to parse config: %s", strerror(err)); + goto error; + } + + /* create message queue for IPC */ + err = plug_mq_init(&ctl->ipc, plug->tplg_file, "ipc", 0); + if (err < 0) + goto error; + + /* open message queue for IPC */ + err = plug_mq_open(&ctl->ipc); + if (err < 0) { + SNDERR("failed to open IPC message queue: %s", strerror(err)); + SNDERR("The PCM needs to be open for mixers to connect to pipeline"); + goto error; + } + + /* create a SHM mapping for low latency stream position */ + err = plug_shm_init(&ctl->shm_ctx, plug->tplg_file, "ctx", 0); + if (err < 0) + goto error; + + // TODO: make this open/close per operation for shared access + /* create a SHM mapping for low latency stream position */ + err = plug_shm_open(&ctl->shm_ctx); + if (err < 0) + goto error; + + /* get global context for kcontrol lookup */ + ctl->glb = ctl->shm_ctx.addr; + + /* TODO: add some flavour to the names based on the topology */ + ctl->ext.version = SND_CTL_EXT_VERSION; + ctl->ext.card_idx = 0; + strncpy(ctl->ext.id, "sof", sizeof(ctl->ext.id) - 1); + strncpy(ctl->ext.driver, "SOF plugin", + sizeof(ctl->ext.driver) - 1); + strncpy(ctl->ext.name, "SOF", sizeof(ctl->ext.name) - 1); + strncpy(ctl->ext.mixername, "SOF", + sizeof(ctl->ext.mixername) - 1); + + /* polling on message queue - supported on Linux but not portable */ + ctl->ext.poll_fd = ctl->ipc.mq; + + ctl->ext.callback = &sof_ext_callback; + ctl->ext.private_data = ctl; + ctl->ext.tlv.c = plug_tlv_rw; + + err = snd_ctl_ext_create(&ctl->ext, name, mode); + if (err < 0) + goto error; + + *handlep = ctl->ext.handle; + + return 0; + +error: + free(ctl); + + return err; +} + +SND_CTL_PLUGIN_SYMBOL(sof); diff --git a/tools/plugin/alsaplug/pcm.c b/tools/plugin/alsaplug/pcm.c new file mode 100644 index 000000000000..f6aef645ce56 --- /dev/null +++ b/tools/plugin/alsaplug/pcm.c @@ -0,0 +1,1038 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. +// +// Author: Liam Girdwood + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "plugin.h" +#include "common.h" + +typedef struct snd_sof_pcm { + snd_pcm_ioplug_t io; + size_t frame_size; + struct timespec wait_timeout; + int capture; + int events; + + /* PCM flow control */ + struct plug_sem_desc ready[TPLG_MAX_PCM_PIPELINES]; + struct plug_sem_desc done[TPLG_MAX_PCM_PIPELINES]; + /* pipeline IPC tx queues */ + struct plug_mq_desc pipeline_ipc_tx[TPLG_MAX_PCM_PIPELINES]; + /* pipeline IPC response queues */ + struct plug_mq_desc pipeline_ipc_rx[TPLG_MAX_PCM_PIPELINES]; + + struct plug_shm_desc glb_ctx; + struct plug_shm_desc shm_pcm; + + int frame_us; +} snd_sof_pcm_t; + +static int plug_pipeline_set_state(snd_sof_plug_t *plug, int state, + struct ipc4_pipeline_set_state *pipe_state, + struct tplg_pipeline_info *pipe_info, + struct plug_mq_desc *ipc_tx, struct plug_mq_desc *ipc_rx) +{ + struct ipc4_message_reply reply = {{ 0 }}; + int ret; + + pipe_state->primary.r.ppl_id = pipe_info->instance_id; + + ret = plug_mq_cmd_tx_rx(ipc_tx, ipc_rx, pipe_state, sizeof(*pipe_state), + &reply, sizeof(reply)); + if (ret < 0) + SNDERR("failed pipeline %d set state %d\n", pipe_info->instance_id, state); + + return ret; +} + +static int plug_pipelines_set_state(snd_sof_plug_t *plug, int state) +{ + snd_sof_pcm_t *pcm = plug->module_prv; + struct ipc4_pipeline_set_state pipe_state = {{ 0 }}; + struct tplg_pipeline_list *pipeline_list; + int i; + + if (pcm->capture) + pipeline_list = &plug->pcm_info->capture_pipeline_list; + else + pipeline_list = &plug->pcm_info->playback_pipeline_list; + + pipe_state.primary.r.ppl_state = state; + pipe_state.primary.r.type = SOF_IPC4_GLB_SET_PIPELINE_STATE; + pipe_state.primary.r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG; + pipe_state.primary.r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST; + + /* + * pipeline list is populated starting from the host to DAI. So traverse the list in + * the reverse order for capture to start the source pipeline first. + */ + if (pcm->capture) { + for (i = pipeline_list->count - 1; i >= 0; i--) { + struct tplg_pipeline_info *pipe_info = pipeline_list->pipelines[i]; + int ret; + + ret = plug_pipeline_set_state(plug, state, &pipe_state, pipe_info, + &pcm->pipeline_ipc_tx[i], + &pcm->pipeline_ipc_rx[i]); + if (ret < 0) + return ret; + } + + return 0; + } + + for (i = 0; i < pipeline_list->count; i++) { + struct tplg_pipeline_info *pipe_info = pipeline_list->pipelines[i]; + int ret; + + ret = plug_pipeline_set_state(plug, state, &pipe_state, pipe_info, + &pcm->pipeline_ipc_tx[i], &pcm->pipeline_ipc_rx[i]); + if (ret < 0) + return ret; + } + + return 0; +} + +static int plug_pcm_start(snd_pcm_ioplug_t *io) +{ + snd_sof_plug_t *plug = io->private_data; + snd_sof_pcm_t *pcm = plug->module_prv; + struct plug_shm_endpoint *ctx = pcm->shm_pcm.addr; + int err; + + switch (ctx->state) { + case SOF_PLUGIN_STATE_READY: + err = plug_pipelines_set_state(plug, SOF_IPC4_PIPELINE_STATE_RUNNING); + if (err < 0) + return err; + break; + case SOF_PLUGIN_STATE_STREAM_RUNNING: + { + struct tplg_pipeline_list *pipeline_list; + int i, delay; + + if (!pcm->capture) + break; + + pipeline_list = &plug->pcm_info->capture_pipeline_list; + + /* start the first period copy for capture */ + for (i = pipeline_list->count - 1; i >= 0; i--) { + sem_post(pcm->ready[i].sem); + + /* wait for sof-pipe reader to consume data or timeout */ + err = clock_gettime(CLOCK_REALTIME, &pcm->wait_timeout); + if (err == -1) { + SNDERR("write: cant get time: %s", strerror(errno)); + return -EPIPE; + } + + /* work out delay TODO: fix ALSA reader */ + delay = pcm->frame_us * io->period_size / 500; + plug_timespec_add_ms(&pcm->wait_timeout, delay); + + /* wait for sof-pipe writer to produce data or timeout */ + err = sem_timedwait(pcm->done[i].sem, &pcm->wait_timeout); + if (err == -1) { + SNDERR("read: waited %d ms for %ld frames fatal timeout: %s", + delay, io->period_size, strerror(errno)); + return -errno; + } + } + } + break; + case SOF_PLUGIN_STATE_INIT: + case SOF_PLUGIN_STATE_STREAM_ERROR: + case SOF_PLUGIN_STATE_DEAD: + default: + /* some error */ + SNDERR("pcm start: invalid pipe state: %d", ctx->state); + return -EINVAL; + } + + return 0; +} + +static int plug_pcm_stop(snd_pcm_ioplug_t *io) +{ + snd_sof_plug_t *plug = io->private_data; + snd_sof_pcm_t *pcm = plug->module_prv; + struct plug_shm_endpoint *ctx = pcm->shm_pcm.addr; + int err; + + printf("%s %d state %ld\n", __func__, __LINE__, ctx->state); + switch (ctx->state) { + case SOF_PLUGIN_STATE_STREAM_ERROR: + case SOF_PLUGIN_STATE_STREAM_RUNNING: + { + err = plug_pipelines_set_state(plug, SOF_IPC4_PIPELINE_STATE_PAUSED); + if (err < 0) + return err; + break; + } + case SOF_PLUGIN_STATE_READY: + /* already stopped */ + break; + case SOF_PLUGIN_STATE_INIT: + case SOF_PLUGIN_STATE_DEAD: + default: + /* some error */ + SNDERR("pcm stop: invalid pipe state: %d", ctx->state); + return -EINVAL; + } + + return 0; +} + +/* buffer position up to buffer_size */ +static snd_pcm_sframes_t plug_pcm_pointer(snd_pcm_ioplug_t *io) +{ + snd_sof_plug_t *plug = io->private_data; + snd_sof_pcm_t *pcm = plug->module_prv; + struct plug_shm_endpoint *ctx = pcm->shm_pcm.addr; + snd_pcm_sframes_t ptr = 0; + int err; + + if (io->state == SND_PCM_STATE_XRUN) + return -EPIPE; + + if (io->state != SND_PCM_STATE_RUNNING) + return 0; + + switch (ctx->state) { + case SOF_PLUGIN_STATE_STREAM_RUNNING: + case SOF_PLUGIN_STATE_STREAM_ERROR: + if (pcm->capture) + ptr = ctx->wtotal / pcm->frame_size; + else + ptr = ctx->rtotal / pcm->frame_size; + break; + case SOF_PLUGIN_STATE_READY: + /* not running */ + return 0; + case SOF_PLUGIN_STATE_INIT: + case SOF_PLUGIN_STATE_DEAD: + default: + /* some error */ + SNDERR("pointer: invalid pipe state: %d", ctx->state); + ptr = -EPIPE; + } + + return ptr; +} + +/* get the delay for the running PCM; optional; since v1.0.1 */ +static int plug_pcm_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp) +{ + snd_sof_plug_t *plug = io->private_data; + snd_sof_pcm_t *pcm = plug->module_prv; + struct plug_shm_endpoint *ctx = pcm->shm_pcm.addr; + int err = 0; + + switch (ctx->state) { + case SOF_PLUGIN_STATE_STREAM_RUNNING: + case SOF_PLUGIN_STATE_READY: + // TODO: is capture delay correct here ??? + if (pcm->capture) + *delayp = (ctx->wtotal - ctx->rtotal) / pcm->frame_size; + else + *delayp = (ctx->rtotal - ctx->wtotal) / pcm->frame_size; + /* sanitize delay */ + if (*delayp < pcm->io.period_size || *delayp > io->buffer_size) + *delayp = pcm->io.period_size; + return 0; + case SOF_PLUGIN_STATE_STREAM_ERROR: + snd_pcm_ioplug_set_state(io, SND_PCM_STATE_XRUN); + return 0; + case SOF_PLUGIN_STATE_INIT: + case SOF_PLUGIN_STATE_DEAD: + default: + /* some error */ + SNDERR("delay: invalid pipe state: %d", ctx->state); + return -EPIPE; + } +} + +/* return frames written */ +static snd_pcm_sframes_t plug_pcm_write(snd_pcm_ioplug_t *io, const snd_pcm_channel_area_t *areas, + snd_pcm_uframes_t offset, snd_pcm_uframes_t size) +{ + snd_sof_plug_t *plug = io->private_data; + snd_sof_pcm_t *pcm = plug->module_prv; + struct plug_shm_endpoint *ctx = pcm->shm_pcm.addr; + struct tplg_pipeline_list *pipeline_list; + snd_pcm_sframes_t frames = 0; + int i; + ssize_t bytes; + const char *buf; + int err, delay; + + pipeline_list = &plug->pcm_info->playback_pipeline_list; + + /* calculate the buffer position and size from application */ + buf = (char *)areas->addr + (areas->first + areas->step * offset) / 8; + bytes = size * pcm->frame_size; + + /* now check what the pipe has free */ + bytes = MIN(plug_ep_get_free(ctx), bytes); + + frames = bytes / pcm->frame_size; + + if (frames == 0) + return frames; + + /* write audio data to the pipe */ + memcpy(plug_ep_wptr(ctx), buf, bytes); + + plug_ep_produce(ctx, bytes); + + /* tell the pipelines data is ready starting at the source pipeline */ + for (i = 0; i < pipeline_list->count; i++) { + struct tplg_pipeline_info *pipe_info = pipeline_list->pipelines[i]; + + sem_post(pcm->ready[i].sem); + + /* wait for sof-pipe reader to consume data or timeout */ + err = clock_gettime(CLOCK_REALTIME, &pcm->wait_timeout); + if (err == -1) { + SNDERR("write: cant get time: %s", strerror(errno)); + return -EPIPE; + } + + /* work out delay */ + delay = pcm->frame_us * frames / 500; + plug_timespec_add_ms(&pcm->wait_timeout, delay); + + /* now block caller on pipeline IO to PCM device */ + err = sem_timedwait(pcm->done[i].sem, &pcm->wait_timeout); + if (err == -1) { + SNDERR("write: waited %d ms for %ld frames, fatal timeout: %s", + delay, frames, strerror(errno)); + return -errno; + } + } + + return frames; +} + +/* return frames read */ +static snd_pcm_sframes_t plug_pcm_read(snd_pcm_ioplug_t *io, const snd_pcm_channel_area_t *areas, + snd_pcm_uframes_t offset, snd_pcm_uframes_t size) +{ + snd_sof_plug_t *plug = io->private_data; + snd_sof_pcm_t *pcm = plug->module_prv; + snd_pcm_sframes_t frames; + struct plug_shm_endpoint *ctx = pcm->shm_pcm.addr; + struct tplg_pipeline_list *pipeline_list; + ssize_t bytes; + char *buf; + int err, delay, i; + + pipeline_list = &plug->pcm_info->capture_pipeline_list; + + /* calculate the buffer position and size */ + buf = (char *)areas->addr + (areas->first + areas->step * offset) / 8; + bytes = size * pcm->frame_size; + + /* check what the pipe has avail */ + bytes = MIN(plug_ep_get_avail(ctx), bytes); + frames = bytes / pcm->frame_size; + + if (!frames) + return 0; + + /* tell the pipe ready we are ready for next period */ + for (i = pipeline_list->count - 1; i >= 0; i--) { + sem_post(pcm->ready[i].sem); + + /* wait for sof-pipe reader to consume data or timeout */ + err = clock_gettime(CLOCK_REALTIME, &pcm->wait_timeout); + if (err == -1) { + SNDERR("write: cant get time: %s", strerror(errno)); + return -EPIPE; + } + + /* work out delay TODO: fix ALSA reader */ + delay = pcm->frame_us * frames / 500; + plug_timespec_add_ms(&pcm->wait_timeout, delay); + + /* wait for sof-pipe writer to produce data or timeout */ + err = sem_timedwait(pcm->done[i].sem, &pcm->wait_timeout); + if (err == -1) { + SNDERR("read: waited %d ms for %ld frames fatal timeout: %s", + delay, frames, strerror(errno)); + return -errno; + } + } + + /* copy audio data from pipe */ + memcpy(buf, plug_ep_rptr(ctx), bytes); + plug_ep_consume(ctx, bytes); + + return frames; +} + +static int plug_pcm_prepare(snd_pcm_ioplug_t *io) +{ + snd_sof_plug_t *plug = io->private_data; + snd_sof_pcm_t *pcm = plug->module_prv; + struct plug_shm_endpoint *ctx = pcm->shm_pcm.addr; + int err = 0; + + ctx->wtotal = 0; + ctx->rtotal = 0; + ctx->rpos = 0; + ctx->rwrap = 0; + ctx->wpos = 0; + ctx->wwrap = 0; + + /* start the pipeline threads + * + * We do this during prepare so that pipelines can consume/produce + * any start threshold worth of data with the pipeline in a running + * state + */ + switch (ctx->state) { + case SOF_PLUGIN_STATE_INIT: + /* set pipelines to PAUSED state to prepare them */ + err = plug_pipelines_set_state(plug, SOF_IPC4_PIPELINE_STATE_PAUSED); + if (err < 0) + return err; + + fprintf(stdout, "pipelines complete now\n"); + + /* set pipelines to RUNNING state */ + err = plug_pipelines_set_state(plug, SOF_IPC4_PIPELINE_STATE_RUNNING); + if (err < 0) + return err; + break; + case SOF_PLUGIN_STATE_STREAM_ERROR: + case SOF_PLUGIN_STATE_DEAD: + /* some error */ + SNDERR("write: invalid pipe state: %d", ctx->state); + return -EINVAL; + case SOF_PLUGIN_STATE_READY: + case SOF_PLUGIN_STATE_STREAM_RUNNING: + default: + /* do nothing */ + break; + } + + fprintf(stdout, "PCM prepare done\n"); + + return err; +} + +static int plug_init_shm_ctx(snd_sof_plug_t *plug); + +static int plug_pcm_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params) +{ + snd_sof_plug_t *plug = io->private_data; + snd_sof_pcm_t *pcm = plug->module_prv; + struct plug_shm_endpoint *ctx; + struct tplg_pipeline_list *pipeline_list; + int i, err; + + pcm->frame_size = (snd_pcm_format_physical_width(io->format) * io->channels) / 8; + + plug->period_size = io->period_size; + + /* used for wait timeouts */ + pcm->frame_us = ceil(1000000.0 / io->rate); + + /* now send IPCs to set up widgets */ + err = plug_set_up_pipelines(plug, pcm->capture); + if (err < 0) { + fprintf(stderr, "error setting up pipelines\n"); + return err; + } + + if (pcm->capture) + pipeline_list = &plug->pcm_info->capture_pipeline_list; + else + pipeline_list = &plug->pcm_info->playback_pipeline_list; + + /* init and open for PCM ready lock for all pipelines */ + for (i = 0; i < pipeline_list->count; i++) { + struct tplg_pipeline_info *pipe_info = pipeline_list->pipelines[i]; + + /* init IPC message queue name */ + err = plug_mq_init(&pcm->pipeline_ipc_tx[i], plug->tplg_file, "pcm-tx", + pipe_info->instance_id); + if (err < 0) { + SNDERR("error: invalid name for pipeline IPC mq %s\n", plug->tplg_file); + return err; + } + + /* open the sof-pipe IPC message queue */ + err = plug_mq_open(&pcm->pipeline_ipc_tx[i]); + if (err < 0) { + SNDERR("error: failed to open sof-pipe IPC mq %s: %s", + pcm->pipeline_ipc_tx[i].queue_name, strerror(err)); + return -errno; + } + + /* init IPC message queue name */ + err = plug_mq_init(&pcm->pipeline_ipc_rx[i], plug->tplg_file, "pcm-rx", + pipe_info->instance_id); + if (err < 0) { + SNDERR("error: invalid name for pipeline IPC mq %s\n", plug->tplg_file); + return err; + } + + /* open the sof-pipe IPC message queue */ + err = plug_mq_open(&pcm->pipeline_ipc_rx[i]); + if (err < 0) { + SNDERR("error: failed to open sof-pipe IPC mq %s: %s", + pcm->pipeline_ipc_tx[i].queue_name, strerror(err)); + return -errno; + } + + /* init name for pipeline ready lock */ + err = plug_lock_init(&pcm->ready[i], plug->tplg_file, "ready", + pipe_info->instance_id); + if (err < 0) { + SNDERR("error: invalid name for PCM ready lock %s\n", + pipe_info->instance_id); + return err; + } + + /* init name for pipeline done lock */ + err = plug_lock_init(&pcm->done[i], plug->tplg_file, "done", + pipe_info->instance_id); + if (err < 0) { + SNDERR("error: invalid name for PCM done lock %s\n", + pipe_info->instance_id); + return err; + } + + /* open lock "ready" for pipeline audio data */ + err = plug_lock_open(&pcm->ready[i]); + if (err < 0) { + SNDERR("error: failed to open sof-pipe ready lock %s: %s", + pcm->ready[i].name, strerror(err)); + return -errno; + } + + /* open lock "done" for pipeline audio data */ + err = plug_lock_open(&pcm->done[i]); + if (err < 0) { + SNDERR("error: failed to open sof-pipe done lock %s: %s", + pcm->done[i].name, strerror(err)); + return -errno; + } + } + + /* init global status shm name */ + err = plug_shm_init(&pcm->glb_ctx, plug->tplg_file, "ctx", 0); + if (err < 0) { + SNDERR("error: invalid name for global SHM %s\n", plug->tplg_file); + return err; + } + + /* init PCM shm name */ + err = plug_shm_init(&pcm->shm_pcm, plug->tplg_file, "pcm", plug->pcm_id); + if (err < 0) { + SNDERR("error: invalid name for PCM SHM %s\n", plug->tplg_file); + return err; + } + + /* open the global sof-pipe context via SHM */ + pcm->glb_ctx.size = 128 * 1024; + err = plug_shm_open(&pcm->glb_ctx); + if (err < 0) { + SNDERR("error: failed to open sof-pipe context: %s:%s", + pcm->glb_ctx.name, strerror(err)); + return err; + } + + /* open audio PCM SHM data endpoint */ + err = plug_shm_open(&pcm->shm_pcm); + if (err < 0) { + SNDERR("error: failed to open sof-pipe PCM SHM %s: %s", + pcm->shm_pcm.name, strerror(err)); + return -errno; + } + + /* set up the endpoint configs */ + err = plug_init_shm_ctx(plug); + if (err < 0) { + SNDERR("error: failed to init sof-pipe ep context: %s:%s", + pcm->glb_ctx.name, strerror(err)); + return -err; + } + + ctx = pcm->shm_pcm.addr; + ctx->frame_size = pcm->frame_size; + + /* needs to be set here and NOT in SW params as SW params not + * called in capture flow ? + */ + ctx->buffer_size = io->buffer_size * ctx->frame_size; + + if (!ctx->buffer_size) { + SNDERR("Invalid buffer_size io buffer_size %d ctx->frame_size %d\n", + io->buffer_size, ctx->frame_size); + return -EINVAL; + } + + fprintf(stdout, "PCM hw_params done\n"); + + return 0; +} + +// TODO: why not called for arecord +static int plug_pcm_sw_params(snd_pcm_ioplug_t *io, snd_pcm_sw_params_t *params) +{ + snd_sof_plug_t *plug = io->private_data; + snd_sof_pcm_t *pcm = plug->module_prv; + snd_pcm_uframes_t start_threshold; + struct plug_shm_endpoint *ctx = pcm->shm_pcm.addr; + int err; + + /* get the stream start threshold */ + err = snd_pcm_sw_params_get_start_threshold(params, &start_threshold); + if (err < 0) { + SNDERR("sw params: failed to get start threshold: %s", strerror(err)); + return err; + } + + /* TODO: this seems to be ignored or overridden by application params ??? */ + if (start_threshold < io->period_size) { + start_threshold = io->period_size; + err = snd_pcm_sw_params_set_start_threshold(pcm->io.pcm, + params, start_threshold); + if (err < 0) { + SNDERR("sw params: failed to set start threshold %d: %s", + start_threshold, strerror(err)); + return err; + } + } + + /* keep running as long as we can */ + err = snd_pcm_sw_params_set_avail_min(pcm->io.pcm, params, 1); + if (err < 0) { + SNDERR("sw params: failed to set avail min %d: %s", 1, strerror(err)); + return err; + } + + fprintf(stdout, "sw_params done\n"); + + return 0; +} + +static int plug_pcm_close(snd_pcm_ioplug_t *io) +{ + snd_sof_plug_t *plug = io->private_data; + snd_sof_pcm_t *pcm = plug->module_prv; + struct plug_shm_glb_state *ctx = pcm->glb_ctx.addr; + int err = 0; + + printf("%s %d\n", __func__, __LINE__); + + ctx->state = SOF_PLUGIN_STATE_INIT; + + plug_free_topology(plug); + + free(plug->tplg_file); + free(plug->module_prv); + free(plug); + + return err; +} + +static int plug_pcm_hw_free(snd_pcm_ioplug_t *io) +{ + struct tplg_pipeline_list *pipeline_list; + snd_sof_plug_t *plug = io->private_data; + snd_sof_pcm_t *pcm = plug->module_prv; + int ret, i; + + /* reset all pipelines */ + ret = plug_pipelines_set_state(plug, SOF_IPC4_PIPELINE_STATE_RESET); + if (ret < 0) { + fprintf(stderr, "failed to reset pipelines\n"); + return ret; + } + + if (pcm->capture) + pipeline_list = &plug->pcm_info->capture_pipeline_list; + else + pipeline_list = &plug->pcm_info->playback_pipeline_list; + + ret = plug_free_pipelines(plug, pipeline_list, pcm->capture); + if (ret < 0) + return ret; + + close(pcm->shm_pcm.fd); + close(pcm->glb_ctx.fd); + + for (i = 0; i < pipeline_list->count; i++) { + struct tplg_pipeline_info *pipe_info = pipeline_list->pipelines[i]; + + mq_close(pcm->pipeline_ipc_tx[pipe_info->instance_id].mq); + mq_close(pcm->pipeline_ipc_rx[pipe_info->instance_id].mq); + sem_close(pcm->ready[pipe_info->instance_id].sem); + sem_close(pcm->done[pipe_info->instance_id].sem); + } +} + +static const snd_pcm_ioplug_callback_t sof_playback_callback = { + .start = plug_pcm_start, + .stop = plug_pcm_stop, + .pointer = plug_pcm_pointer, + .transfer = plug_pcm_write, + .delay = plug_pcm_delay, + .prepare = plug_pcm_prepare, + .hw_params = plug_pcm_hw_params, + .hw_free = plug_pcm_hw_free, + .sw_params = plug_pcm_sw_params, + .close = plug_pcm_close, +}; + +static const snd_pcm_ioplug_callback_t sof_capture_callback = { + .start = plug_pcm_start, + .stop = plug_pcm_stop, + .pointer = plug_pcm_pointer, + .transfer = plug_pcm_read, + .delay = plug_pcm_delay, + .prepare = plug_pcm_prepare, + .hw_params = plug_pcm_hw_params, + .sw_params = plug_pcm_sw_params, + .hw_free = plug_pcm_hw_free, + .close = plug_pcm_close, +}; + +static const snd_pcm_access_t access_list[] = { + SND_PCM_ACCESS_RW_INTERLEAVED +}; + +static const unsigned int formats[] = { + SND_PCM_FORMAT_S16_LE, + SND_PCM_FORMAT_FLOAT_LE, + SND_PCM_FORMAT_S32_LE, + SND_PCM_FORMAT_S24_LE, +}; + +/* + * Set HW constraints for the SOF plugin. This needs to be quite unrestrictive atm + * as we really need to parse topology before the HW constraints can be narrowed + * to a range that will work with the specified pipeline. + * TODO: Align with topology. + */ +static int plug_hw_constraint(snd_sof_plug_t *plug) +{ + snd_sof_pcm_t *pcm = plug->module_prv; + snd_pcm_ioplug_t *io = &pcm->io; + int err; + + err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_ACCESS, + ARRAY_SIZE(access_list), + access_list); + if (err < 0) { + SNDERR("constraints: failed to set access: %s", strerror(err)); + return err; + } + + err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_FORMAT, + ARRAY_SIZE(formats), formats); + if (err < 0) { + SNDERR("constraints: failed to set format: %s", strerror(err)); + return err; + } + + err = + snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_CHANNELS, + 1, 8); + if (err < 0) { + SNDERR("constraints: failed to set channels: %s", strerror(err)); + return err; + } + + err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_RATE, + 1, 192000); + if (err < 0) { + SNDERR("constraints: failed to set rate: %s", strerror(err)); + return err; + } + + err = + snd_pcm_ioplug_set_param_minmax(io, + SND_PCM_IOPLUG_HW_BUFFER_BYTES, + 1, 4 * 1024 * 1024); + if (err < 0) { + SNDERR("constraints: failed to set buffer bytes: %s", strerror(err)); + return err; + } + + err = + snd_pcm_ioplug_set_param_minmax(io, + SND_PCM_IOPLUG_HW_PERIOD_BYTES, + 128, 2 * 1024 * 1024); + if (err < 0) { + SNDERR("constraints: failed to set period bytes: %s", strerror(err)); + return err; + } + + err = + snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, 1, 4); + if (err < 0) { + SNDERR("constraints: failed to set period count: %s", strerror(err)); + return err; + } + + return 0; +} + +/* + * Register the plugin with ALSA and make available for use. + * TODO: setup all audio params + * TODO: setup polling fd for RW or mmap IOs + */ +static int plug_create(snd_sof_plug_t *plug, snd_pcm_t **pcmp, const char *name, + snd_pcm_stream_t stream, int mode) +{ + snd_sof_pcm_t *pcm = plug->module_prv; + int err; + + pcm->io.version = SND_PCM_IOPLUG_VERSION; + pcm->io.name = "ALSA <-> SOF PCM I/O Plugin"; + pcm->io.poll_fd = pcm->shm_pcm.fd; + pcm->io.poll_events = POLLIN; + pcm->io.mmap_rw = 0; + + if (stream == SND_PCM_STREAM_PLAYBACK) + pcm->io.callback = &sof_playback_callback; + else + pcm->io.callback = &sof_capture_callback; + + pcm->io.private_data = plug; + + /* create the plugin */ + err = snd_pcm_ioplug_create(&pcm->io, name, stream, mode); + if (err < 0) { + SNDERR("failed to register plugin %s: %s\n", name, strerror(err)); + return err; + } + + /* set the HW constrainst */ + err = plug_hw_constraint(plug); + if (err < 0) { + snd_pcm_ioplug_delete(&pcm->io); + return err; + } + + *pcmp = pcm->io.pcm; + return 0; +} + +static int plug_init_shm_ctx(snd_sof_plug_t *plug) +{ + snd_sof_pcm_t *pcm = plug->module_prv; + struct plug_shm_glb_state *glb = pcm->glb_ctx.addr; + struct endpoint_hw_config *ep; + struct plug_cmdline_item *ci; + struct plug_config *pc; + int i, j; + + glb->num_ep_configs = 0; + + for (i = 0; i < plug->num_cmdline; i++) { + bool found = false; + + if (glb->num_ep_configs >= NUM_EP_CONFIGS - 1) { + SNDERR("error: too many endpoint configs\n"); + return -EINVAL; + } + + ci = &plug->cmdline[i]; + + for (j = 0; j < plug->num_configs; j++) { + pc = &plug->config[j]; + if (strcmp(pc->name, ci->config_name)) + continue; + + ep = &glb->ep_config[glb->num_ep_configs++]; + ep->buffer_frames = pc->buffer_frames; + ep->buffer_time = pc->buffer_time; + ep->channels = pc->channels; + ep->format = pc->format; + ep->period_frames = pc->period_frames; + ep->period_time = pc->period_time; + ep->rate = pc->rate; + ep->pipeline = ci->pcm; + strncpy(ep->card_name, ci->card_name, + sizeof(ep->card_name)); + strncpy(ep->dev_name, ci->dev_name, + sizeof(ep->dev_name)); + strncpy(ep->config_name, ci->config_name, + sizeof(ep->config_name)); + found = true; + break; + } + + if (!found) { + SNDERR("error: config %s not found\n", ci->config_name); + return -EINVAL; + } + } + + return 0; +} + +/* + * Complete parent initialisation. + * 1. Check if pipe already ready by opening SHM context and IPC. + * 2. TODO: check context state and load topology is needed for core. + */ +static int plug_init_sof_pipe(snd_sof_plug_t *plug, snd_pcm_t **pcmp, + const char *name, snd_pcm_stream_t stream, int mode) +{ + snd_sof_pcm_t *pcm = plug->module_prv; + struct plug_shm_glb_state *ctx; + struct timespec delay; + int err, i; + + /* initialize widget, route and pcm lists */ + list_init(&plug->widget_list); + list_init(&plug->route_list); + list_init(&plug->pcm_list); + + plug->tplg.tplg_file = plug->tplg_file; + + /* plugin only works with IPC4 */ + plug->tplg.ipc_major = 4; + + /* parse topology file */ + err = plug_parse_topology(plug); + if (err < 0) { + fprintf(stderr, "error parsing topology %s\n", plug->tplg.tplg_file); + return err; + } + + fprintf(stdout, "topology parsing complete\n"); + + /* init IPC message queue name */ + err = plug_mq_init(&plug->ipc_tx, "sof", "ipc-tx", 0); + if (err < 0) { + SNDERR("error: invalid name for IPC mq %s\n", plug->tplg_file); + return err; + } + + /* open the sof-pipe IPC message queue */ + err = plug_mq_open(&plug->ipc_tx); + if (err < 0) { + SNDERR("error: failed to open sof-pipe IPC mq %s: %s", + plug->ipc_tx.queue_name, strerror(err)); + return -errno; + } + + err = plug_mq_init(&plug->ipc_rx, "sof", "ipc-rx", 0); + if (err < 0) { + SNDERR("error: invalid name for IPC mq %s\n", plug->tplg_file); + return err; + } + + /* open the sof-pipe IPC message queue */ + err = plug_mq_open(&plug->ipc_rx); + if (err < 0) { + SNDERR("error: failed to open sof-pipe IPC mq %s: %s", + plug->ipc_rx.queue_name, strerror(err)); + return -errno; + } + + /* now register the plugin */ + err = plug_create(plug, pcmp, name, stream, mode); + if (err < 0) { + SNDERR("failed to create plugin: %s", strerror(err)); + return -errno; + } + + return 0; +} + +/* + * ALSA PCM plugin entry point. + */ +SND_PCM_PLUGIN_DEFINE_FUNC(sof) +{ + snd_sof_plug_t *plug; + snd_sof_pcm_t *pcm; + int err; + + fprintf(stdout, "This code is WIP. Cmd args & config will possible change over time\n"); + fprintf(stdout, "\nThe 50-sonf.conf file is parsed for PCM configurations which can\n"); + fprintf(stdout, "be mapped on the cmd line to pipeline endpoints.\n"); + fprintf(stdout, "\ni.e. aplay -Dsof:::: file.wav\n"); + fprintf(stdout, "\nwhich can be used as\n"); + fprintf(stdout, "\ne.g. aplay -Dsof:bdw-nocodec:1:default:default:48k2c16b -f dat ~/audiodump.wav\n\n"); + + /* create context */ + plug = calloc(1, sizeof(*plug)); + if (!plug) + return -ENOMEM; + + pcm = calloc(1, sizeof(*pcm)); + if (!pcm) { + free(plug); + return -ENOMEM; + } + plug->module_prv = pcm; + + if (stream == SND_PCM_STREAM_CAPTURE) + pcm->capture = 1; + + /* parse the ALSA configuration file for sof plugin */ + err = plug_parse_conf(plug, name, root, conf); + if (err < 0) { + SNDERR("failed to parse config: %s", strerror(err)); + goto parse_conf_err; + } + + /* now try and connect to the sof-pipe for this topology */ + err = plug_init_sof_pipe(plug, pcmp, name, stream, mode); + if (err < 0) { + SNDERR("failed to complete plugin init: %s", strerror(err)); + goto pipe_error; + } + + /* everything is good */ + return 0; + +pipe_error: + free(plug->tplg_file); +parse_conf_err: + free(plug->module_prv); +dev_error: + free(plug); + return err; +} + +SND_PCM_PLUGIN_SYMBOL(sof); diff --git a/tools/plugin/alsaplug/plugin.c b/tools/plugin/alsaplug/plugin.c new file mode 100644 index 000000000000..b21e728c69fa --- /dev/null +++ b/tools/plugin/alsaplug/plugin.c @@ -0,0 +1,452 @@ +/*-*- linux-c -*-*/ + +/* + * ALSA <-> SOF PCM I/O plugin + * + * Copyright(c) 2022 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "plugin.h" +#include "common.h" + +int plug_mq_cmd_tx_rx(struct plug_mq_desc *ipc_tx, struct plug_mq_desc *ipc_rx, + void *msg, size_t len, void *reply, size_t rlen) +{ + struct timespec ts; + ssize_t ipc_size; + char mailbox[IPC3_MAX_MSG_SIZE]; + int err; + + if (len > IPC3_MAX_MSG_SIZE) { + SNDERR("ipc: message too big %d\n", len); + return -EINVAL; + } + memset(mailbox, 0, IPC3_MAX_MSG_SIZE); + memcpy(mailbox, msg, len); + + /* wait for sof-pipe reader to consume data or timeout */ + err = clock_gettime(CLOCK_REALTIME, &ts); + if (err == -1) { + SNDERR("ipc: cant get time: %s", strerror(errno)); + return -errno; + } + + /* IPCs should be read under 10ms */ + plug_timespec_add_ms(&ts, 10); + + /* now return message completion status */ + err = mq_timedsend(ipc_tx->mq, mailbox, IPC3_MAX_MSG_SIZE, 0, &ts); + if (err == -1) { + SNDERR("error: timeout can't send IPC message queue %s : %s\n", + ipc_tx->queue_name, strerror(errno)); + return -errno; + } + + /* wait for sof-pipe reader to consume data or timeout */ + err = clock_gettime(CLOCK_REALTIME, &ts); + if (err == -1) { + SNDERR("ipc: cant get time: %s", strerror(errno)); + return -errno; + } + + /* IPCs should be processed under 20ms, but wait longer as + * some can take longer especially in valgrind + */ + plug_timespec_add_ms(&ts, 20); + + ipc_size = mq_timedreceive(ipc_rx->mq, mailbox, IPC3_MAX_MSG_SIZE, NULL, &ts); + if (ipc_size == -1) { + //fprintf(stderr, "dbg: timeout can't read IPC message queue %s : %s retrying\n", + // ipc->queue_name, strerror(errno)); + + /* ok, its a long IPC or valgrind, wait longer */ + plug_timespec_add_ms(&ts, 800); + + ipc_size = mq_timedreceive(ipc_rx->mq, mailbox, IPC3_MAX_MSG_SIZE, NULL, &ts); + if (ipc_size == -1) { + SNDERR("error: timeout can't read IPC message queue %s : %s\n", + ipc_rx->queue_name, strerror(errno)); + return -errno; + } + + /* needed for valgrind to complete MQ op before next client IPC */ + ts.tv_nsec = 20 * 1000 * 1000; + ts.tv_sec = 0; + nanosleep(&ts, NULL); + } + + /* do the message work */ + if (rlen && reply) + memcpy(reply, mailbox, rlen); + + return 0; +} + +int plug_mq_cmd(struct plug_mq_desc *ipc, void *msg, size_t len, void *reply, size_t rlen) +{ + return plug_mq_cmd_tx_rx(ipc, ipc, msg, len, reply, rlen); +} + +/* + * Open an existing message queue using IPC object. + */ +int plug_mq_open(struct plug_mq_desc *ipc) +{ + /* now open new queue for Tx and Rx */ + ipc->mq = mq_open(ipc->queue_name, O_RDWR); + if (ipc->mq < 0) { + // SNDERR("failed to open IPC queue %s: %s\n", + // ipc->queue_name, strerror(errno)); + return -errno; + } + + return 0; +} + +/* + * Open an existing semaphore using lock object. + */ +int plug_lock_open(struct plug_sem_desc *lock) +{ + lock->sem = sem_open(lock->name, O_RDWR); + if (lock->sem == SEM_FAILED) { + SNDERR("failed to open semaphore %s: %s\n", lock->name, strerror(errno)); + return -errno; + } + + return 0; +} + +#define itemsize(type, member) sizeof(((type *)0)->member) + +static int parse_conf_long(snd_config_t *cfg, void *obj, size_t size) +{ + long val; + + if (snd_config_get_integer(cfg, &val) < 0) + return -EINVAL; + + *((long *)obj) = val; + return 0; +} + +static int parse_conf_str(snd_config_t *cfg, void *obj, size_t size) +{ + const char *id; + + if (snd_config_get_id(cfg, &id) < 0) + return -EINVAL; + strncpy(obj, id, size); + + return 0; +} + +static int parse_conf_format(snd_config_t *cfg, void *obj, size_t size) +{ + const char *id; + + if (snd_config_get_string(cfg, &id) < 0) + return -EINVAL; + + if (!strcmp("S16_LE", id)) { + *((long *)obj) = SND_PCM_FORMAT_S16_LE; + return 0; + } + if (!strcmp("S32_LE", id)) { + *((long *)obj) = SND_PCM_FORMAT_S32_LE; + return 0; + } + if (!strcmp("S24_4LE", id)) { + *((long *)obj) = SND_PCM_FORMAT_S24_LE; + return 0; + } + if (!strcmp("FLOAT", id)) { + *((long *)obj) = SND_PCM_FORMAT_FLOAT_LE; + return 0; + } + + /* not found */ + SNDERR("error: cant find format: %s", id); + return -EINVAL; +} + +struct config_item { + char *name; + size_t size; + size_t offset; + int (*copy)(snd_config_t *cfg, void *obj, size_t size); +}; + +struct config_item config_items[] = { + {"name", itemsize(struct plug_config, name), + offsetof(struct plug_config, name), parse_conf_str}, + {"rate", itemsize(struct plug_config, rate), + offsetof(struct plug_config, rate), parse_conf_long}, + {"format", itemsize(struct plug_config, format), + offsetof(struct plug_config, format), parse_conf_format}, + {"channels", itemsize(struct plug_config, channels), + offsetof(struct plug_config, channels), parse_conf_long}, + {"period_time", itemsize(struct plug_config, period_time), + offsetof(struct plug_config, period_time), parse_conf_long}, + {"period_frames", itemsize(struct plug_config, period_frames), + offsetof(struct plug_config, period_frames), parse_conf_long}, + {"buffer_time", itemsize(struct plug_config, buffer_time), + offsetof(struct plug_config, buffer_time), parse_conf_long}, + {"buffer_frames", itemsize(struct plug_config, buffer_frames), + offsetof(struct plug_config, buffer_frames), parse_conf_long}, +}; + +static int parse_item(snd_config_t *cfg, const char *id, struct plug_config *dest_cfg) +{ + void *dest = dest_cfg; + int i; + + for (i = 0; i < ARRAY_SIZE(config_items); i++) { + /* does ID match */ + if (strcmp(id, config_items[i].name)) + continue; + + /* now get the value */ + return config_items[i].copy(cfg, dest + config_items[i].offset, + config_items[i].size); + } + + /* not found - non fatal */ + return 0; +} + +static int parse_slave_configs(snd_sof_plug_t *plug, snd_config_t *n) +{ + snd_config_iterator_t si1, si2, snext1, snext2; + struct plug_config *config; + const char *id; + + fprintf(stdout, "Parsing ALSA conf for configs\n"); + + snd_config_for_each(si1, snext1, n) { + snd_config_t *sn1 = snd_config_iterator_entry(si1); + + config = &plug->config[plug->num_configs]; + + /* get config name */ + if (parse_item(sn1, "name", config) < 0) { + SNDERR("error: cant find config name"); + return -EINVAL; + } + + /* now get item values in each config */ + snd_config_for_each(si2, snext2, sn1) { + snd_config_t *sn2 = snd_config_iterator_entry(si2); + + if (snd_config_get_id(sn2, &id) < 0) + continue; + + if (parse_item(sn2, id, config) < 0) { + SNDERR("error: malformed config: %s", id); + return -EINVAL; + } + } + + fprintf(stdout, " config %d: %s\n", plug->num_configs, + config->name); + + /* next config */ + plug->num_configs++; + if (plug->num_configs >= PLUG_MAX_CONFIG) { + SNDERR("error: too many configs"); + return -EINVAL; + } + } + + return 0; +} + +/* + * Parse the client cmdline. Format is + * tplg:pcm:card:dev:config[dai_pipe:card:dev:config]...] + */ +static int parse_client_cmdline(snd_sof_plug_t *plug, char *cmdline) +{ + struct plug_cmdline_item *cmd_item; + char *tplg, *next, *card, *dev, *config, *pcm; + char *tplg_path = getenv("SOF_PLUGIN_TOPOLOGY_PATH"); + char tplg_file[128]; + int ret; + int i; + + if (!tplg_path) { + SNDERR("Invalid topology path. Please set the SOF_PLUGIN_TOPOLOGY_PATH env variable\n"); + return -EINVAL; + } + + /* get topology file */ + tplg = strtok_r(cmdline, ":", &next); + if (!tplg) { + SNDERR("invalid cmdline, cant find topology %s", cmdline); + return -EINVAL; + } + + /* now convert to filename and add the topology path */ + ret = snprintf(tplg_file, sizeof(tplg_file), "%ssof-%s.tplg", tplg_path, tplg); + if (ret < 0) { + SNDERR("invalid cmdline topology file %s", tplg); + return -EINVAL; + } + plug->tplg_file = strdup(tplg_file); + if (!plug->tplg_file) + return -ENOMEM; + + /* get PCM ID */ + pcm = strtok_r(next, ":", &next); + if (!pcm) { + SNDERR("invalid cmdline, cant find PCM %s", pcm); + return -EINVAL; + } + plug->pcm_id = atoi(pcm); + + fprintf(stdout, "Parsing cmd line\n"); + + cmd_item = &plug->cmdline[plug->num_cmdline]; + card = strtok_r(next, ":", &next); + if (!card) { + SNDERR("Invalid card name\n"); + return -EINVAL; + } + dev = strtok_r(next, ":", &next); + if (!dev) { + SNDERR("Invalid dev name\n"); + return -EINVAL; + } + config = strtok_r(next, ":", &next); + + /* tuple needs all three, any missing ? */ + if (!config) { + SNDERR("invalid cmdline, expected pcm(%s):card(%s):dev(%s):config(%s) from %s", + pcm, card, dev, config, tplg); + return -EINVAL; + } + + cmd_item->pcm = atoi(pcm); + strncpy(cmd_item->card_name, card, sizeof(cmd_item->card_name)); + strncpy(cmd_item->dev_name, dev, sizeof(cmd_item->dev_name)); + strncpy(cmd_item->config_name, config, sizeof(cmd_item->config_name)); + + /* + * dev name is special, we cant use "," in the command line + * so need to replace it with a "." and then later change it + * back to "," + */ + for (i = 0; i < sizeof(cmd_item->dev_name); i++) { + if (cmd_item->dev_name[i] != '.') + continue; + cmd_item->dev_name[i] = ','; + break; + } + + fprintf(stdout, " cmd %d: for pcm %d uses %s with PCM %s:%s\n", + plug->num_cmdline, cmd_item->pcm, cmd_item->config_name, + cmd_item->card_name, cmd_item->dev_name); + + plug->num_cmdline++; + + printf("plug: topology file %s with pipe %ld\n", plug->tplg_file, plug->tplg_pipeline); + return 0; +} + +/* + * Parse the ALSA conf for the SOF plugin and construct the command line options + * to be passed into the SOF pipe executable. + * TODO: verify all args + * TODO: validate all args. + * TODO: contruct sof pipe cmd line. + */ +int plug_parse_conf(snd_sof_plug_t *plug, const char *name, snd_config_t *root, + snd_config_t *conf) +{ + snd_config_iterator_t i, next; + const char *tplg = NULL; + + /* + * The topology filename and topology PCM need to be passed in. + * i.e. aplay -Dsof:tplg:pcm:[card:dev:config]...] + */ + snd_config_for_each(i, next, conf) { + snd_config_t *n = snd_config_iterator_entry(i); + const char *id; + + if (snd_config_get_id(n, &id) < 0) + continue; + + /* dont care */ + if (strcmp(id, "comment") == 0 || strcmp(id, "type") == 0 || + strcmp(id, "hint") == 0) + continue; + + /* client command line topology */ + if (strcmp(id, "tplg") == 0) { + if (snd_config_get_string(n, &tplg) < 0) { + SNDERR("Invalid type for %s", id); + return -EINVAL; + } else if (!*tplg) { + tplg = NULL; + } + continue; + } + + /* topology PCM configurations */ + if (strcmp(id, "config") == 0) { + if (parse_slave_configs(plug, n)) + return -EINVAL; + continue; + } + + /* not fatal - carry on and verify later */ + SNDERR("Unknown field %s", id); + } + + /* verify mandatory inputs are specified */ + if (!tplg) { + SNDERR("Missing topology topology"); + return -EINVAL; + } + + /* parse the client command line */ + if (parse_client_cmdline(plug, (char *)tplg)) { + SNDERR("invalid sof cmd line"); + return -EINVAL; + } + + return 0; +} diff --git a/tools/plugin/alsaplug/plugin.h b/tools/plugin/alsaplug/plugin.h new file mode 100644 index 000000000000..d0f6c85a1653 --- /dev/null +++ b/tools/plugin/alsaplug/plugin.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022-2023 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + */ + +#ifndef __SOF_PLUGIN_PLUGIN_H__ +#define __SOF_PLUGIN_PLUGIN_H__ + +#include +#include +#include "common.h" + +#include + +#define PLUG_MAX_CONFIG 128 + +typedef struct snd_sof_plug { + /* conf data */ + char *device; + + /* topology info */ + char *tplg_file; + long tplg_pipeline; // HACK, use configs + + /* number of configurations in plugin conf */ + struct plug_config config[PLUG_MAX_CONFIG]; + int num_configs; + + /* command line arguments */ + struct plug_cmdline_item cmdline[PLUG_MAX_CONFIG]; + int num_cmdline; + + /* topology */ + struct tplg_context tplg; + struct list_item widget_list; + struct list_item route_list; + struct list_item pcm_list; + struct list_item pipeline_list; + int instance_ids[SND_SOC_TPLG_DAPM_LAST]; + struct plug_mq_desc ipc_tx; + struct plug_mq_desc ipc_rx; + + int pcm_id; + struct tplg_pcm_info *pcm_info; + + snd_pcm_uframes_t period_size; + + void *module_prv; /* module private data */ +} snd_sof_plug_t; + +/* + * ALSA Conf + */ +int sofplug_load_hook(snd_config_t *root, snd_config_t *config, + snd_config_t **dst, snd_config_t *private_data); + +int plug_parse_conf(snd_sof_plug_t *plug, const char *name, + snd_config_t *root, snd_config_t *conf); +int plug_parse_topology(snd_sof_plug_t *plug); +int plug_set_up_pipelines(snd_sof_plug_t *plug, int dir); +int plug_free_pipelines(snd_sof_plug_t *plug, struct tplg_pipeline_list *pipeline_list, int dir); +void plug_free_topology(snd_sof_plug_t *plug); + +#endif diff --git a/tools/plugin/alsaplug/tplg.c b/tools/plugin/alsaplug/tplg.c new file mode 100644 index 000000000000..5b67b47aedfc --- /dev/null +++ b/tools/plugin/alsaplug/tplg.c @@ -0,0 +1,1479 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2018 Intel Corporation. All rights reserved. +// +// Author: Ranjani Sridharan +// Liam Girdwood + +/* Topology loader to set up components and pipeline */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include "plugin.h" + +#define FILE_READ 0 +#define FILE_WRITE 1 + +#define MAX_TPLG_OBJECT_SIZE 4096 + +//#include + +/* temporary - current MAXLEN is not define in UAPI header - fix pending */ +#ifndef SNDRV_CTL_ELEM_ID_NAME_MAXLEN +#define SNDRV_CTL_ELEM_ID_NAME_MAXLEN 44 +#endif +#include + +#define SOF_IPC4_FW_PAGE(x) ((((x) + BIT(12) - 1) & ~(BIT(12) - 1)) >> 12) +#define SOF_IPC4_FW_ROUNDUP(x) (((x) + BIT(6) - 1) & (~(BIT(6) - 1))) +#define SOF_IPC4_MODULE_INSTANCE_LIST_ITEM_SIZE 12 +#define SOF_IPC4_PIPELINE_OBJECT_SIZE 448 +#define SOF_IPC4_DATA_QUEUE_OBJECT_SIZE 128 +#define SOF_IPC4_LL_TASK_OBJECT_SIZE 72 +#define SOF_IPC4_LL_TASK_LIST_ITEM_SIZE 12 +#define SOF_IPC4_FW_MAX_QUEUE_COUNT 8 + +static const struct sof_topology_token ipc4_comp_tokens[] = { + {SOF_TKN_COMP_IS_PAGES, SND_SOC_TPLG_TUPLE_TYPE_WORD, tplg_token_get_uint32_t, + offsetof(struct ipc4_base_module_cfg, is_pages)}, +}; + +static int plug_parse_ipc4_comp_tokens(snd_sof_plug_t *plug, struct ipc4_base_module_cfg *base_cfg) +{ + struct tplg_context *ctx = &plug->tplg; + struct tplg_comp_info *comp_info = ctx->current_comp_info; + struct snd_soc_tplg_vendor_array *array = &ctx->widget->priv.array[0]; + int size = ctx->widget->priv.size; + int ret; + + ret = sof_parse_token_sets(base_cfg, ipc4_comp_tokens, ARRAY_SIZE(ipc4_comp_tokens), + array, size, 1, 0); + if (ret < 0) + return ret; + + return sof_parse_tokens(&comp_info->uuid, comp_ext_tokens, + ARRAY_SIZE(comp_ext_tokens), array, size); +} + +static void plug_setup_widget_ipc_msg(struct tplg_comp_info *comp_info) +{ + struct ipc4_module_init_instance *module_init = &comp_info->module_init; + + module_init->primary.r.type = SOF_IPC4_MOD_INIT_INSTANCE; + module_init->primary.r.module_id = comp_info->module_id; + module_init->primary.r.instance_id = comp_info->instance_id; + module_init->primary.r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_MODULE_MSG; + module_init->primary.r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST; +} + +static int plug_aif_in_out(snd_sof_plug_t *plug, int dir) +{ + struct tplg_context *ctx = &plug->tplg; + struct tplg_comp_info *comp_info = ctx->current_comp_info; + int ret; + + ret = tplg_parse_widget_audio_formats(ctx); + if (ret < 0) + return ret; + + comp_info->ipc_payload = calloc(sizeof(struct ipc4_base_module_cfg), 1); + if (!comp_info->ipc_payload) + return -ENOMEM; + + comp_info->ipc_size = sizeof(struct ipc4_base_module_cfg); + + if (dir == SOF_IPC_STREAM_PLAYBACK) { + comp_info->module_id = 0x96; + plug_setup_widget_ipc_msg(comp_info); + } else { + comp_info->module_id = 0x98; + plug_setup_widget_ipc_msg(comp_info); + } + + return 0; +} + +static int plug_dai_in_out(snd_sof_plug_t *plug, int dir) +{ + struct tplg_context *ctx = &plug->tplg; + struct tplg_comp_info *comp_info = ctx->current_comp_info; + int ret; + + ret = tplg_parse_widget_audio_formats(ctx); + if (ret < 0) + return ret; + + comp_info->ipc_payload = calloc(sizeof(struct ipc4_base_module_cfg), 1); + if (!comp_info->ipc_payload) + return -ENOMEM; + + comp_info->ipc_size = sizeof(struct ipc4_base_module_cfg); + + if (dir == SOF_IPC_STREAM_PLAYBACK) { + comp_info->module_id = 0x97; + plug_setup_widget_ipc_msg(comp_info); + } else { + comp_info->module_id = 0x99; + plug_setup_widget_ipc_msg(comp_info); + } + + return 0; +} + +static int plug_new_src_ipc(snd_sof_plug_t *plug) +{ + struct tplg_context *ctx = &plug->tplg; + char tplg_object[MAX_TPLG_OBJECT_SIZE] = {0}; + struct sof_ipc_comp_src *src = + (struct sof_ipc_comp_src *)tplg_object; + struct snd_soc_tplg_ctl_hdr *tplg_ctl; + int ret; + + tplg_ctl = calloc(ctx->hdr->payload_size, 1); + if (!tplg_ctl) + return -ENOMEM; + + ret = tplg_new_src(ctx, &src->comp, MAX_TPLG_OBJECT_SIZE, + tplg_ctl, ctx->hdr->payload_size); + if (ret < 0) { + SNDERR("error: failed to create src\n"); + goto out; + } + +out: + free(tplg_ctl); + return ret; +} + +static int plug_new_asrc_ipc(snd_sof_plug_t *plug) +{ + struct tplg_context *ctx = &plug->tplg; + char tplg_object[MAX_TPLG_OBJECT_SIZE] = {0}; + struct sof_ipc_comp_asrc *asrc = + (struct sof_ipc_comp_asrc *)tplg_object; + struct snd_soc_tplg_ctl_hdr *tplg_ctl; + int ret; + + tplg_ctl = calloc(ctx->hdr->payload_size, 1); + if (!tplg_ctl) + return -ENOMEM; + + ret = tplg_new_asrc(ctx, &asrc->comp, MAX_TPLG_OBJECT_SIZE, + tplg_ctl, ctx->hdr->payload_size); + if (ret < 0) { + SNDERR("error: failed to create PGA\n"); + goto out; + } + +out: + free(tplg_ctl); + return ret; +} + +static int plug_new_mixer(snd_sof_plug_t *plug) +{ + struct tplg_context *ctx = &plug->tplg; + struct tplg_comp_info *comp_info = ctx->current_comp_info; + char tplg_object[MAX_TPLG_OBJECT_SIZE] = {0}; + struct sof_ipc_comp_mixer *mixer = + (struct sof_ipc_comp_mixer *)tplg_object; + struct snd_soc_tplg_ctl_hdr *tplg_ctl; + int ret; + + tplg_ctl = calloc(ctx->hdr->payload_size, 1); + if (!tplg_ctl) + return -ENOMEM; + + comp_info->instance_id = plug->instance_ids[SND_SOC_TPLG_DAPM_MIXER]++; + comp_info->ipc_size = sizeof(struct ipc4_base_module_cfg); + comp_info->ipc_payload = calloc(comp_info->ipc_size, 1); + if (!comp_info->ipc_payload) + return -ENOMEM; + + ret = tplg_new_mixer(ctx, &mixer->comp, MAX_TPLG_OBJECT_SIZE, + tplg_ctl, ctx->hdr->payload_size); + if (ret < 0) { + SNDERR("error: failed to create mixer\n"); + goto out; + } + + if (strstr(comp_info->name, "mixin")) { + comp_info->module_id = 0x2; + plug_setup_widget_ipc_msg(comp_info); + } else { + comp_info->module_id = 0x3; + plug_setup_widget_ipc_msg(comp_info); + } +out: + free(tplg_ctl); + return ret; +} + +static int plug_new_pga(snd_sof_plug_t *plug) +{ + struct tplg_context *ctx = &plug->tplg; + struct tplg_comp_info *comp_info = ctx->current_comp_info; + struct ipc4_peak_volume_config volume; + struct snd_soc_tplg_ctl_hdr *tplg_ctl; + int ret; + + comp_info->ipc_size = + sizeof(struct ipc4_peak_volume_config) + sizeof(struct ipc4_base_module_cfg); + comp_info->ipc_payload = calloc(comp_info->ipc_size, 1); + if (!comp_info->ipc_payload) + return -ENOMEM; + + /* FIXME: move this to when the widget is actually set up */ + comp_info->instance_id = plug->instance_ids[SND_SOC_TPLG_DAPM_PGA]++; + comp_info->module_id = 0x6; + + tplg_ctl = calloc(ctx->hdr->payload_size, 1); + if (!tplg_ctl) { + free(comp_info->ipc_payload); + return -ENOMEM; + } + + ret = tplg_new_pga(ctx, &volume, sizeof(struct ipc4_peak_volume_config), + tplg_ctl, ctx->hdr->payload_size); + if (ret < 0) { + SNDERR("%s: failed to create PGA\n", __func__); + goto out; + } + + /* copy volume data to ipc_payload */ + memcpy(comp_info->ipc_payload + sizeof(struct ipc4_base_module_cfg), + &volume, sizeof(struct ipc4_peak_volume_config)); + + /* skip kcontrols for now */ + if (tplg_create_controls(ctx, ctx->widget->num_kcontrols, + tplg_ctl, ctx->hdr->payload_size, &volume) < 0) { + SNDERR("error: loading controls\n"); + goto out; + } + + plug_setup_widget_ipc_msg(comp_info); + + free(tplg_ctl); + + return ret; + +out: + free(tplg_ctl); + free(comp_info->ipc_payload); + + return ret; +} + +static int plug_new_process(snd_sof_plug_t *plug) +{ + struct tplg_context *ctx = &plug->tplg; + struct tplg_comp_info *comp_info = ctx->current_comp_info; + struct sof_ipc_comp_process *process; + struct snd_soc_tplg_ctl_hdr *tplg_ctl; + int ret; + + process = calloc(MAX_TPLG_OBJECT_SIZE, 1); + if (!process) + return -ENOMEM; + + comp_info->ipc_payload = process; + + tplg_ctl = calloc(ctx->hdr->payload_size, 1); + if (!tplg_ctl) { + free(process); + return -ENOMEM; + } + + ret = tplg_new_process(ctx, process, MAX_TPLG_OBJECT_SIZE, + tplg_ctl, ctx->hdr->payload_size); + if (ret < 0) { + SNDERR("error: failed to create PGA\n"); + goto out; + } +out: + free(tplg_ctl); + return ret; +} + +static int plug_new_pipeline(snd_sof_plug_t *plug) +{ + struct tplg_pipeline_info *pipe_info; + struct sof_ipc_pipe_new pipeline = {0}; + struct snd_soc_tplg_ctl_hdr *tplg_ctl; + struct tplg_context *ctx = &plug->tplg; + int ret; + + tplg_ctl = calloc(ctx->hdr->payload_size, 1); + if (!tplg_ctl) + return -ENOMEM; + + pipe_info = calloc(sizeof(struct tplg_pipeline_info), 1); + if (!pipe_info) { + ret = -ENOMEM; + goto out; + } + + pipe_info->name = strdup(ctx->widget->name); + if (!pipe_info->name) { + free(pipe_info); + goto out; + } + + pipe_info->id = ctx->pipeline_id; + + ret = tplg_new_pipeline(ctx, &pipeline, sizeof(pipeline), tplg_ctl); + if (ret < 0) { + SNDERR("error: failed to create pipeline\n"); + free(pipe_info->name); + free(pipe_info); + goto out; + } + + list_item_append(&pipe_info->item, &plug->pipeline_list); + tplg_debug("loading pipeline %s\n", pipe_info->name); +out: + free(tplg_ctl); + return ret; +} + +static int plug_new_buffer(snd_sof_plug_t *plug) +{ + struct ipc4_copier_module_cfg *copier = calloc(sizeof(struct ipc4_copier_module_cfg), 1); + struct tplg_context *ctx = &plug->tplg; + struct tplg_comp_info *comp_info = ctx->current_comp_info; + int ret; + + if (!copier) + return -ENOMEM; + + comp_info->ipc_payload = copier; + + ret = tplg_new_buffer(ctx, copier, sizeof(copier), NULL, 0); + if (ret < 0) { + SNDERR("error: failed to create pipeline\n"); + free(copier); + } + + return ret; +} + +/* Insert new comp info into the list of widgets */ +static inline int plug_insert_comp(snd_sof_plug_t *plug) +{ + struct tplg_context *ctx = &plug->tplg; + struct tplg_comp_info *comp_info; + int comp_id = ctx->comp_id; + int ret; + + if (ctx->widget->id == SND_SOC_TPLG_DAPM_SCHEDULER) + return 0; + + comp_info = calloc(sizeof(struct tplg_comp_info), 1); + if (!comp_info) + return -ENOMEM; + + comp_info->name = strdup(ctx->widget->name); + if (!comp_info->name) { + ret = -ENOMEM; + goto err; + } + + comp_info->stream_name = strdup(ctx->widget->sname); + if (!comp_info->stream_name) { + ret = -ENOMEM; + goto sname_err; + } + + comp_info->id = comp_id; + comp_info->type = ctx->widget->id; + comp_info->pipeline_id = ctx->pipeline_id; + ctx->current_comp_info = comp_info; + + ret = plug_parse_ipc4_comp_tokens(plug, &comp_info->basecfg); + if (ret < 0) + goto sname_err; + + list_item_append(&comp_info->item, &plug->widget_list); + + tplg_debug("debug: loading comp_id %d: widget %s type %d size %d at offset %ld is_pages %d\n", + comp_id, ctx->widget->name, ctx->widget->id, ctx->widget->size, + ctx->tplg_offset, comp_info->basecfg.is_pages); + + return 0; +sname_err: + free(comp_info->name); +err: + free(comp_info); + return ret; +} + +/* load dapm widget */ +static int plug_load_widget(snd_sof_plug_t *plug) +{ + struct tplg_context *ctx = &plug->tplg; + int ret = 0; + + /* get next widget */ + ctx->widget = tplg_get_widget(ctx); + ctx->widget_size = ctx->widget->size; + + /* insert widget into mapping */ + ret = plug_insert_comp(plug); + if (ret < 0) { + SNDERR("plug_load_widget: invalid widget index\n"); + return ret; + } + + /* load widget based on type */ + switch (ctx->widget->id) { + /* load pga widget */ + case SND_SOC_TPLG_DAPM_PGA: + if (plug_new_pga(plug) < 0) { + SNDERR("error: load pga\n"); + ret = -EINVAL; + goto exit; + } + break; + case SND_SOC_TPLG_DAPM_AIF_IN: + if (plug_aif_in_out(plug, SOF_IPC_STREAM_PLAYBACK) < 0) { + SNDERR("error: load AIF IN failed\n"); + ret = -EINVAL; + goto exit; + } + break; + case SND_SOC_TPLG_DAPM_AIF_OUT: + if (plug_aif_in_out(plug, SOF_IPC_STREAM_CAPTURE) < 0) { + SNDERR("error: load AIF OUT failed\n"); + ret = -EINVAL; + goto exit; + } + break; + case SND_SOC_TPLG_DAPM_DAI_IN: + if (plug_dai_in_out(plug, SOF_IPC_STREAM_PLAYBACK) < 0) { + SNDERR("error: load filewrite\n"); + ret = -EINVAL; + goto exit; + } + break; + case SND_SOC_TPLG_DAPM_DAI_OUT: + if (plug_dai_in_out(plug, SOF_IPC_STREAM_CAPTURE) < 0) { + SNDERR("error: load filewrite\n"); + ret = -EINVAL; + goto exit; + } + break; + + case SND_SOC_TPLG_DAPM_BUFFER: + if (plug_new_buffer(plug) < 0) { + SNDERR("error: load pipeline\n"); + ret = -EINVAL; + goto exit; + } + break; + + case SND_SOC_TPLG_DAPM_SCHEDULER: + if (plug_new_pipeline(plug) < 0) { + SNDERR("error: load pipeline\n"); + ret = -EINVAL; + goto exit; + } + break; + case SND_SOC_TPLG_DAPM_SRC: + if (plug_new_src_ipc(plug) < 0) { + SNDERR("error: load src\n"); + ret = -EINVAL; + goto exit; + } + break; + case SND_SOC_TPLG_DAPM_ASRC: + if (plug_new_asrc_ipc(plug) < 0) { + SNDERR("error: load asrc\n"); + ret = -EINVAL; + goto exit; + } + break; + + case SND_SOC_TPLG_DAPM_MIXER: + if (plug_new_mixer(plug) < 0) { + SNDERR("error: load mixer\n"); + ret = -EINVAL; + goto exit; + } + break; + case SND_SOC_TPLG_DAPM_EFFECT: + if (plug_new_process(plug) < 0) { + SNDERR("error: load effect\n"); + ret = -EINVAL; + goto exit; + } + break; + + /* unsupported widgets */ + default: + tplg_debug("info: Widget %s id %d unsupported and skipped: size %d priv size %d\n", + ctx->widget->name, ctx->widget->id, + ctx->widget->size, ctx->widget->priv.size); + +#if 0 + if (fseek(ctx->file, ctx->widget->priv.size, SEEK_CUR)) { + SNDERR("error: fseek unsupported widget\n"); + ret = -errno; + goto exit; + } + ret = tplg_create_controls(ctx->widget->num_kcontrols, ctx->file, NULL, 0); + if (ret < 0) { + SNDERR("error: loading controls\n"); + //goto exit; + } +#endif + ret = 0; + break; + } + + ret = 1; + +exit: + return ret; +} + +static int plug_register_graph(snd_sof_plug_t *plug, int count) +{ + struct tplg_context *ctx = &plug->tplg; + int ret = 0; + int i; + + for (i = 0; i < count; i++) { + ret = tplg_parse_graph(ctx, &plug->widget_list, &plug->route_list); + if (ret < 0) + return ret; + } + + return ret; +} + +static int plug_parse_pcm(snd_sof_plug_t *plug, int count) +{ + struct tplg_context *ctx = &plug->tplg; + int ret, i; + + for (i = 0; i < count; i++) { + ret = tplg_parse_pcm(ctx, &plug->widget_list, &plug->pcm_list); + if (ret < 0) + return ret; + } + + return 0; +} + +static void +plug_pipeline_update_resource_usage(snd_sof_plug_t *plug, struct tplg_comp_info *comp_info) +{ + struct ipc4_base_module_cfg *base_config = &comp_info->basecfg; + struct tplg_pipeline_info *pipe_info = comp_info->pipe_info; + int task_mem, queue_mem; + int ibs, bss, total; + + ibs = base_config->ibs; + bss = base_config->is_pages; + + task_mem = SOF_IPC4_PIPELINE_OBJECT_SIZE; + task_mem += SOF_IPC4_MODULE_INSTANCE_LIST_ITEM_SIZE + bss; + + /* LL modules */ + task_mem += SOF_IPC4_FW_ROUNDUP(SOF_IPC4_LL_TASK_OBJECT_SIZE); + task_mem += SOF_IPC4_FW_MAX_QUEUE_COUNT * SOF_IPC4_MODULE_INSTANCE_LIST_ITEM_SIZE; + task_mem += SOF_IPC4_LL_TASK_LIST_ITEM_SIZE; + + ibs = SOF_IPC4_FW_ROUNDUP(ibs); + queue_mem = SOF_IPC4_FW_MAX_QUEUE_COUNT * (SOF_IPC4_DATA_QUEUE_OBJECT_SIZE + ibs); + + total = SOF_IPC4_FW_PAGE(task_mem + queue_mem); + + pipe_info->mem_usage += total; +} + +static int plug_is_single_format(struct sof_ipc4_pin_format *fmts, int num_formats) +{ + struct sof_ipc4_pin_format *fmt = &fmts[0]; + uint32_t _rate, _channels, _valid_bits; + int i; + + _rate = fmt->audio_fmt.sampling_frequency; + _channels = fmt->audio_fmt.fmt_cfg & MASK(7, 0); + _valid_bits = (fmt->audio_fmt.fmt_cfg & MASK(15, 8)) >> 8; + for (i = 1; i < num_formats; i++) { + struct sof_ipc4_pin_format *fmt = &fmts[i]; + uint32_t rate, channels, valid_bits; + + rate = fmt->audio_fmt.sampling_frequency; + channels = fmt->audio_fmt.fmt_cfg & MASK(7, 0); + valid_bits = (fmt->audio_fmt.fmt_cfg & MASK(15, 8)) >> 8; + if (rate != _rate || channels != _channels || valid_bits != _valid_bits) + return false; + } + + return true; +} + +static int plug_match_audio_format(snd_sof_plug_t *plug, struct tplg_comp_info *comp_info, + struct plug_config *config) +{ + struct sof_ipc4_available_audio_format *available_fmt = &comp_info->available_fmt; + struct ipc4_base_module_cfg *base_cfg = &comp_info->basecfg; + struct sof_ipc4_pin_format *fmt; + int config_valid_bits; + int i; + + switch (config->format) { + case SND_PCM_FORMAT_S16_LE: + config_valid_bits = 16; + break; + case SND_PCM_FORMAT_S32_LE: + config_valid_bits = 32; + break; + case SND_PCM_FORMAT_S24_LE: + config_valid_bits = 24; + break; + default: + break; + } + + if (plug_is_single_format(available_fmt->input_pin_fmts, + available_fmt->num_input_formats)) { + fmt = &available_fmt->input_pin_fmts[0]; + goto out; + } + + for (i = 0; i < available_fmt->num_input_formats; i++) { + uint32_t rate, channels, valid_bits; + + fmt = &available_fmt->input_pin_fmts[i]; + + rate = fmt->audio_fmt.sampling_frequency; + channels = fmt->audio_fmt.fmt_cfg & MASK(7, 0); + valid_bits = (fmt->audio_fmt.fmt_cfg & MASK(15, 8)) >> 8; + + if (rate == config->rate && channels == config->channels && + valid_bits == config_valid_bits) + break; + } + + if (i == available_fmt->num_input_formats) { + SNDERR("Cannot find matching format for rate %d channels %d valid_bits %d for %s\n", + config->rate, config->channels, config_valid_bits, comp_info->name); + return -EINVAL; + } +out: + + base_cfg->audio_fmt.sampling_frequency = fmt->audio_fmt.sampling_frequency; + base_cfg->audio_fmt.depth = fmt->audio_fmt.bit_depth; + base_cfg->audio_fmt.ch_map = fmt->audio_fmt.ch_map; + base_cfg->audio_fmt.ch_cfg = fmt->audio_fmt.ch_cfg; + base_cfg->audio_fmt.interleaving_style = fmt->audio_fmt.interleaving_style; + base_cfg->audio_fmt.channels_count = fmt->audio_fmt.fmt_cfg & MASK(7, 0); + base_cfg->audio_fmt.valid_bit_depth = + (fmt->audio_fmt.fmt_cfg & MASK(15, 8)) >> 8; + base_cfg->audio_fmt.s_type = + (fmt->audio_fmt.fmt_cfg & MASK(23, 16)) >> 16; + base_cfg->ibs = fmt->buffer_size; + + /* + * FIXME: is this correct? Choose ALSA period size for obs so that the buffer sizes + * will set accodingly. Need to get channel count and format from output format + */ + base_cfg->obs = plug->period_size * 2 * 2; + + return 0; +} + +static int plug_set_up_widget_base_config(snd_sof_plug_t *plug, struct tplg_comp_info *comp_info) +{ + struct plug_cmdline_item *cmd_item = &plug->cmdline[0]; + struct plug_config *config; + bool config_found = false; + int ret, i; + + for (i < 0; i < plug->num_configs; i++) { + config = &plug->config[i]; + + if (!strcmp(config->name, cmd_item->config_name)) { + config_found = true; + break; + } + } + + if (!config_found) { + SNDERR("unsupported config requested %s\n", cmd_item->config_name); + return -ENOTSUP; + } + + /* match audio formats and populate base config */ + ret = plug_match_audio_format(plug, comp_info, config); + if (ret < 0) + return ret; + + /* copy the basecfg into the ipc payload */ + memcpy(comp_info->ipc_payload, &comp_info->basecfg, sizeof(struct ipc4_base_module_cfg)); + + return 0; +} + +/* parse topology file and set up pipeline */ +int plug_parse_topology(snd_sof_plug_t *plug) + +{ + struct tplg_context *ctx = &plug->tplg; + struct snd_soc_tplg_hdr *hdr; + struct list_item *item; + char pipeline_string[256] = {0}; + int i; + int ret = 0; + FILE *file; + size_t size; + + tplg_debug("parsing topology file %s\n", ctx->tplg_file); + + /* TODO: ctl callback */ +// ctx->ctl_arg = sp; +// ctx->ctl_cb = pipe_kcontrol_cb_new; + + /* open topology file */ + file = fopen(ctx->tplg_file, "rb"); + if (!file) { + SNDERR("error: can't open topology %s : %s\n", ctx->tplg_file, strerror(errno)); + return -errno; + } + + /* file size */ + if (fseek(file, 0, SEEK_END)) { + SNDERR("error: can't seek to end of topology: %s\n", strerror(errno)); + fclose(file); + return -errno; + } + ctx->tplg_size = ftell(file); + if (fseek(file, 0, SEEK_SET)) { + SNDERR("error: can't seek to beginning of topology: %s\n", strerror(errno)); + fclose(file); + return -errno; + } + + /* load whole topology into memory */ + ctx->tplg_base = calloc(ctx->tplg_size, 1); + if (!ctx->tplg_base) { + SNDERR("error: can't alloc buffer for topology %zu bytes\n", ctx->tplg_size); + fclose(file); + return -ENOMEM; + } + ret = fread(ctx->tplg_base, ctx->tplg_size, 1, file); + if (ret != 1) { + SNDERR("error: can't read topology: %s\n", + strerror(errno)); + fclose(file); + return -errno; + } + fclose(file); + + /* initialize widget, route, pipeline and pcm lists */ + list_init(&plug->widget_list); + list_init(&plug->route_list); + list_init(&plug->pcm_list); + list_init(&plug->pipeline_list); + + while (ctx->tplg_offset < ctx->tplg_size) { + /* read next topology header */ + hdr = tplg_get_hdr(ctx); + + tplg_debug("type: %x, size: 0x%x count: %d index: %d\n", + hdr->type, hdr->payload_size, hdr->count, hdr->index); + + ctx->hdr = hdr; + + /* parse header and load the next block based on type */ + switch (hdr->type) { + /* load dapm widget */ + case SND_SOC_TPLG_TYPE_DAPM_WIDGET: + tplg_debug("number of DAPM widgets %d\n", hdr->count); + + /* update max pipeline_id */ + ctx->pipeline_id = hdr->index; + + for (i = 0; i < hdr->count; i++) { + ret = plug_load_widget(plug); + if (ret < 0) { + SNDERR("error: loading widget\n"); + return ret; + } + ctx->comp_id++; + } + break; + /* set up component connections from pipeline graph */ + case SND_SOC_TPLG_TYPE_DAPM_GRAPH: + if (plug_register_graph(plug, hdr->count) < 0) { + SNDERR("error: pipeline graph\n"); + return -EINVAL; + } + break; + /* parse PCM info */ + case SND_SOC_TPLG_TYPE_PCM: + ret = plug_parse_pcm(plug, hdr->count); + if (ret < 0) + goto out; + break; + default: + tplg_debug("%s %d\n", __func__, __LINE__); + tplg_skip_hdr_payload(ctx); + break; + } + } + + /* assign pipeline to every widget in the widget list */ + list_for_item(item, &plug->widget_list) { + struct tplg_comp_info *comp_info = container_of(item, struct tplg_comp_info, item); + struct list_item *pipe_item; + + list_for_item(pipe_item, &plug->pipeline_list) { + struct tplg_pipeline_info *pipe_info; + + pipe_info = container_of(pipe_item, struct tplg_pipeline_info, item); + if (pipe_info->id == comp_info->pipeline_id) { + comp_info->pipe_info = pipe_info; + break; + } + } + + if (!comp_info->pipe_info) { + SNDERR("Error assigning pipeline for %s\n", comp_info->name); + return -EINVAL; + } + } +out: + return ret; +} + +static int plug_set_up_widget_ipc(snd_sof_plug_t *plug, struct tplg_comp_info *comp_info) +{ + struct ipc4_module_init_instance *module_init = &comp_info->module_init; + struct ipc4_message_reply reply; + void *msg; + int size, ret; + + module_init->extension.r.param_block_size = comp_info->ipc_size >> 2; + module_init->extension.r.ppl_instance_id = comp_info->pipe_info->instance_id; + + size = sizeof(*module_init) + comp_info->ipc_size; + msg = calloc(size, 1); + if (!msg) + return -ENOMEM; + + memcpy(msg, module_init, sizeof(*module_init)); + memcpy(msg + sizeof(*module_init), comp_info->ipc_payload, comp_info->ipc_size); + + ret = plug_mq_cmd_tx_rx(&plug->ipc_tx, &plug->ipc_rx, + msg, size, &reply, sizeof(reply)); + free(msg); + if (ret < 0) { + SNDERR("error: can't set up widget %s\n", comp_info->name); + return ret; + } + + if (reply.primary.r.status != IPC4_SUCCESS) { + SNDERR("widget %s set up failed with status %d\n", + comp_info->name, reply.primary.r.status); + return -EINVAL; + } + return 0; +} + +static int plug_set_up_pipeline(snd_sof_plug_t *plug, struct tplg_pipeline_info *pipe_info) +{ + struct ipc4_pipeline_create msg; + struct ipc4_message_reply reply; + int ret; + + msg.primary.r.type = SOF_IPC4_GLB_CREATE_PIPELINE; + msg.primary.r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG; + msg.primary.r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST; + pipe_info->instance_id = plug->instance_ids[SND_SOC_TPLG_DAPM_SCHEDULER]++; + msg.primary.r.instance_id = pipe_info->instance_id; + msg.primary.r.ppl_mem_size = pipe_info->mem_usage; + + ret = plug_mq_cmd_tx_rx(&plug->ipc_tx, &plug->ipc_rx, + &msg, sizeof(msg), &reply, sizeof(reply)); + if (ret < 0) { + SNDERR("error: can't set up pipeline %s\n", pipe_info->name); + return ret; + } + + if (reply.primary.r.status != IPC4_SUCCESS) { + SNDERR("pipeline %s instance ID %d set up failed with status %d\n", + pipe_info->name, pipe_info->instance_id, reply.primary.r.status); + return -EINVAL; + } + + tplg_debug("pipeline %s instance_id %d mem_usage %d set up\n", pipe_info->name, + pipe_info->instance_id, pipe_info->mem_usage); + + return 0; +} + +static int plug_prepare_widget(snd_sof_plug_t *plug, struct tplg_pcm_info *pcm_info, + struct tplg_comp_info *comp_info, int dir) +{ + struct tplg_pipeline_list *pipeline_list; + int ret, i; + + if (dir) + pipeline_list = &pcm_info->capture_pipeline_list; + else + pipeline_list = &pcm_info->playback_pipeline_list; + + /* populate base config */ + ret = plug_set_up_widget_base_config(plug, comp_info); + if (ret < 0) + return ret; + + plug_pipeline_update_resource_usage(plug, comp_info); + + /* add pipeline to pcm pipeline_list if needed */ + for (i = 0; i < pipeline_list->count; i++) { + struct tplg_pipeline_info *pipe_info = pipeline_list->pipelines[i]; + + if (pipe_info == comp_info->pipe_info) + break; + } + + if (i == pipeline_list->count) { + pipeline_list->pipelines[pipeline_list->count] = comp_info->pipe_info; + pipeline_list->count++; + } + + tplg_debug("widget %s prepared\n", comp_info->name); + return 0; +} + +static int plug_prepare_widgets(snd_sof_plug_t *plug, struct tplg_pcm_info *pcm_info, + struct tplg_comp_info *starting_comp_info, + struct tplg_comp_info *current_comp_info) +{ + struct list_item *item; + int ret; + + /* for playback */ + list_for_item(item, &plug->route_list) { + struct tplg_route_info *route_info = container_of(item, struct tplg_route_info, + item); + + if (route_info->source != current_comp_info) + continue; + + /* set up source widget if it is the starting widget */ + if (starting_comp_info == current_comp_info) { + ret = plug_prepare_widget(plug, pcm_info, current_comp_info, 0); + if (ret < 0) + return ret; + } + + /* set up the sink widget */ + ret = plug_prepare_widget(plug, pcm_info, route_info->sink, 0); + if (ret < 0) + return ret; + + /* and then continue down the path */ + if (route_info->sink->type != SND_SOC_TPLG_DAPM_DAI_IN || + route_info->sink->type != SND_SOC_TPLG_DAPM_DAI_OUT) { + ret = plug_prepare_widgets(plug, pcm_info, starting_comp_info, + route_info->sink); + if (ret < 0) + return ret; + } + } + + return 0; +} + +static int plug_prepare_widgets_capture(snd_sof_plug_t *plug, struct tplg_pcm_info *pcm_info, + struct tplg_comp_info *starting_comp_info, + struct tplg_comp_info *current_comp_info) +{ + struct list_item *item; + int ret; + + /* for playback */ + list_for_item(item, &plug->route_list) { + struct tplg_route_info *route_info = container_of(item, struct tplg_route_info, + item); + + if (route_info->sink != current_comp_info) + continue; + + /* set up sink widget if it is the starting widget */ + if (starting_comp_info == current_comp_info) { + ret = plug_prepare_widget(plug, pcm_info, current_comp_info, 1); + if (ret < 0) + return ret; + } + + /* set up the source widget */ + ret = plug_prepare_widget(plug, pcm_info, route_info->source, 1); + if (ret < 0) + return ret; + + /* and then continue up the path */ + if (route_info->source->type != SND_SOC_TPLG_DAPM_DAI_IN && + route_info->source->type != SND_SOC_TPLG_DAPM_DAI_OUT) { + ret = plug_prepare_widgets(plug, pcm_info, starting_comp_info, + route_info->source); + if (ret < 0) + return ret; + } + } + + return 0; +} + +static int plug_set_up_route(snd_sof_plug_t *plug, struct tplg_route_info *route_info) +{ + struct tplg_comp_info *src_comp_info = route_info->source; + struct tplg_comp_info *sink_comp_info = route_info->sink; + struct ipc4_module_bind_unbind bu; + struct ipc4_message_reply reply; + int ret; + + bu.primary.r.module_id = src_comp_info->module_id; + bu.primary.r.instance_id = src_comp_info->instance_id; + bu.primary.r.type = SOF_IPC4_MOD_BIND; + bu.primary.r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_MODULE_MSG; + bu.primary.r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST; + + bu.extension.r.dst_module_id = sink_comp_info->module_id; + bu.extension.r.dst_instance_id = sink_comp_info->instance_id; + + /* FIXME: assign queue ID for components with multiple inputs/outputs */ + bu.extension.r.dst_queue = 0; + bu.extension.r.src_queue = 0; + + ret = plug_mq_cmd_tx_rx(&plug->ipc_tx, &plug->ipc_rx, + &bu, sizeof(bu), &reply, sizeof(reply)); + if (ret < 0) { + SNDERR("error: can't set up route %s -> %s\n", src_comp_info->name, + sink_comp_info->name); + return ret; + } + + if (reply.primary.r.status != IPC4_SUCCESS) { + SNDERR("route %s -> %s ID set up failed with status %d\n", + src_comp_info->name, sink_comp_info->name, reply.primary.r.status); + return -EINVAL; + } + + tplg_debug("route %s -> %s set up\n", src_comp_info->name, sink_comp_info->name); + + return 0; +} + +static int plug_set_up_widget(snd_sof_plug_t *plug, struct tplg_comp_info *comp_info) +{ + struct tplg_pipeline_info *pipe_info = comp_info->pipe_info; + int ret; + + pipe_info->usage_count++; + + /* first set up pipeline if needed, only done once for the first pipeline widget */ + if (pipe_info->usage_count == 1) { + ret = plug_set_up_pipeline(plug, pipe_info); + if (ret < 0) { + pipe_info->usage_count--; + return ret; + } + } + + /* now set up the widget */ + ret = plug_set_up_widget_ipc(plug, comp_info); + if (ret < 0) + return ret; + + tplg_debug("widget %s set up\n", comp_info->name); + + return 0; +} + +static int plug_set_up_widgets(snd_sof_plug_t *plug, struct tplg_comp_info *starting_comp_info, + struct tplg_comp_info *current_comp_info) +{ + struct list_item *item; + int ret; + + /* for playback */ + list_for_item(item, &plug->route_list) { + struct tplg_route_info *route_info = container_of(item, struct tplg_route_info, + item); + + if (route_info->source != current_comp_info) + continue; + + /* set up source widget if it is the starting widget */ + if (starting_comp_info == current_comp_info) { + ret = plug_set_up_widget(plug, current_comp_info); + if (ret < 0) + return ret; + } + + /* set up the sink widget */ + ret = plug_set_up_widget(plug, route_info->sink); + if (ret < 0) + return ret; + + /* source and sink widgets are up, so set up route now */ + ret = plug_set_up_route(plug, route_info); + if (ret < 0) + return ret; + + /* and then continue down the path */ + if (route_info->sink->type != SND_SOC_TPLG_DAPM_DAI_IN || + route_info->sink->type != SND_SOC_TPLG_DAPM_DAI_OUT) { + ret = plug_set_up_widgets(plug, starting_comp_info, route_info->sink); + if (ret < 0) + return ret; + } + } + + return 0; +} + +static int plug_set_up_widgets_capture(snd_sof_plug_t *plug, + struct tplg_comp_info *starting_comp_info, + struct tplg_comp_info *current_comp_info) +{ + struct list_item *item; + int ret; + + /* for playback */ + list_for_item(item, &plug->route_list) { + struct tplg_route_info *route_info = container_of(item, struct tplg_route_info, + item); + + if (route_info->sink != current_comp_info) + continue; + + /* set up source widget if it is the starting widget */ + if (starting_comp_info == current_comp_info) { + ret = plug_set_up_widget(plug, current_comp_info); + if (ret < 0) + return ret; + } + + /* set up the sink widget */ + ret = plug_set_up_widget(plug, route_info->source); + if (ret < 0) + return ret; + + /* source and sink widgets are up, so set up route now */ + ret = plug_set_up_route(plug, route_info); + if (ret < 0) + return ret; + + /* and then continue down the path */ + if (route_info->source->type != SND_SOC_TPLG_DAPM_DAI_IN && + route_info->source->type != SND_SOC_TPLG_DAPM_DAI_OUT) { + ret = plug_set_up_widgets(plug, starting_comp_info, route_info->source); + if (ret < 0) + return ret; + } + } + + return 0; +} + +int plug_set_up_pipelines(snd_sof_plug_t *plug, int dir) +{ + struct tplg_comp_info *host = NULL; + struct tplg_pcm_info *pcm_info; + struct list_item *item; + int ret; + + list_for_item(item, &plug->pcm_list) { + pcm_info = container_of(item, struct tplg_pcm_info, item); + + if (pcm_info->id == plug->pcm_id) { + if (dir) + host = pcm_info->capture_host; + else + host = pcm_info->playback_host; + break; + } + } + + if (!host) { + SNDERR("No host component found for PCM ID: %d\n", plug->pcm_id); + return -EINVAL; + } + + plug->pcm_info = pcm_info; + + if (dir) { + ret = plug_prepare_widgets_capture(plug, pcm_info, host, host); + if (ret < 0) + return ret; + + ret = plug_set_up_widgets_capture(plug, host, host); + if (ret < 0) + return ret; + + tplg_debug("Setting up capture pipelines complete\n"); + + return 0; + } + + ret = plug_prepare_widgets(plug, pcm_info, host, host); + if (ret < 0) + return ret; + + ret = plug_set_up_widgets(plug, host, host); + if (ret < 0) + return ret; + + tplg_debug("Setting up playback pipelines complete\n"); + + return 0; +} + +static int plug_delete_pipeline(snd_sof_plug_t *plug, struct tplg_pipeline_info *pipe_info) +{ + struct ipc4_pipeline_delete msg; + struct ipc4_message_reply reply; + int ret; + + msg.primary.r.type = SOF_IPC4_GLB_DELETE_PIPELINE; + msg.primary.r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG; + msg.primary.r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST; + msg.primary.r.instance_id = pipe_info->instance_id; + + ret = plug_mq_cmd_tx_rx(&plug->ipc_tx, &plug->ipc_rx, + &msg, sizeof(msg), &reply, sizeof(reply)); + if (ret < 0) { + SNDERR("error: can't delete pipeline %s\n", pipe_info->name); + return ret; + } + + if (reply.primary.r.status != IPC4_SUCCESS) { + SNDERR("pipeline %s instance ID %d delete failed with status %d\n", + pipe_info->name, pipe_info->instance_id, reply.primary.r.status); + return -EINVAL; + } + + tplg_debug("pipeline %s instance_id %d freed\n", pipe_info->name, + pipe_info->instance_id); + + return 0; +} + +static int plug_free_route(snd_sof_plug_t *plug, struct tplg_route_info *route_info) +{ + struct tplg_comp_info *src_comp_info = route_info->source; + struct tplg_comp_info *sink_comp_info = route_info->sink; + struct ipc4_module_bind_unbind bu; + struct ipc4_message_reply reply; + int ret; + + /* only unbind when widgets belong to separate pipelines */ + if (src_comp_info->pipeline_id == sink_comp_info->pipeline_id) + return 0; + + bu.primary.r.module_id = src_comp_info->module_id; + bu.primary.r.instance_id = src_comp_info->instance_id; + bu.primary.r.type = SOF_IPC4_MOD_UNBIND; + bu.primary.r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_MODULE_MSG; + bu.primary.r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST; + + bu.extension.r.dst_module_id = sink_comp_info->module_id; + bu.extension.r.dst_instance_id = sink_comp_info->instance_id; + + /* FIXME: assign queue ID for components with multiple inputs/outputs */ + bu.extension.r.dst_queue = 0; + bu.extension.r.src_queue = 0; + + ret = plug_mq_cmd_tx_rx(&plug->ipc_tx, &plug->ipc_rx, + &bu, sizeof(bu), &reply, sizeof(reply)); + if (ret < 0) { + SNDERR("error: can't set up route %s -> %s\n", src_comp_info->name, + sink_comp_info->name); + return ret; + } + + if (reply.primary.r.status != IPC4_SUCCESS) { + SNDERR("route %s -> %s ID set up failed with status %d\n", + src_comp_info->name, sink_comp_info->name, reply.primary.r.status); + return -EINVAL; + } + + tplg_debug("route %s -> %s freed\n", src_comp_info->name, sink_comp_info->name); + + return 0; +} + +static int plug_free_widgets(snd_sof_plug_t *plug, struct tplg_comp_info *starting_comp_info, + struct tplg_comp_info *current_comp_info) +{ + struct list_item *item; + int ret; + + /* for playback */ + list_for_item(item, &plug->route_list) { + struct tplg_route_info *route_info = container_of(item, struct tplg_route_info, + item); + + if (route_info->source != current_comp_info) + continue; + + /* Widgets will be freed when the pipeline is deleted, so just unbind modules */ + ret = plug_free_route(plug, route_info); + if (ret < 0) + return ret; + + /* and then continue down the path */ + if (route_info->sink->type != SND_SOC_TPLG_DAPM_DAI_IN || + route_info->sink->type != SND_SOC_TPLG_DAPM_DAI_OUT) { + ret = plug_free_widgets(plug, starting_comp_info, route_info->sink); + if (ret < 0) + return ret; + } + } + + return 0; +} + +static int plug_free_widgets_capture(snd_sof_plug_t *plug, + struct tplg_comp_info *starting_comp_info, + struct tplg_comp_info *current_comp_info) +{ + struct list_item *item; + int ret; + + /* for playback */ + list_for_item(item, &plug->route_list) { + struct tplg_route_info *route_info = container_of(item, struct tplg_route_info, + item); + + if (route_info->sink != current_comp_info) + continue; + + /* Widgets will be freed when the pipeline is deleted, so just unbind modules */ + ret = plug_free_route(plug, route_info); + if (ret < 0) + return ret; + + /* and then continue down the path */ + if (route_info->sink->type != SND_SOC_TPLG_DAPM_DAI_IN && + route_info->sink->type != SND_SOC_TPLG_DAPM_DAI_OUT) { + ret = plug_free_widgets(plug, starting_comp_info, route_info->source); + if (ret < 0) + return ret; + } + } + + return 0; +} + +int plug_free_pipelines(snd_sof_plug_t *plug, struct tplg_pipeline_list *pipeline_list, int dir) +{ + struct tplg_comp_info *host = NULL; + struct tplg_pcm_info *pcm_info; + struct list_item *item; + int ret, i; + + list_for_item(item, &plug->pcm_list) { + pcm_info = container_of(item, struct tplg_pcm_info, item); + + if (pcm_info->id == plug->pcm_id) { + host = pcm_info->playback_host; /* FIXME */ + break; + } + } + + if (!host) { + SNDERR("No host component found for PCM ID: %d\n", plug->pcm_id); + return -EINVAL; + } + + if (dir) { + } else { + ret = plug_free_widgets(plug, host, host); + if (ret < 0) { + SNDERR("failed to free widgets for PCM %d\n", plug->pcm_id); + return ret; + } + } + + for (i = 0; i < pipeline_list->count; i++) { + struct tplg_pipeline_info *pipe_info = pipeline_list->pipelines[i]; + + ret = plug_delete_pipeline(plug, pipe_info); + if (ret < 0) + return ret; + } + + plug->instance_ids[SND_SOC_TPLG_DAPM_SCHEDULER] = 0; + return 0; +} + +void plug_free_topology(snd_sof_plug_t *plug) +{ + struct list_item *item, *_item; + + list_for_item_safe(item, _item, &plug->pcm_list) { + struct tplg_pcm_info *pcm_info = container_of(item, struct tplg_pcm_info, item); + + free(pcm_info->name); + free(pcm_info); + } + + list_for_item_safe(item, _item, &plug->widget_list) { + struct tplg_comp_info *comp_info = container_of(item, struct tplg_comp_info, item); + + free(comp_info->name); + free(comp_info->stream_name); + free(comp_info->ipc_payload); + free(comp_info); + } + + list_for_item_safe(item, _item, &plug->route_list) { + struct tplg_route_info *route_info = container_of(item, struct tplg_route_info, + item); + + free(route_info); + } + + list_for_item_safe(item, _item, &plug->pipeline_list) { + struct tplg_pipeline_info *pipe_info = container_of(item, struct tplg_pipeline_info, + item); + + free(pipe_info->name); + free(pipe_info); + } + + tplg_debug("freed all pipelines, widgets, routes and pcms\n"); +} diff --git a/tools/plugin/common.c b/tools/plugin/common.c new file mode 100644 index 000000000000..d9bb1c7bb6ba --- /dev/null +++ b/tools/plugin/common.c @@ -0,0 +1,180 @@ +/*-*- linux-c -*-*/ + +/* + * ALSA <-> SOF PCM I/O plugin + * + * Copyright (c) 2022 by Liam Girdwood + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +/* + * Timing + */ +void plug_timespec_add_ms(struct timespec *ts, unsigned long ms) +{ + long ns; + long secs = ms / 1000; + + /* get ms remainder */ + ms = ms - (secs * 1000); + ns = ms * 1000000; + + ts->tv_nsec += ns; + if (ts->tv_nsec > 1000000000) { + secs++; + ts->tv_nsec -= 1000000000; + } + ts->tv_sec += (secs + DEBUG_TV_SECS); +} + +long plug_timespec_delta_ns(struct timespec *before, struct timespec *after) +{ + long ns; + + ns = (after->tv_sec - before->tv_sec) * 1000000000; + ns += after->tv_nsec - before->tv_nsec; + + return ns; +} + +static const char *suffix_name(const char *longname) +{ + size_t len = strlen(longname); + int i = len; + + /* longname name invalid */ + if (len < 1) { + SNDERR("invalid topology long name\n"); + return NULL; + } + + /* find the last '/' in the longname topology path */ + while (--i >= 0) { + if (longname[i] == '/') { + i += 1; /* skip / */ + return &longname[i]; + } + } + + /* no / in topology path, so use full path */ + return longname; +} + +/* + * IPC + * + * POSIX message queues are used for interprocess IPC messaging. + */ + +/* + * Initialise the IPC object. + */ +int plug_mq_init(struct plug_mq_desc *ipc, const char *tplg, const char *type, int index) +{ + const char *name = suffix_name(tplg); + + if (!name) + return -EINVAL; + + snprintf(ipc->queue_name, NAME_SIZE, "/mq-%s-%s-%d", type, name, index); + return 0; +} + +/* + * Locking + * + * POSIX semaphores are used to block and synchronise audio between + * different threads and processes. + */ + +/* + * Initialise the lock object. + */ +int plug_lock_init(struct plug_sem_desc *lock, const char *tplg, const char *type, int index) +{ + const char *name = suffix_name(tplg); + + if (!name) + return -EINVAL; + + /* semaphores need the leading / */ + snprintf(lock->name, NAME_SIZE, "/lock-%s-%s-%d", name, type, index); + + return 0; +} + +/* + * SHM + * + * Shared memory is used for audio data and audio context sharing between + * threads and processes. + */ + +/* + * Initialise the SHM object. + */ +int plug_shm_init(struct plug_shm_desc *shm, const char *tplg, const char *type, int index) +{ + const char *name = suffix_name(tplg); + + if (!name) + return -EINVAL; + + snprintf(shm->name, NAME_SIZE, "/shm-%s-%s-%d", name, type, index); + shm->size = SHM_SIZE; + + return 0; +} + +/* + * Open an existing shared memory region using the SHM object. + */ +int plug_shm_open(struct plug_shm_desc *shm) +{ + struct stat status; + + /* open SHM to be used for low latency position */ + shm->fd = shm_open(shm->name, O_RDWR, + S_IRWXU | S_IRWXG); + if (shm->fd < 0) { + //SNDERR("failed to open SHM position %s: %s\n", + // shm->name, strerror(errno)); + return -errno; + } + + fstat(shm->fd, &status); + /* map it locally for context readback */ + shm->addr = mmap(NULL, status.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm->fd, 0); + if (!shm->addr) { + SNDERR("failed to mmap SHM position%s: %s\n", shm->name, strerror(errno)); + return -errno; + } + + return 0; +} + diff --git a/tools/plugin/common.h b/tools/plugin/common.h new file mode 100644 index 000000000000..c6e9225567d4 --- /dev/null +++ b/tools/plugin/common.h @@ -0,0 +1,316 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022-2023 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + */ + +#ifndef __SOF_PLUGIN_COMMON_H__ +#define __SOF_PLUGIN_COMMON_H__ + +#include +#include +#include +#include + +/* temporary - current MAXLEN is not define in UAPI header - fix pending */ +#ifndef SNDRV_CTL_ELEM_ID_NAME_MAXLEN +#define SNDRV_CTL_ELEM_ID_NAME_MAXLEN 44 +#endif + +#include + +#define IPC3_MAX_MSG_SIZE 384 +#define NAME_SIZE 256 + +#define MAX_CTLS 256 + +#define MS_TO_US(_msus) (_msus * 1000) +#define MS_TO_NS(_msns) (MS_TO_US(_msns * 1000)) + +#define MS_TO_US(_msus) (_msus * 1000) +#define MS_TO_NS(_msns) (MS_TO_US(_msns * 1000)) + +#define SEM_PERMS (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) + +#define SHM_SIZE (4096 * 64) /* get from topology - and set for context */ + +#define NUM_EP_CONFIGS 8 + +/* + * Run with valgrind + * valgrind --trace-children=yes aplay -v -Dsof:blah.tplg,1,hw:1,2 -f dat /dev/zero + */ +//#define VALGRIND +#ifdef VALGRIND +#define DEBUG_TV_SECS 10 +#define DEBUG_RETRIES 1000 +#else +#define DEBUG_RETRIES 10 +#define DEBUG_TV_SECS 0 +#endif + +#define SOF_MAGIC "sofpipe" + +enum plugin_state { + SOF_PLUGIN_STATE_INIT = 0, + SOF_PLUGIN_STATE_READY = 1, + SOF_PLUGIN_STATE_DEAD = 2, + SOF_PLUGIN_STATE_STREAM_RUNNING = 3, + SOF_PLUGIN_STATE_STREAM_ERROR = 5, +}; + +struct plug_shm_ctl { + unsigned int comp_id; + unsigned int type; + union { + struct snd_soc_tplg_mixer_control mixer_ctl; + struct snd_soc_tplg_enum_control enum_ctl; + struct snd_soc_tplg_bytes_control bytes_ctl; + }; +}; + +/* + * config.48k2c { + * rate 48000 + * channels 2 + * period_time 0 + * period_frames 6000 + * buffer_time 0 + * buffer_frames 24000 + * } + */ +struct plug_config { + char name[44]; + unsigned long buffer_frames; + unsigned long buffer_time; + unsigned long period_frames; + unsigned long period_time; + int rate; + int channels; + unsigned long format; +}; + +/* + * :[pcm:card:dev:config[pcm:card:dev:config]...] + */ +struct plug_cmdline_item { + int pcm; + char card_name[44]; + char dev_name[44]; + char config_name[44]; +}; + +/* + * Endpoint pipeline configuration + */ +struct endpoint_hw_config { + int pipeline; + char card_name[44]; + char dev_name[44]; + char config_name[44]; + unsigned long buffer_frames; + unsigned long buffer_time; + unsigned long period_frames; + unsigned long period_time; + int rate; + int channels; + unsigned long format; +}; + +struct plug_shm_endpoint { + char magic[8]; /* SOF_MAGIC */ + uint64_t state; + uint32_t pipeline_id; + uint32_t comp_id; + uint32_t idx; + unsigned long rpos; /* current position in ring buffer */ + unsigned long rwrap; + unsigned long wpos; /* current position in ring buffer */ + unsigned long wwrap; + unsigned long buffer_size; /* buffer size */ + unsigned long wtotal; /* total frames copied */ + unsigned long rtotal; /* total frames copied */ + int frame_size; + char data[0]; // TODO: align this on SIMD/cache +}; + +struct plug_shm_glb_state { + char magic[8]; /* SOF_MAGIC */ + uint64_t size; /* size of this structure in bytes */ + uint64_t state; /* enum plugin_state */ + struct endpoint_hw_config ep_config[NUM_EP_CONFIGS]; + int num_ep_configs; + uint64_t num_ctls; /* number of ctls */ + struct plug_shm_ctl ctl[]; +}; + +struct plug_shm_desc { + /* SHM for stream context sync */ + int fd; + int size; + char name[NAME_SIZE]; + void *addr; +}; + +struct plug_mq_desc { + /* IPC message queue */ + mqd_t mq; + struct mq_attr attr; + char queue_name[NAME_SIZE]; +}; + +struct plug_sem_desc { + char name[NAME_SIZE]; + sem_t *sem; +}; + +struct plug_ctl_container { + struct snd_soc_tplg_ctl_hdr *tplg[MAX_CTLS]; + int updated[MAX_CTLS]; + int count; +}; + +static inline void *plug_ep_rptr(struct plug_shm_endpoint *ep) +{ + return ep->data + ep->rpos; +} + +static inline void *plug_ep_wptr(struct plug_shm_endpoint *ep) +{ + return ep->data + ep->wpos; +} + +static inline int plug_ep_wrap_rsize(struct plug_shm_endpoint *ep) +{ + return ep->buffer_size - ep->rpos; +} + +static inline int plug_ep_wrap_wsize(struct plug_shm_endpoint *ep) +{ + return ep->buffer_size - ep->wpos; +} + +static inline int plug_ep_get_free(struct plug_shm_endpoint *ep) +{ + if (ep->rwrap == ep->wwrap) { + /* calculate available bytes */ + if (ep->rpos < ep->wpos) + return ep->buffer_size - (ep->wpos - ep->rpos); + else + return ep->buffer_size; + } else { + return ep->rpos - ep->wpos; + } +} + +static inline int plug_ep_get_avail(struct plug_shm_endpoint *ep) +{ + if (ep->rwrap == ep->wwrap) { + /* calculate available bytes */ + if (ep->rpos < ep->wpos) + return ep->wpos - ep->rpos; + else + return 0; + } else { + return (ep->buffer_size - ep->rpos) + ep->wpos; + } +} + +static inline void *plug_ep_consume(struct plug_shm_endpoint *ep, unsigned int bytes) +{ + ep->rtotal += bytes; + ep->rpos += bytes; + + if (ep->rpos >= ep->buffer_size) { + ep->rpos -= ep->buffer_size; + ep->rwrap++; + } + + return ep->data + ep->rpos; +} + +static inline void *plug_ep_produce(struct plug_shm_endpoint *ep, unsigned int bytes) +{ + ep->wtotal += bytes; + ep->wpos += bytes; + + if (ep->wpos >= ep->buffer_size) { + ep->wpos -= ep->buffer_size; + ep->wwrap++; + } + + return ep->data + ep->wpos; +} + +/* + * SHM + */ +int plug_shm_init(struct plug_shm_desc *shm, const char *tplg, const char *type, int index); + +int plug_shm_create(struct plug_shm_desc *shm); + +int plug_shm_open(struct plug_shm_desc *shm); + +void plug_shm_free(struct plug_shm_desc *shm); + +/* + * IPC + */ +int plug_mq_create(struct plug_mq_desc *ipc); + +int plug_mq_open(struct plug_mq_desc *ipc); + +int plug_mq_init(struct plug_mq_desc *ipc, const char *tplg, const char *type, int index); + +void plug_mq_free(struct plug_mq_desc *ipc); + +int plug_mq_cmd(struct plug_mq_desc *ipc, void *msg, size_t len, void *reply, size_t rlen); + +int plug_mq_cmd_tx_rx(struct plug_mq_desc *ipc_tx, struct plug_mq_desc *ipc_rx, + void *msg, size_t len, void *reply, size_t rlen); + +/* + * Locking + */ +int plug_lock_create(struct plug_sem_desc *lock); + +void plug_lock_free(struct plug_sem_desc *lock); + +int plug_lock_init(struct plug_sem_desc *lock, const char *tplg, const char *type, int index); + +int plug_lock_open(struct plug_sem_desc *lock); + +/* + * Timing. + */ +void plug_timespec_add_ms(struct timespec *ts, unsigned long ms); + +long plug_timespec_delta_ns(struct timespec *before, struct timespec *after); + +/* dump the IPC data - dont print lines of 0s */ +static inline void data_dump(void *vdata, size_t bytes) +{ + uint32_t *data = vdata; + size_t words = bytes >> 2; + int i; + + for (i = 0; i < words; i++) { + /* 4 words per line */ + if (i % 4 == 0) { + /* delete lines with all 0s */ + if (i > 0 && data[i - 3] == 0 && data[i - 2] == 0 && + data[i - 1] == 0 && data[i - 0] == 0) + printf("\r"); + else + printf("\n"); + + printf("0x%4.4x: 0x%8.8x", i, data[i]); + } else { + printf(" 0x%8.8x", data[i]); + } + } + printf("\n"); +} + +#endif diff --git a/tools/plugin/modules/CMakeLists.txt b/tools/plugin/modules/CMakeLists.txt new file mode 100644 index 000000000000..dfd7105c072e --- /dev/null +++ b/tools/plugin/modules/CMakeLists.txt @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: BSD-3-Clause + +# File SHM pipe module +add_library(sof_mod_shm MODULE + shm.c +) +sof_append_relative_path_definitions(sof_mod_shm) +target_include_directories(sof_mod_shm PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_SOURCE_DIR}/../pipe + ${sof_source_directory}/src/audio) + +target_compile_options(sof_mod_shm PRIVATE -DPIC -g -O3 -Wl,-EL -Wall -Werror -DCONFIG_LIBRARY -imacros${config_h}) + +install(TARGETS sof_mod_shm + DESTINATION /usr/lib/x86_64-linux-gnu/alsa-lib) + +target_link_options(sof_mod_shm PRIVATE -Wl,--export-dynamic) + +target_include_directories(sof_mod_shm PRIVATE ${sof_install_directory}/include) +target_include_directories(sof_mod_shm PRIVATE ${parser_install_dir}/include) + +set_target_properties(sof_mod_shm + PROPERTIES + INSTALL_RPATH "${sof_install_directory}/alsa-lib" + INSTALL_RPATH_USE_LINK_PATH TRUE +) + + +# ALSA SOF pipe module +add_library(sof_mod_alsa MODULE + alsa.c +) +sof_append_relative_path_definitions(sof_mod_alsa) +target_include_directories(sof_mod_alsa PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_SOURCE_DIR}/../pipe + ${sof_source_directory}/src/audio) + +target_compile_options(sof_mod_alsa PRIVATE -DPIC -g -O3 -Wl,-EL -Wmissing-prototypes + -Wimplicit-fallthrough -Wall -Werror -DCONFIG_LIBRARY -imacros${config_h}) + +install(TARGETS sof_mod_alsa + DESTINATION /usr/lib/x86_64-linux-gnu/alsa-lib) + +target_link_options(sof_mod_alsa PRIVATE -Wl,--export-dynamic) + +target_include_directories(sof_mod_alsa PRIVATE ${sof_install_directory}/include) +target_include_directories(sof_mod_alsa PRIVATE ${parser_install_dir}/include) + +set_target_properties(sof_mod_alsa + PROPERTIES + INSTALL_RPATH "${sof_install_directory}/alsa-lib" + INSTALL_RPATH_USE_LINK_PATH TRUE +) diff --git a/tools/plugin/modules/alsa.c b/tools/plugin/modules/alsa.c new file mode 100644 index 000000000000..a00ca95d759f --- /dev/null +++ b/tools/plugin/modules/alsa.c @@ -0,0 +1,790 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. + +/* file component for reading/writing pcm samples to/from a file */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "pipe.h" + +/* 66def9f0-39f2-11ed-89f7-af98a6440cc4 */ +DECLARE_SOF_RT_UUID("arecord", arecord_uuid, 0x66def9f0, 0x39f2, 0x11ed, + 0xf7, 0x89, 0xaf, 0x98, 0xa6, 0x44, 0x0c, 0xc4); +DECLARE_TR_CTX(arecord_tr, SOF_UUID(arecord_uuid), LOG_LEVEL_INFO); + +/* 72cee996-39f2-11ed-a08f-97fcc42eaaeb */ +DECLARE_SOF_RT_UUID("aplay", aplay_uuid, 0x72cee996, 0x39f2, 0x11ed, + 0xa0, 0x8f, 0x97, 0xfc, 0xc4, 0x2e, 0xaa, 0xeb); +DECLARE_TR_CTX(aplay_tr, SOF_UUID(aplay_uuid), LOG_LEVEL_INFO); + +static const struct comp_driver comp_arecord; +static const struct comp_driver comp_aplay; + +/* ALSA comp data */ +struct alsa_comp_data { + snd_pcm_t *handle; + snd_pcm_info_t *info; + snd_pcm_hw_params_t *hw_params; + snd_pcm_sw_params_t *sw_params; + snd_pcm_uframes_t period_frames; + snd_pcm_uframes_t buffer_frames; + char *pcm_name; + struct sof_ipc_stream_params params; + struct plug_shm_desc pcm; + struct plug_shm_endpoint *ctx; + struct plug_shm_desc glb; + struct plug_shm_glb_state *glb_ctx; + struct endpoint_hw_config *ep_hw; +#if CONFIG_IPC_MAJOR_4 + struct ipc4_base_module_cfg base_cfg; +#endif +}; + +static struct endpoint_hw_config *alsa_get_hw_config(struct comp_dev *dev) +{ + struct alsa_comp_data *cd = comp_get_drvdata(dev); + struct plug_shm_glb_state *glb = cd->glb_ctx; + + if (!glb->num_ep_configs) + return NULL; + + return glb->ep_config; +} + +static int alsa_alloc(struct comp_dev *dev) +{ + struct alsa_comp_data *cd = comp_get_drvdata(dev); + int err; + + /* get ALSA ready */ + err = snd_pcm_info_malloc(&cd->info); + if (err < 0) + goto error; + + err = snd_pcm_hw_params_malloc(&cd->hw_params); + if (err < 0) + goto error; + + err = snd_pcm_sw_params_malloc(&cd->sw_params); + if (err < 0) + goto error; + + comp_dbg(dev, "open done"); + return 0; + +error: + return err; +} + +static int alsa_close(struct comp_dev *dev) +{ + struct alsa_comp_data *cd = comp_get_drvdata(dev); + int ret = 0; + + comp_dbg(dev, "close"); + if (cd->handle) { + ret = snd_pcm_hw_free(cd->handle); + if (ret < 0) + comp_err(dev, "error: failed to snd_pcm_hw_free: %s\n", snd_strerror(ret)); + + ret = snd_pcm_close(cd->handle); + if (ret < 0) + comp_err(dev, "error: failed to snd_pcm_close: %s\n", snd_strerror(ret)); + + cd->handle = NULL; + } + + return ret; +} + +static void alsa_free(struct comp_dev *dev) +{ + struct alsa_comp_data *cd = comp_get_drvdata(dev); + + comp_dbg(dev, "alsa_free()"); + + snd_pcm_sw_params_free(cd->sw_params); + snd_pcm_hw_params_free(cd->hw_params); + snd_pcm_info_free(cd->info); + plug_shm_free(&cd->pcm); + free(cd); + free(dev); +} + +static struct comp_dev *alsa_new(const struct comp_driver *drv, + const struct comp_ipc_config *config, + const void *spec) +{ +#if CONFIG_IPC_MAJOR_4 + const struct ipc4_base_module_cfg *base_cfg = (struct ipc4_base_module_cfg *)spec; +#endif + struct comp_dev *dev; + struct alsa_comp_data *cd; + int err; + + dev = comp_alloc(drv, sizeof(*dev)); + if (!dev) + return NULL; + dev->ipc_config = *config; + + /* allocate memory for file comp data */ + cd = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*cd)); + if (!cd) + goto error; + + comp_set_drvdata(dev, cd); + memcpy(&cd->base_cfg, base_cfg, sizeof(struct ipc4_base_module_cfg)); + + /* use PCM ID to create shm */ + err = plug_shm_init(&cd->pcm, _sp->topology_name, "pcm", 1); + if (err < 0) { + comp_err(dev, "Error initializing pcm\n"); + goto error; + } + + // TODO: get the shm size for the buffer using a better method + //cd->pcm.size = 128 * 1024; + + /* mmap the SHM PCM */ + err = plug_shm_open(&cd->pcm); + if (err < 0) { + comp_err(dev, "Error open pcm shm"); + goto error; + } + cd->ctx = cd->pcm.addr; + + err = plug_shm_init(&cd->glb, _sp->topology_name, "ctx", 0); + if (err < 0) { + comp_err(dev, "Error initializing ctx\n"); + goto error; + } + + // TODO: get the shm size for the buffer using a better method + //cd->pcm.size = 128 * 1024; + + /* mmap the GLB ctx */ + err = plug_shm_open(&cd->glb); + if (err < 0) { + comp_err(dev, "Error opening glb ctx\n"); + goto error; + } + cd->glb_ctx = cd->glb.addr; + + /* alloc alsa context */ + err = alsa_alloc(dev); + if (err < 0) { + comp_err(dev, "Error allocating alsa context\n"); + goto error; + } + + return dev; + +error: + free(cd); + free(dev); + return NULL; +} + +static struct comp_dev *arecord_new(const struct comp_driver *drv, + const struct comp_ipc_config *config, const void *spec) +{ + struct comp_dev *dev; + struct alsa_comp_data *cd; + + comp_dbg(dev, "arecord_new()"); + + dev = alsa_new(drv, config, spec); + if (!dev) + return NULL; + + cd = comp_get_drvdata(dev); + cd->params.direction = SND_PCM_STREAM_CAPTURE; + + dev->state = COMP_STATE_READY; + return dev; +} + +static struct comp_dev *aplay_new(const struct comp_driver *drv, + const struct comp_ipc_config *config, + const void *spec) +{ + struct comp_dev *dev; + struct alsa_comp_data *cd; + + comp_dbg(dev, "aplay_new()"); + + dev = alsa_new(drv, config, spec); + if (!dev) + return NULL; + + cd = comp_get_drvdata(dev); + cd->params.direction = SND_PCM_STREAM_PLAYBACK; + + dev->state = COMP_STATE_READY; + return dev; +} + +static int set_params(struct comp_dev *dev) +{ + struct alsa_comp_data *cd = comp_get_drvdata(dev); + struct sof_ipc_stream_params *params = &cd->params; + int frame_fmt; + int err; + + err = snd_pcm_open(&cd->handle, cd->pcm_name, cd->params.direction, 0); + if (err < 0) { + comp_err(dev, "error: cant open PCM %s: %s\n", cd->pcm_name, snd_strerror(err)); + return err; + } + + err = snd_pcm_info(cd->handle, cd->info); + if (err < 0) { + comp_err(dev, "error: cant get PCM info: %s\n", snd_strerror(err)); + return err; + } + + /* is sound card HW configuration valid ? */ + err = snd_pcm_hw_params_any(cd->handle, cd->hw_params); + if (err < 0) { + comp_err(dev, "error: cant get PCM hw_params: %s\n", snd_strerror(err)); + return err; + } + + /* set interleaved buffer format */ + err = snd_pcm_hw_params_set_access(cd->handle, cd->hw_params, + SND_PCM_ACCESS_RW_INTERLEAVED); + if (err < 0) { + comp_err(dev, "error: PCM can't set interleaved: %s\n", snd_strerror(err)); + return err; + } + + /* set sample format */ + /* set all topology configuration */ + switch (params->frame_fmt) { + case SOF_IPC_FRAME_S16_LE: + frame_fmt = SND_PCM_FORMAT_S16_LE; + break; + case SOF_IPC_FRAME_S24_4LE: + frame_fmt = SND_PCM_FORMAT_S24_LE; + break; + case SOF_IPC_FRAME_S32_LE: + frame_fmt = SND_PCM_FORMAT_S32_LE; + break; + case SOF_IPC_FRAME_FLOAT: + frame_fmt = SND_PCM_FORMAT_FLOAT_LE; + break; + case SOF_IPC_FRAME_S24_3LE: + frame_fmt = SND_PCM_FORMAT_S24_3LE; + break; + default: + comp_err(dev, "error: invalid frame format %d for ALSA PCM\n", params->frame_fmt); + return -EINVAL; + } + err = snd_pcm_hw_params_set_format(cd->handle, cd->hw_params, frame_fmt); + if (err < 0) { + comp_err(dev, "error: PCM can't set format %d: %s\n", + frame_fmt, snd_strerror(err)); + return err; + } + + /* set number of channels */ + err = snd_pcm_hw_params_set_channels(cd->handle, cd->hw_params, params->channels); + if (err < 0) { + comp_err(dev, "error: PCM can't set channels %d: %s\n", + params->channels, snd_strerror(err)); + return err; + } + + /* set sample rate */ + err = snd_pcm_hw_params_set_rate(cd->handle, cd->hw_params, params->rate, 0); + if (err < 0) { + comp_err(dev, "error: PCM can't set rate %d: %s\n", + params->rate, snd_strerror(err)); + return err; + } + + /* set period size TODO: get from topology */ + err = snd_pcm_hw_params_set_period_size(cd->handle, cd->hw_params, + cd->period_frames, 0); + if (err < 0) { + comp_err(dev, "error: PCM can't set period size %ld frames: %s\n", + cd->period_frames, snd_strerror(err)); + return err; + } + + /* set buffer size: TODO: get from topology */ + err = snd_pcm_hw_params_set_buffer_size_near(cd->handle, cd->hw_params, + &cd->buffer_frames); + if (err < 0) { + comp_err(dev, "error: PCM can't set buffer size %ld frames: %s\n", + cd->buffer_frames, snd_strerror(err)); + return err; + } + + /* commit the hw params */ + err = snd_pcm_hw_params(cd->handle, cd->hw_params); + if (err < 0) { + comp_err(dev, "error: PCM can't commit hw_params: %s\n", snd_strerror(err)); + snd_pcm_hw_params_dump(cd->hw_params, SND_OUTPUT_STDIO); + return err; + } + + /* get the initial SW params */ + err = snd_pcm_sw_params_current(cd->handle, cd->sw_params); + if (err < 0) { + comp_err(dev, "error: PCM can't get sw params: %s\n", snd_strerror(err)); + return err; + } + + /* set the avail min to the period size */ + err = snd_pcm_sw_params_set_avail_min(cd->handle, cd->sw_params, cd->period_frames); + if (err < 0) { + comp_err(dev, "error: PCM can't set avail min: %s\n", snd_strerror(err)); + return err; + } + + /* PCM should start after receiving first periods worth of data */ + err = snd_pcm_sw_params_set_start_threshold(cd->handle, cd->sw_params, cd->period_frames); + if (err < 0) { + comp_err(dev, "error: PCM can't set start threshold: %s\n", snd_strerror(err)); + return err; + } + + /* PCM should stop if only 1/4 period worth of data is available */ + err = snd_pcm_sw_params_set_stop_threshold(cd->handle, cd->sw_params, + cd->period_frames / 4); + if (err < 0) { + comp_err(dev, "error: PCM can't set stop threshold: %s\n", snd_strerror(err)); + return err; + } + + /* commit the sw params */ + if (snd_pcm_sw_params(cd->handle, cd->sw_params) < 0) { + comp_err(dev, "error: PCM can't commit sw_params: %s\n", snd_strerror(err)); + snd_pcm_sw_params_dump(cd->sw_params, SND_OUTPUT_STDIO); + return err; + } + + comp_dbg(dev, "params set"); + return 0; +} + +static int alsa_dai_get_hw_params(struct comp_dev *dev, + struct sof_ipc_stream_params *params, int dir); + +/** + * \brief Sets file component audio stream parameters. + * \param[in,out] dev Volume base component device. + * \param[in] params Audio (PCM) stream parameters (ignored for this component) + * \return Error code. + * + * All done in prepare() since we need to know source and sink component params. + */ +static int arecord_params(struct comp_dev *dev, struct sof_ipc_stream_params *params) +{ + struct comp_buffer *buffer; + struct alsa_comp_data *cd = comp_get_drvdata(dev); + struct comp_buffer __sparse_cache *buf_c; + int ret; + + comp_dbg(dev, "arecord params"); + + ret = alsa_dai_get_hw_params(dev, params, cd->params.direction); + + if (params->direction != SND_PCM_STREAM_CAPTURE) { + comp_err(dev, "alsa_params(): pcm params invalid direction."); + return -EINVAL; + } + + /* params can be aligned to match pipeline here */ + ret = comp_verify_params(dev, 0, params); + if (ret < 0) { + comp_err(dev, "alsa_params(): pcm params verification failed."); + return ret; + } + memcpy(&cd->params, params, sizeof(*params)); + + /* file component sink/source buffer period count */ + buffer = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + buf_c = buffer_acquire(buffer); + buffer_reset_pos(buf_c, NULL); + buffer_release(buf_c); + + comp_dbg(dev, "prepare done ret = %d", ret); + + return 0; +} + +static int aplay_params(struct comp_dev *dev, struct sof_ipc_stream_params *params) +{ + struct comp_buffer *buffer; + struct alsa_comp_data *cd = comp_get_drvdata(dev); + int ret; + + comp_dbg(dev, "aplay params"); + + ret = alsa_dai_get_hw_params(dev, params, cd->params.direction); + + if (params->direction != SND_PCM_STREAM_PLAYBACK) { + comp_err(dev, "alsa_params(): pcm params invalid direction."); + return -EINVAL; + } + + /* params can be aligned to match pipeline here */ + ret = comp_verify_params(dev, 0, params); + if (ret < 0) { + comp_err(dev, "alsa_params(): pcm params verification failed."); + return ret; + } + memcpy(&cd->params, params, sizeof(*params)); + + /* file component sink/source buffer period count */ + buffer = list_first_item(&dev->bsource_list, struct comp_buffer, + sink_list); + buffer_reset_pos(buffer, NULL); + + comp_dbg(dev, "prepare done ret = %d", ret); + return 0; +} + +static int alsa_trigger(struct comp_dev *dev, int cmd) +{ + int err; + + /* trigger is handled automatically by ALSA start threshold */ + comp_dbg(dev, "trigger cmd %d", cmd); + + switch (cmd) { + case COMP_TRIGGER_PAUSE: + case COMP_TRIGGER_STOP: + err = alsa_close(dev); + if (err < 0) { + comp_err(dev, "error: cant stop pipeline"); + return err; + } + break; + case COMP_TRIGGER_RELEASE: + case COMP_TRIGGER_START: + err = set_params(dev); + if (err < 0) { + comp_err(dev, "error: cant stop pipeline"); + return err; + } + break; + default: + break; + } + + return comp_set_state(dev, cmd); +} + +/* used to pass standard and bespoke commands (with data) to component */ +static int alsa_cmd(struct comp_dev *dev, int cmd, void *data, + int max_data_size) +{ + return 0; +} + +/* + * copy and process stream samples + * returns the number of bytes copied + */ +static int arecord_copy(struct comp_dev *dev) +{ + struct alsa_comp_data *cd = comp_get_drvdata(dev); + struct comp_buffer __sparse_cache *buf_c; + struct comp_buffer *buffer; + struct audio_stream *sink; + snd_pcm_sframes_t frames; + snd_pcm_uframes_t free; + snd_pcm_uframes_t total = 0; + unsigned int frame_bytes; + void *pos; + + switch (dev->state) { + case COMP_STATE_ACTIVE: + break; + default: + return -EINVAL; + } + + /* file component sink buffer */ + buffer = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + buf_c = buffer_acquire(buffer); + sink = &buf_c->stream; + pos = sink->w_ptr; + + //FIX: this will fill buffer and higher latency, use period size + free = MIN(audio_stream_get_free_frames(sink), cd->period_frames); + frame_bytes = audio_stream_frame_bytes(sink); + + while (free) { + frames = MIN(free, audio_stream_frames_without_wrap(sink, pos)); + + /* read PCM samples from file */ + frames = snd_pcm_readi(cd->handle, pos, frames); + if (frames < 0) { + comp_err(dev, "failed to read: %s: %s\n", + cd->pcm_name, snd_strerror(frames)); + buffer_release(buf_c); + return frames; + } + + free -= frames; + pos = audio_stream_wrap(sink, pos + frames * frame_bytes); + total += frames; + } + + /* update sink buffer pointers */ + comp_update_buffer_produce(buffer, total * frame_bytes); + comp_dbg(dev, "read %d frames", total); + buffer_release(buf_c); + + return 0; +} + +/* + * copy and process stream samples + * returns the number of bytes copied + */ +static int aplay_copy(struct comp_dev *dev) +{ + struct alsa_comp_data *cd = comp_get_drvdata(dev); + struct comp_buffer *buffer; + struct audio_stream *source; + snd_pcm_sframes_t frames; + snd_pcm_sframes_t avail; + snd_pcm_uframes_t total = 0; + unsigned int frame_bytes; + void *pos; + + switch (dev->state) { + case COMP_STATE_ACTIVE: + break; + default: + return -EINVAL; + } + + /* file component source buffer */ + buffer = list_first_item(&dev->bsource_list, struct comp_buffer, + sink_list); + source = &buffer->stream; + pos = source->r_ptr; + avail = MIN(audio_stream_get_avail_frames(source), cd->period_frames); + avail = audio_stream_get_avail_frames(source); + frame_bytes = audio_stream_frame_bytes(source); + + while (avail > 0) { + frames = MIN(avail, audio_stream_frames_without_wrap(source, pos)); + + /* write PCM samples to PCM */ + frames = snd_pcm_writei(cd->handle, pos, frames); + if (frames < 0) { + comp_err(dev, "failed to write: %s: %s\n", + cd->pcm_name, snd_strerror(frames)); + return frames; + } + + avail -= frames; + pos = audio_stream_wrap(source, pos + frames * frame_bytes); + total += frames; + } + + /* update sink buffer pointers */ + comp_update_buffer_consume(buffer, total * frame_bytes); + comp_dbg(dev, "wrote %d bytes", total * frame_bytes); + + return 0; +} + +static int alsa_prepare(struct comp_dev *dev) +{ + int ret = 0; + + comp_dbg(dev, "prepare"); + ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); + if (ret < 0) + return ret; + + if (ret == COMP_STATUS_STATE_ALREADY_SET) + return PPL_STATUS_PATH_STOP; + + return ret; +} + +static int alsa_reset(struct comp_dev *dev) +{ + comp_dbg(dev, "reset"); + + comp_set_state(dev, COMP_TRIGGER_RESET); + + return 0; +} + +/* + * TODO: we pass the DAI topology config back up the pipeline so + * that upstream/downstream can be configured. Needs to be configured + * at stream runtime instead of at topology load time. + */ +static int alsa_dai_get_hw_params(struct comp_dev *dev, struct sof_ipc_stream_params *params, + int dir) +{ + struct alsa_comp_data *cd = comp_get_drvdata(dev); + struct endpoint_hw_config *ep_hw; + char pcm_name[128]; + + comp_dbg(dev, "get_hw_params"); + + /* get our hw config from cmdline and conf file */ + ep_hw = alsa_get_hw_config(dev); + if (!ep_hw) { + comp_err(dev, "error: failed to get hw config %d\n"); + return -EINVAL; + } + cd->ep_hw = ep_hw; + + /* PCM name comes from cmd line - "default" dev means dont use dev */ + if (!strncmp(cd->ep_hw->dev_name, "default", sizeof(cd->ep_hw->dev_name))) { + snprintf(pcm_name, sizeof(pcm_name), "%s", cd->ep_hw->card_name); + } else { + snprintf(pcm_name, sizeof(pcm_name), "%s:%s", + cd->ep_hw->card_name, cd->ep_hw->dev_name); + } + cd->pcm_name = strdup(pcm_name); + comp_dbg(dev, "using ALSA card %s", cd->pcm_name); + + /* set default config - get from cmdline and plugin config */ + cd->params.rate = cd->ep_hw->rate; + cd->params.channels = cd->ep_hw->channels; + cd->buffer_frames = cd->ep_hw->buffer_frames; + cd->period_frames = cd->ep_hw->period_frames; + + /* ALSA API uses frames, SOF buffer uses bytes */ + switch (cd->ep_hw->format) { + case SND_PCM_FORMAT_S16_LE: + cd->params.frame_fmt = SOF_IPC_FRAME_S16_LE; + cd->params.buffer.size = cd->ep_hw->buffer_frames * 2; + break; + case SND_PCM_FORMAT_S24_LE: + cd->params.frame_fmt = SOF_IPC_FRAME_S24_4LE; + cd->params.buffer.size = cd->ep_hw->buffer_frames * 4; + break; + case SND_PCM_FORMAT_S32_LE: + cd->params.frame_fmt = SOF_IPC_FRAME_S32_LE; + cd->params.buffer.size = cd->ep_hw->buffer_frames * 4; + break; + case SND_PCM_FORMAT_FLOAT: + cd->params.frame_fmt = SOF_IPC_FRAME_FLOAT; + cd->params.buffer.size = cd->ep_hw->buffer_frames * 4; + break; + case SND_PCM_FORMAT_S24_3LE: + cd->params.frame_fmt = SOF_IPC_FRAME_S24_3LE; + cd->params.buffer.size = cd->ep_hw->buffer_frames * 3; + break; + default: + comp_err(dev, "error: invalid frame format %d for ALSA PCM\n", params->frame_fmt); + return -EINVAL; + } + + memcpy(params, &cd->params, sizeof(*params)); + + comp_dbg(dev, "rate %d", params->rate); + comp_dbg(dev, "frame format %d", params->frame_fmt); + comp_dbg(dev, "channels %d", params->channels); + comp_dbg(dev, "buffer frames %d", cd->buffer_frames); + comp_dbg(dev, "period frames %d", cd->period_frames); + comp_dbg(dev, "direction %d", params->direction); + + return 0; +} + +static int alsa_get_attribute(struct comp_dev *dev, uint32_t type, void *value) +{ + struct alsa_comp_data *cd = comp_get_drvdata(dev); + + switch (type) { + case COMP_ATTR_BASE_CONFIG: + memcpy_s(value, sizeof(struct ipc4_base_module_cfg), + &cd->base_cfg, sizeof(struct ipc4_base_module_cfg)); + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct comp_driver comp_arecord = { + .type = SOF_COMP_FILEREAD, + .uid = SOF_RT_UUID(arecord_uuid), + .tctx = &arecord_tr, + .ops = { + .create = arecord_new, + .free = alsa_free, + .params = arecord_params, + .cmd = alsa_cmd, + .trigger = alsa_trigger, + .copy = arecord_copy, + .prepare = alsa_prepare, + .reset = alsa_reset, + .dai_get_hw_params = alsa_dai_get_hw_params, + .get_attribute = alsa_get_attribute, + }, +}; + +static const struct comp_driver comp_aplay = { + .type = SOF_COMP_FILEWRITE, + .uid = SOF_RT_UUID(aplay_uuid), + .tctx = &aplay_tr, + .ops = { + .create = aplay_new, + .free = alsa_free, + .params = aplay_params, + .cmd = alsa_cmd, + .trigger = alsa_trigger, + .copy = aplay_copy, + .prepare = alsa_prepare, + .reset = alsa_reset, + .dai_get_hw_params = alsa_dai_get_hw_params, + .get_attribute = alsa_get_attribute, + }, +}; + +static struct comp_driver_info comp_arecord_info = { + .drv = &comp_arecord, +}; + +static struct comp_driver_info comp_aplay_info = { + .drv = &comp_aplay, +}; + +static void sys_comp_alsa_init(void) +{ + comp_register(&comp_arecord_info); + comp_register(&comp_aplay_info); +} + +DECLARE_MODULE(sys_comp_alsa_init); diff --git a/tools/plugin/modules/shm.c b/tools/plugin/modules/shm.c new file mode 100644 index 000000000000..d59db6694902 --- /dev/null +++ b/tools/plugin/modules/shm.c @@ -0,0 +1,451 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. + +/* shm component for reading/writing pcm samples to/from a shm */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pipe.h" + +/* 1488beda-e847-ed11-b309-a58b974fecce */ +DECLARE_SOF_RT_UUID("shmread", shmread_uuid, 0xdabe8814, 0x47e8, 0x11ed, + 0xa5, 0x8b, 0xb3, 0x09, 0x97, 0x4f, 0xec, 0xce); +DECLARE_TR_CTX(shmread_tr, SOF_UUID(shmread_uuid), LOG_LEVEL_INFO); + +/* 1c03b6e2-e847-ed11-7f80-07a91b6efa6c */ +DECLARE_SOF_RT_UUID("shmwrite", shmwrite_uuid, 0xe2b6031c, 0x47e8, 0x11ed, + 0x07, 0xa9, 0x7f, 0x80, 0x1b, 0x6e, 0xfa, 0x6c); +DECLARE_TR_CTX(shmwrite_tr, SOF_UUID(shmwrite_uuid), LOG_LEVEL_INFO); + +static const struct comp_driver comp_shmread; +static const struct comp_driver comp_shmwrite; + +/* shm comp data */ +struct shm_comp_data { + /* PCM data */ + struct plug_shm_desc pcm; + struct plug_shm_endpoint *ctx; +#if CONFIG_IPC_MAJOR_4 + struct ipc4_base_module_cfg base_cfg; +#endif +}; + +static int shm_process_new(struct comp_dev *dev, + const struct comp_ipc_config *config, + const void *spec) +{ + struct shm_comp_data *cd = comp_get_drvdata(dev); + struct plug_shm_endpoint *ctx; + int ret; + + comp_dbg(dev, "shm new()"); + + /* FIXME: use PCM ID to create shm */ + ret = plug_shm_init(&cd->pcm, _sp->topology_name, "pcm", 1); + if (ret < 0) + return ret; + + // TODO: get the shm size for the buffer using a better method + cd->pcm.size = 128 * 1024; + + /* mmap the SHM PCM */ + ret = plug_shm_create(&cd->pcm); + if (ret < 0) + return ret; + + cd->ctx = cd->pcm.addr; + ctx = cd->ctx; + ctx->buffer_size = cd->pcm.size; + memset(ctx, 0, sizeof(*ctx)); + ctx->comp_id = config->id; + ctx->pipeline_id = config->pipeline_id; + ctx->state = SOF_PLUGIN_STATE_INIT; + dev->state = COMP_STATE_READY; + + return 0; +} + +static void shm_free(struct comp_dev *dev) +{ + struct shm_comp_data *cd = comp_get_drvdata(dev); + + cd->ctx = NULL; + + plug_shm_free(&cd->pcm); + shm_unlink(cd->pcm.name); + + free(cd); + free(dev); +} + +static struct comp_dev *shm_new(const struct comp_driver *drv, + const struct comp_ipc_config *config, + const void *spec, int direction) +{ + struct comp_dev *dev; +#if CONFIG_IPC_MAJOR_4 + const struct ipc4_base_module_cfg *base_cfg = (struct ipc4_base_module_cfg *)spec; +#endif + struct shm_comp_data *cd; + int err; + + dev = comp_alloc(drv, sizeof(*dev)); + if (!dev) + return NULL; + dev->ipc_config = *config; + + /* allocate memory for shm comp data */ + cd = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*cd)); + if (!cd) + goto error; + + comp_set_drvdata(dev, cd); + memcpy(&cd->base_cfg, base_cfg, sizeof(struct ipc4_base_module_cfg)); + + dev->direction = direction; + err = shm_process_new(dev, config, spec); + if (err < 0) { + free(cd); + free(dev); + return NULL; + } + dev->direction_set = true; + + dev->state = COMP_STATE_READY; + return dev; + +error: + free(dev); + return NULL; +} + +static struct comp_dev *shmwrite_new(const struct comp_driver *drv, + const struct comp_ipc_config *config, + const void *spec) +{ + return shm_new(drv, config, spec, SOF_IPC_STREAM_PLAYBACK); +} + +static struct comp_dev *shmread_new(const struct comp_driver *drv, + const struct comp_ipc_config *config, + const void *spec) +{ + return shm_new(drv, config, spec, SOF_IPC_STREAM_CAPTURE); +} + +/** + * \brief Sets shm component audio stream parameters. + * \param[in,out] dev Volume base component device. + * \param[in] params Audio (PCM) stream parameters (ignored for this component) + * \return Error code. + * + * All done in prepare() since we need to know source and sink component params. + */ +static int shmread_params(struct comp_dev *dev, struct sof_ipc_stream_params *params) +{ + struct shm_comp_data *cd = comp_get_drvdata(dev); + struct plug_shm_endpoint *ctx = cd->ctx; + int ret; + +#if CONFIG_IPC_MAJOR_4 + ipc4_base_module_cfg_to_stream_params(&cd->base_cfg, params); +#endif + + comp_err(dev, "forme_fmt %d channels %d", params->frame_fmt, params->channels); + + ret = comp_verify_params(dev, 0, params); + if (ret < 0) { + comp_err(dev, "shm_params(): pcm params verification failed."); + return ret; + } + ctx->state = SOF_PLUGIN_STATE_READY; + + return 0; +} + +static int shmwrite_params(struct comp_dev *dev, struct sof_ipc_stream_params *params) +{ + struct shm_comp_data *cd = comp_get_drvdata(dev); + struct plug_shm_endpoint *ctx = cd->ctx; + int ret; + + ret = comp_verify_params(dev, 0, params); + if (ret < 0) { + comp_err(dev, "shm_params(): pcm params verification failed."); + return ret; + } + ctx->state = SOF_PLUGIN_STATE_READY; + + return 0; +} + +static int shm_trigger(struct comp_dev *dev, int cmd) +{ + struct shm_comp_data *cd = comp_get_drvdata(dev); + struct plug_shm_endpoint *ctx = cd->ctx; + + comp_dbg(dev, "shm_trigger(%d)", cmd); + + switch (cmd) { + case COMP_TRIGGER_START: + case COMP_TRIGGER_RELEASE: + ctx->state = SOF_PLUGIN_STATE_STREAM_RUNNING; + break; + case COMP_TRIGGER_STOP: + case COMP_TRIGGER_PAUSE: + ctx->state = SOF_PLUGIN_STATE_READY; + break; + case COMP_TRIGGER_RESET: + ctx->state = SOF_PLUGIN_STATE_INIT; + break; + case COMP_TRIGGER_XRUN: + ctx->state = SOF_PLUGIN_STATE_STREAM_ERROR; + break; + default: + break; + } + + return comp_set_state(dev, cmd); +} + +static int shm_cmd(struct comp_dev *dev, int cmd, void *data, int max_data_size) +{ + return 0; +} + +/* + * copy from local SOF buffer to remote SHM buffer + */ +static int shmread_copy(struct comp_dev *dev) +{ + struct shm_comp_data *cd = comp_get_drvdata(dev); + struct plug_shm_endpoint *ctx = cd->ctx; + struct comp_buffer *buffer; + struct audio_stream *source; + unsigned int copy_bytes; + unsigned int remaining; + unsigned int total = 0; + void *rptr; + void *dest; + + /* local SOF source buffer */ + buffer = list_first_item(&dev->bsource_list, struct comp_buffer, + sink_list); + source = &buffer->stream; + rptr = source->r_ptr; + + /* remote SHM sink buffer */ + dest = plug_ep_wptr(ctx); + + /* maximum byte count that can be copied this iteration */ + remaining = MIN(audio_stream_get_avail_bytes(source), plug_ep_get_free(ctx)); + + while (remaining) { + /* min bytes from source pipe */ + copy_bytes = MIN(remaining, plug_ep_wrap_wsize(ctx)); + + /* min bytes from source and sink */ + copy_bytes = MIN(copy_bytes, audio_stream_bytes_without_wrap(source, rptr)); + + /* anything to copy ? */ + if (copy_bytes == 0) + break; + + /* copy to local buffer from SHM buffer */ + memcpy(dest, rptr, copy_bytes); + + /* update SHM pointer with wrap */ + dest = plug_ep_produce(ctx, copy_bytes); + + /* update local pointers */ + rptr = audio_stream_wrap(source, rptr + copy_bytes); + + /* update avail and totals */ + remaining -= copy_bytes; + total += copy_bytes; + } + + /* update sink buffer pointers */ + comp_update_buffer_consume(buffer, total); + comp_dbg(dev, "wrote %d bytes", total); + + return 0; +} + +/* + * copy to local SOF buffer from remote SHM buffer + */ +static int shmwrite_copy(struct comp_dev *dev) +{ + struct shm_comp_data *cd = comp_get_drvdata(dev); + struct plug_shm_endpoint *ctx = cd->ctx; + struct comp_buffer *buffer; + struct audio_stream *sink; + unsigned int copy_bytes; + unsigned int remaining; + unsigned int total = 0; + void *wptr; + void *src; + + /* local SOF sink buffer */ + buffer = list_first_item(&dev->bsink_list, struct comp_buffer, + source_list); + sink = &buffer->stream; + wptr = sink->w_ptr; + + /* remote SHM source buffer */ + src = plug_ep_rptr(ctx); + + /* maximum byte count that can be copied this iteration */ + remaining = MIN(audio_stream_get_free_bytes(sink), plug_ep_get_avail(ctx)); + + while (remaining > 0) { + /* min bytes free bytes in local sink */ + copy_bytes = MIN(remaining, plug_ep_wrap_rsize(ctx)); + + /* min bytes to wrap */ + copy_bytes = MIN(copy_bytes, audio_stream_bytes_without_wrap(sink, wptr)); + + /* nothing to copy ? */ + if (copy_bytes == 0) + break; + + /* copy to SHM from local buffer */ + memcpy(wptr, src, copy_bytes); + + /* update local pointers */ + wptr = audio_stream_wrap(sink, wptr + copy_bytes); + + /* update SHM pointer with wrap */ + src = plug_ep_consume(ctx, copy_bytes); + + /* update avail and totals */ + remaining -= copy_bytes; + total += copy_bytes; + } + + /* update sink buffer pointers */ + comp_update_buffer_produce(buffer, total); + comp_dbg(dev, "read %d bytes", total); + + return 0; +} + +static int shm_prepare(struct comp_dev *dev) +{ + struct shm_comp_data *cd = comp_get_drvdata(dev); + struct plug_shm_endpoint *ctx = cd->ctx; + int ret = 0; + + comp_dbg(dev, "shm prepare_copy()"); + + ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); + if (ret < 0) + return ret; + + ctx->state = SOF_PLUGIN_STATE_READY; + + if (ret == COMP_STATUS_STATE_ALREADY_SET) + return PPL_STATUS_PATH_STOP; + + return ret; +} + +static int shm_reset(struct comp_dev *dev) +{ + struct shm_comp_data *cd = comp_get_drvdata(dev); + struct plug_shm_endpoint *ctx = cd->ctx; + + comp_set_state(dev, COMP_TRIGGER_RESET); + ctx->state = SOF_PLUGIN_STATE_INIT; + + return 0; +} + +int shm_get_attribute(struct comp_dev *dev, uint32_t type, void *value) +{ + struct shm_comp_data *cd = comp_get_drvdata(dev); + + switch (type) { + case COMP_ATTR_BASE_CONFIG: + memcpy_s(value, sizeof(struct ipc4_base_module_cfg), + &cd->base_cfg, sizeof(struct ipc4_base_module_cfg)); + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct comp_driver comp_shmread = { + .type = SOF_COMP_HOST, + .uid = SOF_RT_UUID(shmread_uuid), + .tctx = &shmread_tr, + .ops = { + .create = shmread_new, + .free = shm_free, + .params = shmread_params, + .cmd = shm_cmd, + .trigger = shm_trigger, + .copy = shmread_copy, + .prepare = shm_prepare, + .reset = shm_reset, + .get_attribute = shm_get_attribute, + }, +}; + +static const struct comp_driver comp_shmwrite = { + .type = SOF_COMP_HOST, + .uid = SOF_RT_UUID(shmwrite_uuid), + .tctx = &shmwrite_tr, + .ops = { + .create = shmwrite_new, + .free = shm_free, + .params = shmwrite_params, + .cmd = shm_cmd, + .trigger = shm_trigger, + .copy = shmwrite_copy, + .prepare = shm_prepare, + .reset = shm_reset, + .get_attribute = shm_get_attribute, + }, +}; + +static struct comp_driver_info comp_shmread_info = { + .drv = &comp_shmread, +}; + +static struct comp_driver_info comp_shmwrite_info = { + .drv = &comp_shmwrite, +}; + +static void sys_comp_shm_init(void) +{ + comp_register(&comp_shmread_info); + comp_register(&comp_shmwrite_info); +} + +DECLARE_MODULE(sys_comp_shm_init); diff --git a/tools/plugin/pipe/CMakeLists.txt b/tools/plugin/pipe/CMakeLists.txt new file mode 100644 index 000000000000..69f6245cfab2 --- /dev/null +++ b/tools/plugin/pipe/CMakeLists.txt @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: BSD-3-Clause + +add_executable(sof-pipe + main.c + cpu.c + pipeline.c + ctl.c + ipc4.c + ../common.c +) + +sof_append_relative_path_definitions(sof-pipe) + +target_include_directories(sof-pipe PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${sof_source_directory}/src/audio) + +target_compile_options(sof-pipe PRIVATE -DPIC -g -O3 -Wl,-EL -Wall -Werror -DCONFIG_LIBRARY -imacros${config_h}) + +target_include_directories(sof-pipe PRIVATE ${sof_install_directory}/include) +target_include_directories(sof-pipe PRIVATE ${parser_install_dir}/include) + +target_link_libraries(sof-pipe PRIVATE -Wl,-whole-archive sof_library -Wl,-no-whole-archive) +target_link_libraries(sof-pipe PRIVATE sof_parser_lib) +target_link_libraries(sof-pipe PRIVATE pthread) +target_link_libraries(sof-pipe PRIVATE -rdynamic -lasound -ldl -lm -lasound -lrt) diff --git a/tools/plugin/pipe/cpu.c b/tools/plugin/pipe/cpu.c new file mode 100644 index 000000000000..ea7e5d0645e2 --- /dev/null +++ b/tools/plugin/pipe/cpu.c @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. +// +// Author: Liam Girdwood + +/* + * SOF pipeline in userspace. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "pipe.h" + +/* read the CPU ID register data on x86 */ +static inline void x86_cpuid(unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) +{ + /* data type is passed in on eax (and sometimes ecx) */ + asm volatile("cpuid" + : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) + : "0" (*eax), "2" (*ecx)); +} + +/* + * Check core type for E cores. If non hybrid then it does not matter. + */ +static inline int use_this_core(struct sof_pipe *sp) +{ + /* CPUID - set eax to 0x1a for hybrid core types */ + unsigned int eax = 0x1a, ebx = 0, ecx = 0, edx = 0; + char core_mask; + + /* get the processor core type we are running on now */ + x86_cpuid(&eax, &ebx, &ecx, &edx); + + /* core type 0x20 is atom, 0x40 is core */ + core_mask = (eax >> 24) & 0xFF; + switch (core_mask) { + case 0x20: + fprintf(sp->log, "found E core\n"); + if (sp->use_E_core) + return 1; + return 0; + case 0x40: + fprintf(sp->log, "found P core\n"); + if (sp->use_P_core) + return 1; + return 0; + default: + /* non hybrid arch, just use first core */ + fprintf(sp->log, "found non hybrid core topology\n"); + return 1; + } +} + +/* sof-pipe needs to be sticky to the current core for low latency */ +int pipe_set_affinity(struct sof_pipe *sp) +{ + cpu_set_t cpuset; + pthread_t thread; + long core_count = sysconf(_SC_NPROCESSORS_ONLN); + int i; + int err; + + /* Set affinity mask to core */ + thread = pthread_self(); + CPU_ZERO(&cpuset); + + /* find the first E core (usually come after the P cores ?) */ + for (i = core_count - 1; i >= 0; i--) { + CPU_ZERO(&cpuset); + CPU_SET(i, &cpuset); + + /* change our core to i */ + err = pthread_setaffinity_np(thread, sizeof(cpuset), &cpuset); + if (err != 0) { + fprintf(sp->log, "error: failed to set CPU affinity to core %d: %s\n", + i, strerror(err)); + return err; + } + + /* should we use this core ? */ + if (use_this_core(sp)) + break; + } + + return 0; +} + +/* set ipc thread to low priority */ +int pipe_set_ipc_lowpri(struct sof_pipe *sp) +{ + pthread_attr_t attr; + struct sched_param param; + int err; + + /* attempt to set thread priority - needs suid */ + fprintf(sp->log, "pipe: set IPC low priority\n"); + + err = pthread_attr_init(&attr); + if (err < 0) { + fprintf(sp->log, "error: can't create thread attr %d %s\n", err, strerror(errno)); + return err; + } + + err = pthread_attr_setschedpolicy(&attr, SCHED_OTHER); + if (err < 0) { + fprintf(sp->log, "error: can't set thread policy %d %s\n", err, strerror(errno)); + return err; + } + param.sched_priority = 0; + err = pthread_attr_setschedparam(&attr, ¶m); + if (err < 0) { + fprintf(sp->log, "error: can't set thread sched param %d %s\n", + err, strerror(errno)); + return err; + } + + return 0; +} + +/* set pipeline to realtime priority */ +int pipe_set_rt(struct sof_pipe *sp) +{ + pthread_attr_t attr; + struct sched_param param; + int err; + uid_t uid = getuid(); + uid_t euid = geteuid(); + + /* do we have elevated privileges to attempt RT priority */ + if (uid < 0 || uid != euid) { + /* attempt to set thread priority - needs suid */ + fprintf(sp->log, "pipe: set RT priority\n"); + + err = pthread_attr_init(&attr); + if (err < 0) { + fprintf(sp->log, "error: can't create thread attr %d %s\n", + err, strerror(errno)); + return err; + } + + err = pthread_attr_setschedpolicy(&attr, SCHED_FIFO); + if (err < 0) { + fprintf(sp->log, "error: can't set thread policy %d %s\n", + err, strerror(errno)); + return err; + } + param.sched_priority = 80; + err = pthread_attr_setschedparam(&attr, ¶m); + if (err < 0) { + fprintf(sp->log, "error: can't set thread sched param %d %s\n", + err, strerror(errno)); + return err; + } + err = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + if (err < 0) { + fprintf(sp->log, "error: can't set thread inherit %d %s\n", + err, strerror(errno)); + return err; + } + } else { + fprintf(sp->log, "error: no elevated privileges for RT. uid %d euid %d\n", + uid, euid); + } + + return 0; +} diff --git a/tools/plugin/pipe/ctl.c b/tools/plugin/pipe/ctl.c new file mode 100644 index 000000000000..c2c806621927 --- /dev/null +++ b/tools/plugin/pipe/ctl.c @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. +// +// Author: Liam Girdwood + +/* + * SOF pipeline in userspace. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "pipe.h" + +int pipe_kcontrol_cb_new(struct snd_soc_tplg_ctl_hdr *tplg_ctl, + void *_comp, void *arg) +{ + struct sof_pipe *sp = arg; + struct sof_ipc_comp *comp = _comp; + struct plug_shm_glb_state *glb = sp->glb; + struct plug_shm_ctl *ctl; + + if (glb->num_ctls >= MAX_CTLS) { + fprintf(sp->log, "error: too many ctls\n"); + return -EINVAL; + } + + switch (tplg_ctl->type) { + case SND_SOC_TPLG_CTL_VOLSW: + case SND_SOC_TPLG_CTL_VOLSW_SX: + case SND_SOC_TPLG_CTL_VOLSW_XR_SX: + { + struct snd_soc_tplg_mixer_control *tplg_mixer = + (struct snd_soc_tplg_mixer_control *)tplg_ctl; + + glb->size += sizeof(struct plug_shm_ctl); + ctl = &glb->ctl[glb->num_ctls++]; + ctl->comp_id = comp->id; + ctl->mixer_ctl = *tplg_mixer; + break; + } + case SND_SOC_TPLG_CTL_ENUM: + case SND_SOC_TPLG_CTL_ENUM_VALUE: + { + struct snd_soc_tplg_enum_control *tplg_enum = + (struct snd_soc_tplg_enum_control *)tplg_ctl; + + glb->size += sizeof(struct plug_shm_ctl); + ctl = &glb->ctl[glb->num_ctls++]; + ctl->comp_id = comp->id; + ctl->enum_ctl = *tplg_enum; + break; + } + case SND_SOC_TPLG_CTL_BYTES: + { + struct snd_soc_tplg_bytes_control *tplg_bytes = + (struct snd_soc_tplg_bytes_control *)tplg_ctl; + + glb->size += sizeof(struct plug_shm_ctl); + ctl = &glb->ctl[glb->num_ctls++]; + ctl->comp_id = comp->id; + ctl->bytes_ctl = *tplg_bytes; + break; + } + case SND_SOC_TPLG_CTL_RANGE: + case SND_SOC_TPLG_CTL_STROBE: + default: + fprintf(sp->log, "error: invalid ctl type %d\n", + tplg_ctl->type); + return -EINVAL; + } + + return 0; +} diff --git a/tools/plugin/pipe/ipc4.c b/tools/plugin/pipe/ipc4.c new file mode 100644 index 000000000000..9320eeef1999 --- /dev/null +++ b/tools/plugin/pipe/ipc4.c @@ -0,0 +1,444 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. +// +// Author: Liam Girdwood + +/* + * SOF pipeline in userspace. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "pipe.h" + +// TODO: take prefix from ALSA prefix +#define COMP_PREFIX "./sof_ep/install/lib/libsof_" +#define COMP_SUFFIX ".so" +#define UUID_STR_SIZE 32 + +struct sof_pipe_module_library_map { + int module_id; + const char *name; +}; + +static const struct sof_pipe_module_library_map library_map[] = { + {0x6, "libsof_volume.so"}, + {0x2, "libsof_mixer.so"}, + {0x3, "libsof_mixer.so"}, + /*FIXME: hack for now to set up ALSA and SHM components */ + {0x96, "libsof_mod_shm.so"}, /* host playback */ + {0x97, "libsof_mod_alsa.so"}, /* dai playback */ + {0x98, "libsof_mod_shm.so"}, /* host capture */ + {0x99, "libsof_mod_alsa.so"}, /* dai capture */ +}; + +static int pipe_register_comp(struct sof_pipe *sp, uint16_t module_id) +{ + const struct sof_pipe_module_library_map *lib; + int i; + + /* check if module already loaded */ + for (i = 0; i < sp->mod_idx; i++) { + if (sp->module[i].module_id == module_id) + return 0; /* module found and already loaded */ + } + + for (i = 0; i < ARRAY_SIZE(library_map); i++) { + lib = &library_map[i]; + + if (module_id == lib->module_id) + break; + } + + if (i == ARRAY_SIZE(library_map)) { + fprintf(stderr, "module ID: %d not supported\n", module_id); + return -ENOTSUP; + } + + /* not loaded, so load module */ + sp->module[sp->mod_idx].handle = dlopen(lib->name, RTLD_NOW); + if (!sp->module[sp->mod_idx].handle) { + fprintf(stderr, "error: cant load module %s: %s\n", + lib->name, dlerror()); + return -errno; + } + + sp->mod_idx++; + + return 0; +} + +#define iCS(x) ((x) & SOF_CMD_TYPE_MASK) +#define iGS(x) ((x) & SOF_GLB_TYPE_MASK) + +static int pipe_sof_ipc_cmd_before(struct sof_pipe *sp, void *mailbox, size_t bytes) +{ + struct ipc4_message_request *in = mailbox; + enum ipc4_message_target target = in->primary.r.msg_tgt; + int ret = 0; + + switch (target) { + case SOF_IPC4_MESSAGE_TARGET_MODULE_MSG: + { + uint32_t type = in->primary.r.type; + + switch (type) { + case SOF_IPC4_MOD_INIT_INSTANCE: + struct ipc4_module_init_instance *module_init = + (struct ipc4_module_init_instance *)in; + + ret = pipe_register_comp(sp, module_init->primary.r.module_id); + break; + default: + break; + } + break; + } + case SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG: + { + uint32_t type = in->primary.r.type; + + switch (type) { + case SOF_IPC4_GLB_SET_PIPELINE_STATE: + { + struct ipc4_pipeline_set_state *state; + struct ipc_comp_dev *ipc_pipe; + struct ipc *ipc = ipc_get(); + unsigned int pipeline_id; + + state = (struct ipc4_pipeline_set_state *)in; + pipeline_id = (unsigned int)state->primary.r.ppl_id; + + if (state->primary.r.ppl_state == SOF_IPC4_PIPELINE_STATE_PAUSED) { + ipc_pipe = ipc_get_pipeline_by_id(ipc, pipeline_id); + if (!ipc_pipe) { + fprintf(stderr, "No pipeline with instance_id = %u", + pipeline_id); + return -EINVAL; + } + + /* stop the pipeline thread */ + ret = pipe_thread_stop(sp, ipc_pipe->pipeline); + if (ret < 0) { + printf("error: can't start pipeline %d thread\n", + ipc_pipe->pipeline->comp_id); + return ret; + } + } + break; + } + default: + break; + } + break; + } + default: + fprintf(sp->log, "ipc: unknown command target %u size %ld", + target, bytes); + ret = -EINVAL; + break; + } + + return ret; +} + +static int pipe_sof_ipc_cmd_after(struct sof_pipe *sp, void *mailbox, size_t bytes) +{ + struct ipc4_message_request *in = mailbox; + enum ipc4_message_target target = in->primary.r.msg_tgt; + int ret = 0; + + switch (target) { + case SOF_IPC4_MESSAGE_TARGET_MODULE_MSG: + break; + case SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG: + { + uint32_t type = in->primary.r.type; + + switch (type) { + case SOF_IPC4_GLB_CREATE_PIPELINE: + { + struct ipc4_pipeline_create *pipe_desc = (struct ipc4_pipeline_create *)in; + struct ipc_comp_dev *ipc_pipe; + struct ipc *ipc = ipc_get(); + unsigned int pipeline_id = (unsigned int)pipe_desc->primary.r.instance_id; + + ipc_pipe = ipc_get_pipeline_by_id(ipc, pipeline_id); + if (!ipc_pipe) { + fprintf(stderr, "No pipeline with instance_id = %u\n", + pipeline_id); + return -EINVAL; + } + + /* create new pipeline thread */ + ret = pipe_thread_new(sp, ipc_pipe->pipeline); + if (ret < 0) { + printf("error: can't create pipeline %d thread\n", + ipc_pipe->pipeline->pipeline_id); + return ret; + } + break; + } + case SOF_IPC4_GLB_SET_PIPELINE_STATE: + { + struct ipc4_pipeline_set_state *state; + struct ipc_comp_dev *ipc_pipe; + struct ipc *ipc = ipc_get(); + unsigned int pipeline_id; + + state = (struct ipc4_pipeline_set_state *)in; + pipeline_id = (unsigned int)state->primary.r.ppl_id; + + if (state->primary.r.ppl_state == SOF_IPC4_PIPELINE_STATE_RUNNING) { + ipc_pipe = ipc_get_pipeline_by_id(ipc, pipeline_id); + if (!ipc_pipe) { + fprintf(stderr, "No pipeline with instance_id = %u\n", + pipeline_id); + return -EINVAL; + } + + /* start the pipeline thread */ + ret = pipe_thread_start(sp, ipc_pipe->pipeline); + if (ret < 0) { + printf("error: can't start pipeline %d thread\n", + ipc_pipe->pipeline->comp_id); + return ret; + } + } + break; + } + case SOF_IPC4_GLB_DELETE_PIPELINE: + { + struct ipc4_pipeline_create *pipe_desc = (struct ipc4_pipeline_create *)in; + unsigned int pipeline_id = (unsigned int)pipe_desc->primary.r.instance_id; + + /* free pipeline thread */ + ret = pipe_thread_free(sp, pipeline_id); + if (ret < 0) { + printf("error: can't free pipeline %d thread\n", + pipeline_id); + return ret; + } + + break; + } + default: + break; + } + break; + } + default: + fprintf(sp->log, "ipc: unknown command target %u size %ld", + target, bytes); + ret = -EINVAL; + break; + } + + return ret; +} + +int pipe_ipc_do(struct sof_pipe *sp, void *mailbox, size_t bytes) +{ + char mailbox_copy[IPC3_MAX_MSG_SIZE] = {0}; + int err = 0; + + /* preserve mailbox contents for local "after" config */ + memcpy(mailbox_copy, mailbox, bytes); + + /* some IPCs require pipe to perform actions before core */ + /* mailbox can be re-written here by local pipe if needed */ + err = pipe_sof_ipc_cmd_before(sp, mailbox, bytes); + if (err < 0) { + fprintf(sp->log, "error: local IPC processing failed\n"); + return err; + } + + /* is the IPC local only or do we need send to infra ? */ + err = pipe_ipc_message(sp, mailbox, bytes); + if (err < 0) { + fprintf(sp->log, "error: infra IPC processing failed\n"); + return err; + } + + /* some IPCs require pipe to perform actions before core */ + err = pipe_sof_ipc_cmd_after(sp, mailbox_copy, bytes); + if (err < 0) { + fprintf(sp->log, "error: local IPC processing failed\n"); + return err; + } + + return err; +} + +int pipe_ipc_process(struct sof_pipe *sp, struct plug_mq_desc *tx_mq, struct plug_mq_desc *rx_mq) +{ + ssize_t ipc_size; + char mailbox[IPC3_MAX_MSG_SIZE] = {0}; + int err; + struct timespec ts; + + /* IPC thread should not preempt processing thread */ + err = pipe_set_ipc_lowpri(sp); + if (err < 0) + fprintf(sp->log, "error: cant set PCM IPC thread to low priority"); + + /* create the IPC message queue */ + err = plug_mq_create(tx_mq); + if (err < 0) { + fprintf(sp->log, "error: can't create TX IPC message queue : %s\n", + strerror(errno)); + return -errno; + } + + /* create the IPC message queue */ + err = plug_mq_create(rx_mq); + if (err < 0) { + fprintf(sp->log, "error: can't create PCM IPC message queue : %s\n", + strerror(errno)); + return -errno; + } + + /* let main() know we are ready */ + fprintf(sp->log, "sof-pipe: IPC TX %s thread ready\n", tx_mq->queue_name); + fprintf(sp->log, "sof-pipe: IPC RX %s thread ready\n", rx_mq->queue_name); + + /* main PCM IPC handling loop */ + while (1) { + memset(mailbox, 0, IPC3_MAX_MSG_SIZE); + + /* is client dead ? */ + if (sp->glb->state == SOF_PLUGIN_STATE_DEAD) { + fprintf(sp->log, "sof-pipe: IPC %s client complete\n", tx_mq->queue_name); + break; + } + + ipc_size = mq_receive(tx_mq->mq, mailbox, IPC3_MAX_MSG_SIZE, NULL); + if (ipc_size < 0) { + fprintf(sp->log, "error: can't read PCM IPC message queue %s : %s\n", + tx_mq->queue_name, strerror(errno)); + break; + } + + /* TODO: properly validate message and continue if garbage */ + if (*((uint32_t *)mailbox) == 0) { + fprintf(sp->log, "sof-pipe: IPC %s garbage read\n", tx_mq->queue_name); + ts.tv_sec = 0; + ts.tv_nsec = 20 * 1000 * 1000; /* 20 ms */ + nanosleep(&ts, NULL); + continue; + } + + /* do the message work */ + //data_dump(mailbox, IPC3_MAX_MSG_SIZE); + + err = pipe_ipc_do(sp, mailbox, ipc_size); + if (err < 0) + fprintf(sp->log, "error: local IPC processing failed\n"); + + /* now return message completion status found in mailbox */ + err = mq_send(rx_mq->mq, mailbox, IPC3_MAX_MSG_SIZE, 0); + if (err < 0) { + fprintf(sp->log, "error: can't send PCM IPC message queue %s : %s\n", + rx_mq->queue_name, strerror(errno)); + break; + } + } + + fprintf(sp->log, "***sof-pipe: IPC %s thread finished !!\n", tx_mq->queue_name); + return 0; +} + +int plug_mq_cmd(struct plug_mq_desc *ipc, void *msg, size_t len, void *reply, size_t rlen) +{ + struct timespec ts; + ssize_t ipc_size; + char mailbox[IPC3_MAX_MSG_SIZE]; + int err; + + if (len > IPC3_MAX_MSG_SIZE) { + SNDERR("ipc: message too big %d\n", len); + return -EINVAL; + } + memset(mailbox, 0, IPC3_MAX_MSG_SIZE); + memcpy(mailbox, msg, len); + + /* wait for sof-pipe reader to consume data or timeout */ + err = clock_gettime(CLOCK_REALTIME, &ts); + if (err == -1) { + SNDERR("ipc: cant get time: %s", strerror(errno)); + return -errno; + } + + /* IPCs should be read under 10ms */ + plug_timespec_add_ms(&ts, 10); + + /* now return message completion status */ + err = mq_timedsend(ipc->mq, mailbox, IPC3_MAX_MSG_SIZE, 0, &ts); + if (err < 0) { + SNDERR("error: can't send IPC message queue %s : %s\n", + ipc->queue_name, strerror(errno)); + return -errno; + } + + /* wait for sof-pipe reader to consume data or timeout */ + err = clock_gettime(CLOCK_REALTIME, &ts); + if (err == -1) { + SNDERR("ipc: cant get time: %s", strerror(errno)); + return -errno; + } + + /* IPCs should be processed under 20ms */ + plug_timespec_add_ms(&ts, 20); + + ipc_size = mq_timedreceive(ipc->mq, mailbox, IPC3_MAX_MSG_SIZE, NULL, &ts); + if (ipc_size < 0) { + SNDERR("error: can't read IPC message queue %s : %s\n", + ipc->queue_name, strerror(errno)); + return -errno; + } + + /* do the message work */ + //printf("cmd got IPC %ld reply bytes\n", ipc_size); + if (rlen && reply) + memcpy(reply, mailbox, rlen); + + return 0; +} diff --git a/tools/plugin/pipe/main.c b/tools/plugin/pipe/main.c new file mode 100644 index 000000000000..3d9c831dba0b --- /dev/null +++ b/tools/plugin/pipe/main.c @@ -0,0 +1,377 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. +// +// Author: Liam Girdwood + +/* + * SOF pipeline in userspace. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "pipe.h" + +#define VERSION "v0.1" + +/* global needed for signal handler */ +struct sof_pipe *_sp; + +static void shutdown(struct sof_pipe *sp) +{ + struct pipethread_data *pipeline_ctx = sp->pipeline_ctx; + int i; + + /* free everything */ + munmap(sp->shm_context.addr, sp->shm_context.size); + shm_unlink(sp->shm_context.name); + + /* cancel all threads, free locks and message queues */ + for (i = 0; i < sp->pipe_thread_count; i++) { + struct pipethread_data *pd = &pipeline_ctx[i]; + + pthread_cancel(pd->ipc_thread); + pthread_cancel(pd->pcm_thread); + plug_mq_free(&pd->ipc_tx_mq); + plug_mq_free(&pd->ipc_rx_mq); + plug_lock_free(&pd->ready); + plug_lock_free(&pd->done); + } + + /* free the sof-pipe IPC tx/rx message queues */ + plug_mq_free(&sp->ipc_tx_mq); + plug_mq_free(&sp->ipc_rx_mq); + + pthread_mutex_destroy(&sp->ipc_lock); + + fflush(sp->log); + fflush(stdout); + fflush(stderr); +} + +/* signals from the ALSA PCM plugin or something has gone wrong */ +static void signal_handler(int sig) +{ + switch (sig) { + case SIGTERM: + fprintf(_sp->log, "Pipe caught SIGTERM - shutdown\n"); + break; + case SIGINT: + fprintf(_sp->log, "Pipe caught SIGINT - shutdown\n"); + break; + default: + fprintf(_sp->log, "Pipe caught signal %d, something went wrong\n", sig); + break; + } + fprintf(_sp->log, "Pipe shutdown signal\n"); + + /* try and clean up if we can */ + shutdown(_sp); + exit(EXIT_FAILURE); +} + +static int pipe_init_signals(struct sof_pipe *sp) +{ + struct sigaction *action = &sp->action; + int err; + + /* + * signals - currently only check for SIGCHLD. TODO: handle more + */ + sigemptyset(&action->sa_mask); + action->sa_handler = signal_handler; + err = sigaction(SIGTERM, action, NULL); + if (err < 0) { + fprintf(sp->log, "failed to register signal action: %s", + strerror(errno)); + return err; + } + + err = sigaction(SIGSEGV, action, NULL); + if (err < 0) { + fprintf(sp->log, "failed to register signal action: %s", + strerror(errno)); + return err; + } + + err = sigaction(SIGINT, action, NULL); + if (err < 0) { + fprintf(sp->log, "failed to register signal action: %s", + strerror(errno)); + return err; + } + + return 0; +} + +int pipe_ipc_message(struct sof_pipe *sp, void *mailbox, size_t bytes) +{ + struct ipc *ipc = ipc_get(); + + /* reply is copied back to mailbox */ + pthread_mutex_lock(&sp->ipc_lock); + memcpy(ipc->comp_data, mailbox, bytes); + ipc_cmd(mailbox); + memcpy(mailbox, ipc->comp_data, bytes); + pthread_mutex_unlock(&sp->ipc_lock); + + return 0; +} + +/* + * Create and open a new semaphore using the lock object. + */ +int plug_lock_create(struct plug_sem_desc *lock) +{ + /* delete any old stale resources that use our resource name */ + sem_unlink(lock->name); + + /* RW blocking lock */ + lock->sem = sem_open(lock->name, O_CREAT | O_RDWR | O_EXCL, SEM_PERMS, 0); + if (lock->sem == SEM_FAILED) { + SNDERR("failed to create semaphore %s: %s", lock->name, strerror(errno)); + return -errno; + } + + return 0; +} + +/* + * Free and delete semaphore resourses in lock object. + */ +void plug_lock_free(struct plug_sem_desc *lock) +{ + sem_close(lock->sem); + sem_unlink(lock->name); +} + +/* + * Create and open a new shared memory region using the SHM object. + */ +int plug_shm_create(struct plug_shm_desc *shm) +{ + int err; + + /* delete any old stale resources that use our resource name */ + shm_unlink(shm->name); + + /* open SHM to be used for low latency position */ + shm->fd = shm_open(shm->name, O_RDWR | O_CREAT, S_IRWXU | S_IRWXG); + if (shm->fd < 0) { + SNDERR("failed to create SHM position %s: %s", shm->name, strerror(errno)); + return -errno; + } + + /* set SHM size */ + err = ftruncate(shm->fd, shm->size); + if (err < 0) { + SNDERR("failed to truncate SHM position %s: %s", shm->name, strerror(errno)); + shm_unlink(shm->name); + return -errno; + } + + /* map it locally for context readback */ + shm->addr = mmap(NULL, shm->size, PROT_READ | PROT_WRITE, MAP_SHARED, shm->fd, 0); + if (!shm->addr) { + SNDERR("failed to mmap SHM position%s: %s", shm->name, strerror(errno)); + shm_unlink(shm->name); + return -errno; + } + + return 0; +} + +/* + * Free and delete shared memory region resourses in SHM object. + */ +void plug_shm_free(struct plug_shm_desc *shm) +{ + close(shm->fd); + shm_unlink(shm->name); +} + +/* + * Create and open a new message queue using the IPC object. + */ +int plug_mq_create(struct plug_mq_desc *ipc) +{ + /* delete any old stale resources that use our resource name */ + mq_unlink(ipc->queue_name); + + memset(&ipc->attr, 0, sizeof(ipc->attr)); + ipc->attr.mq_msgsize = IPC3_MAX_MSG_SIZE; + ipc->attr.mq_maxmsg = 1; + + /* now open new queue for Tx/Rx */ + ipc->mq = mq_open(ipc->queue_name, O_CREAT | O_RDWR | O_EXCL, + S_IRWXU | S_IRWXG, &ipc->attr); + if (ipc->mq < 0) { + fprintf(stderr, "failed to create IPC queue %s: %s\n", + ipc->queue_name, strerror(errno)); + return -errno; + } + + return 0; +} + +/* + * Free and delete message queue resources in IPC object. + */ +void plug_mq_free(struct plug_mq_desc *ipc) +{ + mq_close(ipc->mq); + mq_unlink(ipc->queue_name); +} + +/* + * -D ALSA device. e.g. + * -R realtime (needs parent to set uid) + * -p Force run on P core + * -e Force run on E core + * -t topology name. + * -L log file (otherwise stdout) + * -h help + */ +static void usage(char *name) +{ + fprintf(stdout, "Usage: %s -D ALSA device -T topology\n", name); +} + +int main(int argc, char *argv[], char *env[]) +{ + struct sof_pipe sp = {0}; + int option = 0; + int ret = 0; + + /* default config */ + sp.log = stdout; + sp.alsa_name = "default"; /* default sound device */ + _sp = &sp; + + /* parse all args */ + while ((option = getopt(argc, argv, "hD:RpeT:")) != -1) { + switch (option) { + /* Alsa device */ + case 'D': + sp.alsa_name = strdup(optarg); + break; + case 'R': + sp.realtime = 1; + break; + case 'p': + sp.use_P_core = 1; + sp.use_E_core = 0; + break; + case 'e': + sp.use_E_core = 1; + sp.use_P_core = 0; + break; + case 'T': + snprintf(sp.topology_name, NAME_SIZE, "%s", optarg); + break; + + /* print usage */ + default: + fprintf(sp.log, "unknown option %c\n", option); + __attribute__ ((fallthrough)); + case 'h': + usage(argv[0]); + exit(EXIT_SUCCESS); + } + } + + /* validate cmd line params */ + if (strlen(sp.topology_name) == 0) { + fprintf(sp.log, "error: no IPC topology name specified\n"); + exit(EXIT_FAILURE); + } + + /* global IPC access serialisation mutex */ + ret = pthread_mutex_init(&sp.ipc_lock, NULL); + if (ret < 0) { + fprintf(sp.log, "error: cant create mutex %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + + fprintf(sp.log, "sof-pipe-%s: using topology %s\n", VERSION, sp.topology_name); + + /* set CPU affinity */ + if (sp.use_E_core || sp.use_P_core) { + ret = pipe_set_affinity(&sp); + if (ret < 0) + goto out; + } + + /* initialize ipc and scheduler */ + if (pipe_sof_setup(sof_get()) < 0) { + fprintf(stderr, "error: pipeline init\n"); + exit(EXIT_FAILURE); + } + + /* global context - plugin clients open this first */ + ret = plug_shm_init(&sp.shm_context, sp.topology_name, "ctx", 0); + if (ret < 0) + goto out; + + /* cleanup any lingering global IPC files */ + shm_unlink(sp.shm_context.name); + + /* make sure we can cleanly shutdown */ + ret = pipe_init_signals(&sp); + if (ret < 0) + goto out; + + /* mmap context on successful topology load */ + ret = plug_shm_create(&sp.shm_context); + if (ret < 0) + goto out; + + /* now prep the global context for client plugin access */ + sp.glb = sp.shm_context.addr; + memset(sp.glb, 0, sizeof(*sp.glb)); + sprintf(sp.glb->magic, "%s", SOF_MAGIC); + sp.glb->size = sizeof(*sp.glb); + sp.glb->state = SOF_PLUGIN_STATE_INIT; + sp.tplg.tplg_file = sp.topology_name; + sp.tplg.ipc_major = 4; //HACK hard code to v4 + + /* sofpipe is now ready */ + sp.glb->state = SOF_PLUGIN_STATE_INIT; + + ret = plug_mq_init(&sp.ipc_tx_mq, "sof", "ipc-tx", 0); + if (ret < 0) + goto out; + + ret = plug_mq_init(&sp.ipc_rx_mq, "sof", "ipc-rx", 0); + if (ret < 0) + goto out; + + /* now process IPCs as they arrive from plugins */ + ret = pipe_ipc_process(&sp, &sp.ipc_tx_mq, &sp.ipc_rx_mq); + +out: + fprintf(sp.log, "shutdown main\n"); + shutdown(&sp); + return ret; +} diff --git a/tools/plugin/pipe/pipe.h b/tools/plugin/pipe/pipe.h new file mode 100644 index 000000000000..3cc95bf8401e --- /dev/null +++ b/tools/plugin/pipe/pipe.h @@ -0,0 +1,126 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022-2023 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + */ + +#ifndef __SOF_PLUGIN_PIPE_H__ +#define __SOF_PLUGIN_PIPE_H__ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include "common.h" + +struct sof_pipe; + +#define MAX_MODULE_ID 256 +#define MAX_PIPE_THREADS 128 +#define MAX_PIPELINES 32 + +struct pipethread_data { + pthread_t pcm_thread; + pthread_t ipc_thread; + struct sof_pipe *sp; + struct plug_mq_desc ipc_tx_mq; + struct plug_mq_desc ipc_rx_mq; + struct pipeline *pcm_pipeline; + /* PCM flow control */ + struct plug_sem_desc ready; + struct plug_sem_desc done; + atomic_int pipe_users; +}; + +struct sof_pipe_module { + void *handle; + char uuid[SOF_UUID_SIZE]; + int module_id; +}; + +struct sof_pipe { + const char *alsa_name; + char topology_name[NAME_SIZE]; + int realtime; + int use_P_core; + int use_E_core; + int capture; + int file_mode; + int pipe_thread_count; + + struct sigaction action; + + /* SHM for stream context sync */ + struct plug_shm_desc shm_context; + struct plug_shm_glb_state *glb; + + FILE *log; + pthread_mutex_t ipc_lock; + struct tplg_context tplg; + struct tplg_comp_info *comp_list; + struct list_item widget_list; /* list of widgets */ + struct list_item route_list; /* list of widget connections */ + struct list_item pcm_list; /* list of PCMs */ + int info_elems; + int info_index; + + /* IPC */ + pthread_t ipc_pcm_thread; + struct plug_mq_desc ipc_tx_mq; /* queue used by plugin to send IPCs */ + struct plug_mq_desc ipc_rx_mq; /* queue used by plugin to receive the IPC response */ + + /* module SO handles */ + struct sof_pipe_module module[MAX_MODULE_ID]; + int mod_idx; + + /* pipeline context */ + struct pipethread_data pipeline_ctx[MAX_PIPELINES]; +}; + +/* global needed for signal handler */ +extern struct sof_pipe *_sp; + +int pipe_thread_new(struct sof_pipe *sp, struct pipeline *p); +int pipe_thread_free(struct sof_pipe *sp, int pipeline_id); +int pipe_thread_start(struct sof_pipe *sp, struct pipeline *p); +int pipe_thread_stop(struct sof_pipe *sp, struct pipeline *p); +int pipe_sof_setup(struct sof *sof); +int pipe_kcontrol_cb_new(struct snd_soc_tplg_ctl_hdr *tplg_ctl, + void *comp, void *arg); + +/* set pipeline to realtime priority */ +int pipe_set_rt(struct sof_pipe *sp); + +/* set ipc thread to low priority */ +int pipe_set_ipc_lowpri(struct sof_pipe *sp); + +int pipe_ipc_process(struct sof_pipe *sp, struct plug_mq_desc *tx_mq, struct plug_mq_desc *rx_mq); + +int pipe_ipc_new(struct sof_pipe *sp, int pri, int core); +void pipe_ipc_free(struct sof_pipe *sp); + +int pipe_set_affinity(struct sof_pipe *sp); + +int pipe_ipc_message(struct sof_pipe *sp, void *mailbox, size_t bytes); + +int pipe_ipc_do(struct sof_pipe *sp, void *mailbox, size_t bytes); + +/* + * Topology + */ +int plug_parse_topology(struct sof_pipe *sp, struct tplg_context *ctx); + +int plug_load_widget(struct sof_pipe *sp, struct tplg_context *ctx); + +int plug_register_graph(struct sof_pipe *sp, struct tplg_context *ctx, + struct tplg_comp_info *temp_comp_list, + char *pipeline_string, + int count, int num_comps, int pipeline_id); + +#endif diff --git a/tools/plugin/pipe/pipeline.c b/tools/plugin/pipe/pipeline.c new file mode 100644 index 000000000000..831b60a3b6a9 --- /dev/null +++ b/tools/plugin/pipe/pipeline.c @@ -0,0 +1,380 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. +// +// Author: Liam Girdwood + +/* + * SOF pipeline in userspace. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "pipe.h" + +#define MAX_PIPE_USERS 8 + +static struct ll_schedule_domain domain = {0}; + +// TODO: all these steps are probably not needed - i.e we only need IPC and pipeline. +int pipe_sof_setup(struct sof *sof) +{ + /* register modules */ + + domain.next_tick = 0; + + /* init components */ + sys_comp_init(sof); + + /* other necessary initializations, todo: follow better SOF init */ + pipeline_posn_init(sof); + init_system_notify(sof); + + /* init IPC */ + if (ipc_init(sof) < 0) { + fprintf(stderr, "error: IPC init\n"); + return -EINVAL; + } + + /* init LL scheduler */ + if (scheduler_init_ll(&domain) < 0) { + fprintf(stderr, "error: edf scheduler init\n"); + return -EINVAL; + } + + /* init EDF scheduler */ + if (scheduler_init_edf() < 0) { + fprintf(stderr, "error: edf scheduler init\n"); + return -EINVAL; + } + + return 0; +} + +static inline int pipe_copy_ready(struct pipethread_data *pd) +{ + struct timespec delay; + int err; + + /* get the current time for source delay */ + err = clock_gettime(CLOCK_REALTIME, &delay); + if (err == -1) { + fprintf(_sp->log, "shm: cant get time: %s", strerror(errno)); + return -errno; + } + + // TODO get from rate + plug_timespec_add_ms(&delay, 2000); + + /* wait for data from source */ + err = sem_timedwait(pd->ready.sem, &delay); + if (err == -1) { + fprintf(_sp->log, "%s %d: fatal timeout: %s on %s\n", __FILE__, __LINE__, + strerror(errno), pd->ready.name); + return -errno; + } + + return 0; +} + +static inline void pipe_copy_done(struct pipethread_data *pd) +{ + /* tell peer we are done */ + sem_post(pd->done.sem); +} + +static void *pipe_process_thread(void *arg) +{ + struct pipethread_data *pd = arg; + int err; + + fprintf(_sp->log, "pipe thread started for pipeline %d\n", + pd->pcm_pipeline->pipeline_id); + + do { + if (pd->pcm_pipeline->status != COMP_STATE_ACTIVE) { + fprintf(_sp->log, "pipe state non active %d\n", + pd->pcm_pipeline->status); + break; + } + + if (pd->pipe_users <= 0) { + fprintf(_sp->log, "pipe no users.\n"); + break; + } + + /* wait for pipe to be ready */ + err = pipe_copy_ready(pd); + if (err < 0) { + fprintf(_sp->log, "pipe ready timeout on pipeline %d state %d users %d\n", + pd->pcm_pipeline->pipeline_id, pd->pcm_pipeline->status, + pd->pipe_users); + break; + } + + /* sink has read data so now generate more it */ + err = pipeline_copy(pd->pcm_pipeline); + + pipe_copy_done(pd); + + if (err < 0) { + fprintf(_sp->log, "pipe thread error %d\n", err); + break; + } else if (err > 0) { + fprintf(_sp->log, "pipe thread complete %d\n", err); + break; + } + + } while (1); + + fprintf(_sp->log, "pipe complete for pipeline %d\n", + pd->pcm_pipeline->pipeline_id); + return 0; +} + +static void *pipe_ipc_process_thread(void *arg) +{ + struct pipethread_data *pd = arg; + int err; + + /* initialise semaphores to default starting value */ + err = sem_init(pd->done.sem, 1, 0); + if (err < 0) { + fprintf(_sp->log, "failed to reset DONE: %s\n", + strerror(errno)); + return NULL; + } + err = sem_init(pd->ready.sem, 1, 0); + if (err < 0) { + fprintf(_sp->log, "failed to reset READY: %s\n", + strerror(errno)); + return NULL; + } + + err = pipe_ipc_process(pd->sp, &pd->ipc_tx_mq, &pd->ipc_rx_mq); + if (err < 0) { + fprintf(_sp->log, "pipe IPC thread error for pipeline %d\n", + pd->pcm_pipeline->pipeline_id); + } + + return NULL; +} + +int pipe_thread_start(struct sof_pipe *sp, struct pipeline *p) +{ + struct pipethread_data *pipeline_ctx = sp->pipeline_ctx; + struct pipethread_data *pd; + int pipeline_id; + int ret, pipe_users; + + pipeline_id = p->pipeline_id; + + if (pipeline_id >= MAX_PIPELINES) { + fprintf(_sp->log, "error: pipeline ID %d out of range\n", pipeline_id); + return -EINVAL; + } + + if (!pipeline_ctx[pipeline_id].sp) { + fprintf(_sp->log, "error: pipeline ID %d not in use\n", pipeline_id); + return -EINVAL; + } + pd = &pipeline_ctx[pipeline_id]; + + /* only create thread if not active */ + pipe_users = atomic_fetch_add(&pd->pipe_users, 1); + if (pipe_users > 0) { + fprintf(_sp->log, "pipeline ID %d thread already running %d users\n", + pipeline_id, pipe_users); + return 0; + } + + fprintf(_sp->log, "pipeline ID %d thread not running so starting...\n", pipeline_id); + + /* first user so start the PCM pipeline thread */ + ret = pthread_create(&pd->pcm_thread, NULL, pipe_process_thread, pd); + if (ret < 0) { + fprintf(_sp->log, "failed to create PCM thread: %s\n", strerror(errno)); + return -errno; + } + + return ret; +} + +int pipe_thread_stop(struct sof_pipe *sp, struct pipeline *p) +{ + struct pipethread_data *pipeline_ctx = sp->pipeline_ctx; + struct pipethread_data *pd; + int pipeline_id; + int ret, pipe_users; + + pipeline_id = p->pipeline_id; + + /* this is called when the pipeline is PAUSED for the first time before RUNNING */ + if (p->status == COMP_STATE_INIT) + return 0; + + if (pipeline_id >= MAX_PIPELINES) { + fprintf(_sp->log, "error: pipeline ID %d out of range\n", pipeline_id); + return -EINVAL; + } + + if (!pipeline_ctx[pipeline_id].sp) { + fprintf(_sp->log, "error: pipeline ID %d not in use\n", pipeline_id); + return -EINVAL; + } + pd = &pipeline_ctx[pipeline_id]; + + /* only join thread if not active */ + pipe_users = atomic_fetch_sub(&pd->pipe_users, 1); + if (pipe_users != 1) { + fprintf(_sp->log, "pipeline ID %d thread has multiple %d users\n", + pipeline_id, pipe_users); + return 0; + } + + fprintf(_sp->log, "pipeline ID %d thread can be stopped...\n", pipeline_id); + + ret = pthread_cancel(pd->pcm_thread); + if (ret < 0) { + fprintf(_sp->log, "failed to cancel PCM thread: %s\n", strerror(errno)); + return -errno; + } + + return ret; +} + +int pipe_thread_new(struct sof_pipe *sp, struct pipeline *p) +{ + struct pipethread_data *pipeline_ctx = sp->pipeline_ctx; + struct pipethread_data *pd; + int ret; + + if (!p) { + fprintf(_sp->log, "error: invalid pipeline\n"); + return -EINVAL; + } + + if (p->pipeline_id >= MAX_PIPELINES) { + fprintf(_sp->log, "error: pipeline ID %d out of range\n", p->pipeline_id); + return -EINVAL; + } + + if (pipeline_ctx[p->pipeline_id].sp) { + fprintf(_sp->log, "error: pipeline ID %d in use\n", p->pipeline_id); + return -EINVAL; + } + pd = &pipeline_ctx[p->pipeline_id]; + pd->sp = _sp; + pd->pcm_pipeline = p; + + /* initialise global IPC data */ + /* TODO: change the PCM name to tplg or make it per PID*/ + ret = plug_mq_init(&pd->ipc_tx_mq, pd->sp->topology_name, "pcm-tx", p->pipeline_id); + if (ret < 0) + return -EINVAL; + mq_unlink(pd->ipc_tx_mq.queue_name); + + ret = plug_mq_init(&pd->ipc_rx_mq, pd->sp->topology_name, "pcm-rx", p->pipeline_id); + if (ret < 0) + return -EINVAL; + mq_unlink(pd->ipc_rx_mq.queue_name); + + /* init names of shared resources */ + ret = plug_lock_init(&pd->ready, _sp->topology_name, "ready", p->pipeline_id); + if (ret < 0) + return ret; + + ret = plug_lock_init(&pd->done, _sp->topology_name, "done", p->pipeline_id); + if (ret) + return ret; + + /* open semaphores */ + ret = plug_lock_create(&pd->ready); + if (ret < 0) + return ret; + ret = plug_lock_create(&pd->done); + if (ret < 0) + goto lock_err; + + /* start IPC pipeline thread */ + ret = pthread_create(&pd->ipc_thread, NULL, pipe_ipc_process_thread, pd); + if (ret < 0) { + fprintf(_sp->log, "failed to create IPC thread: %s\n", strerror(errno)); + ret = -errno; + goto lock2_err; + } + + return 0; + +lock2_err: + plug_lock_free(&pd->done); +lock_err: + plug_lock_free(&pd->ready); + return ret; +} + +int pipe_thread_free(struct sof_pipe *sp, int pipeline_id) +{ + struct pipethread_data *pipeline_ctx = sp->pipeline_ctx; + struct pipethread_data *pd; + int err; + + if (pipeline_id >= MAX_PIPELINES) { + fprintf(_sp->log, "error: pipeline ID %d out of range\n", pipeline_id); + return -EINVAL; + } + + if (!pipeline_ctx[pipeline_id].sp) { + fprintf(_sp->log, "error: pipeline ID %d not in use\n", pipeline_id); + return -EINVAL; + } + + pd = &pipeline_ctx[pipeline_id]; + + err = pthread_cancel(pd->ipc_thread); + if (err < 0) { + fprintf(_sp->log, "failed to create IPC thread: %s\n", strerror(errno)); + return -errno; + } + + plug_mq_free(&pd->ipc_tx_mq); + mq_unlink(pd->ipc_tx_mq.queue_name); + plug_mq_free(&pd->ipc_rx_mq); + mq_unlink(pd->ipc_rx_mq.queue_name); + + plug_lock_free(&pd->ready); + plug_lock_free(&pd->done); + + pd->sp = NULL; + return 0; +} diff --git a/tools/probes/probes_demux.c b/tools/probes/probes_demux.c index 3db021e8a6e3..a411eef117b9 100644 --- a/tools/probes/probes_demux.c +++ b/tools/probes/probes_demux.c @@ -139,8 +139,9 @@ int init_wave(struct dma_frame_parser *p, uint32_t buffer_id, uint32_t format) return i; } -void finalize_wave_files(struct wave_files *files) +void finalize_wave_files(struct dma_frame_parser *p) { + struct wave_files *files = p->files; uint32_t i, chunk_size; /* fill the header at the beginning of each file */ diff --git a/tools/probes/probes_demux.h b/tools/probes/probes_demux.h index a656d4c7af47..93aa89119a5e 100644 --- a/tools/probes/probes_demux.h +++ b/tools/probes/probes_demux.h @@ -24,4 +24,6 @@ void parser_fetch_free_buffer(struct dma_frame_parser *p, uint8_t **d, size_t *l int parser_parse_data(struct dma_frame_parser *p, size_t d_len); +void finalize_wave_files(struct dma_frame_parser *p); + #endif diff --git a/tools/probes/probes_main.c b/tools/probes/probes_main.c index 7b553709a446..cdba2c6347d5 100644 --- a/tools/probes/probes_main.c +++ b/tools/probes/probes_main.c @@ -66,6 +66,10 @@ void parse_data(const char *file_in, bool log_to_stdout) len = fread(data, 1, len, fd_in); ret = parser_parse_data(p, len); } while (!ret && !feof(fd_in)); + + if (!log_to_stdout) + finalize_wave_files(p); + } int main(int argc, char *argv[]) diff --git a/tools/rimage/.checkpatch.conf b/tools/rimage/.checkpatch.conf new file mode 100644 index 000000000000..98ddafcb3fb1 --- /dev/null +++ b/tools/rimage/.checkpatch.conf @@ -0,0 +1,6 @@ +--codespell +--codespellfile scripts/spelling.txt +--ignore C99_COMMENT_TOLERANCE +--no-tree +--strict +-g diff --git a/tools/rimage/CMakeLists.txt b/tools/rimage/CMakeLists.txt new file mode 100644 index 000000000000..8e0a5da7d267 --- /dev/null +++ b/tools/rimage/CMakeLists.txt @@ -0,0 +1,67 @@ +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.10) + +project(SOF_RIMAGE C) + +if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "No CMAKE_BUILD_TYPE, defaulting to Debug") + set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build Type" FORCE) +endif() + +add_executable(rimage + src/file_simple.c + src/cse.c + src/css.c + src/plat_auth.c + src/hash.c + src/pkcs1_5.c + src/manifest.c + src/ext_manifest.c + src/rimage.c + src/toml_utils.c + src/adsp_config.c + src/misc_utils.c + src/file_utils.c + src/elf_file.c + src/module.c + tomlc99/toml.c +) + +set_property(TARGET rimage PROPERTY C_STANDARD 99) + +target_compile_options(rimage PRIVATE + -Wall -Werror -Wmissing-prototypes -Wimplicit-fallthrough +) + +if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 9.1) + target_compile_options(rimage PRIVATE -Wno-char-subscripts) +endif() + +# Windows builds use MSYS2 https://www.msys2.org/ to get linux tools and headers. +# MSYS_INSTALL_DIR variable points to MSYS2 installation directory. +# You may pass it as environmental or cmake configure variable. +if(${CMAKE_HOST_WIN32}) + cmake_minimum_required(VERSION 3.20) + if(DEFINED ENV{MSYS_INSTALL_DIR} AND NOT MSYS_INSTALL_DIR) + set(MSYS_INSTALL_DIR $ENV{MSYS_INSTALL_DIR}) + endif() + + if(MSYS_INSTALL_DIR) + cmake_path(IS_ABSOLUTE MSYS_INSTALL_DIR IS_MSYS_INSTALL_DIR_ABSOLUTE) + if(NOT IS_MSYS_INSTALL_DIR_ABSOLUTE) + message(FATAL_ERROR "Please provide absolute path to MSYS2 installation + setting MSYS_INSTALL_DIR env variable") + endif() + # Include standard posix headers. Requires pacman openssl-devel package. + cmake_path(APPEND MSYS_INSTALL_DIR "usr" "include" OUTPUT_VARIABLE MSYS_SYSTEM_INCLUDE_PATH) + target_include_directories(rimage PRIVATE "${MSYS_SYSTEM_INCLUDE_PATH}") + endif() +endif() + +target_link_libraries(rimage PRIVATE crypto) + +target_include_directories(rimage PRIVATE + src/include/ + tomlc99/ +) diff --git a/tools/rimage/LICENSE b/tools/rimage/LICENSE new file mode 100644 index 000000000000..468893dff94b --- /dev/null +++ b/tools/rimage/LICENSE @@ -0,0 +1,97 @@ +/* + * BSD 3 Clause + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +// Copyright (c) 2003-2014 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. + + +Files with 2-Clause BSD licence: + +src/include/rimage/elf.h + +/* + * Derived from: + * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $ + * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $ + * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $ + * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $ + * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $ + * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $ + * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $ + * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $ + * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $ + * + * Copyright (c) 1996-1998 John D. Polstra. All rights reserved. + * Copyright (c) 2001 David E. O'Brien + * Portions Copyright 2009 The Go Authors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ diff --git a/tools/rimage/README.md b/tools/rimage/README.md new file mode 100644 index 000000000000..9f32fffa5cb1 --- /dev/null +++ b/tools/rimage/README.md @@ -0,0 +1,105 @@ +# rimage + +`rimage` is a DSP firmware image creation and signing tool targeting +the DSP on certain Intel System-on-Chip (SoC). This is used by +the [Sound Open Firmware (SOF)](https://github.com/thesofproject/sof) +to generate binary image files. + +## Building + +Most SOF users never build `rimage` directly but as an ExternalProject +defined by CMake in SOF. This makes sure they always use an up-to-date +version of rimage and configuration files that have been fully tested. + +If needed, `rimage` can be built manually with the usual CMake commands: + +```shell +$ cmake -B build/ +$ make -C build/ help # lists all targets +$ make -C build/ +``` + +The `build/rimage` executable can then be copied to a directory in the +PATH. Zephyr users can run `west config rimage.path +/path/to/rimage/build/rimage`; Zephyr documentation and `west sign -h` +have more details. + +## Testing tomlc99 changes with SOF Continuous Integration + +This section is about leveraging SOF validation to test tomlc99 changes +_before_ submitting them to the tomlc99 repository. + +Nothing here is actually specific to SOF and tomlc99; you can apply the +same test logic to any submodule and parent on Github. In fact the same +logic applies to submodule alternatives. Github is the only requirement. + +### Get familiar with git submodules + +This is unfortunately not optional for SOF and tomlc99. + +For various reasons submodules seem to confuse many git users. Maybe +because the versions of the submodules are not directly visible in some +configuration file like with most alternatives? Either way, an +unfortunate prerequisite before doing any tomlc99 work is to get familiar +with git submodules in general. As submodules are built-in there are +many resources about them on the Internet. One possible starting point +is https://git-scm.com/book/en/v2/Git-Tools-Submodules but feel free +to use any other good tutorial instead. Make sure you actually practice +a tutorial; don't just read it. Practicing on a temporary and throw-away +copy of SOF + tomlc99 is a great idea. + +Obviously, you also need to be familiar with regular Github pull +requests. + +### Run SOF tests on unmerged tomlc99 commits + +First, push the tomlc99 commits you want to be tested to any branch of +your tomlc99 fork on Github. Do _not_ submit an tomlc99 pull request yet. + +Note your tomlc99 fork must have been created using the actual "fork" +button on Github so Github is aware of the connection with the upstream +tomlc99 repo. In the top-left corner you should see `forked from +thesofproject/tomlc99` under the name of your fork. If not then search +the Internet for "re-attach detached github fork". + +Then, **pretend** these tomlc99 commits have already been accepted and +merged (they have been neither) and submit to SOF a draft pull request +that updates the main SOF branch with your brand new tomlc99 commits to +test. The only SOF commit in this SOF TEST pull request is an SOF commit +that updates the tomlc99 pointer to the SHA of your last tomlc99 +commit. If you're not sure how to do this then you must go back to the +previous section and practice submodules more. + +Submit this SOF pull request as a Github _draft_ so reviewers are _not_ +notified. Starting every pull request as a draft is always a good idea +but in this case this particular SOF pull request can be especially +confusing because it points at commits in a different repo and commits +that are not merged yet. So you _really_ don't want to bother busy +reviewers (here's a secret: some of the reviewers don't like submodules +either). You can freely switch back and forth between draft and ready +status and should indeed switch to draft if you forgot at submission +time but you can never "un-notify" reviewers. + +Github has very good support for submodules and will display your SOF +TEST pull request better than what the git command line can show. For +instance Github will list your tomlc99 changes directly in the SOF Pull +Request. So if something looks unexpected on Github then it means you +did something wrong. Stop immediately (except for switching to draft if +you forgot) and ask the closest git guru for help. + +Search for "Submodule" in the build logs and make sure the last of your +new tomlc99 commits has been checked out. + +Iterate and force-push your tomlc99 branch and your SOF TEST pull request +until all the SOF tests pass. Then you can submit your tomlc99 pull +request as usual. In the comments section of the tomlc99 pull request, +point at your test results on the SOF side to impress the tomlc99 +reviewers and get your tomlc99 changes merged faster. + +Finally, after your tomlc99 changes have been merged, you can if you want +submit one final SOF pull request that points to the final tomlc99 +SHA. Or, if your tomlc99 change is not urgently needed, you can just wait +for someone else to do it later. If you do it, copy the tomlc99 git log +--oneline in the SOF commit message. Find some good (and less good) +commit message examples for submodule updates at +https://github.com/thesofproject/sof/commits/main/rimage diff --git a/tools/rimage/config/acp_6_3.toml b/tools/rimage/config/acp_6_3.toml new file mode 100644 index 000000000000..8a6286dde153 --- /dev/null +++ b/tools/rimage/config/acp_6_3.toml @@ -0,0 +1,20 @@ +version = [1, 0] # use simple file write + +[adsp] +name = "acp_6_3" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0x7F000000" +size = "0x60000" +host_offset = "0x0" +[[adsp.mem_zone]] +type = "DRAM" +base = "0xE0000000" +size = "0x20000" +host_offset = "0x0" +[[adsp.mem_zone]] +type = "SRAM" +base = "0x60006000" +size = "0x27A000" +host_offset = "0x0" diff --git a/tools/rimage/config/apl.toml b/tools/rimage/config/apl.toml new file mode 100644 index 000000000000..e100c78a754c --- /dev/null +++ b/tools/rimage/config/apl.toml @@ -0,0 +1,57 @@ +version = [1, 8] + +[adsp] +name = "apl" +image_size = "0x0A0000" # (8 + 2) bank * 64KB +alias_mask = "0xE0000000" + +[[adsp.mem_zone]] +type = "ROM" +base = "0xBEFE0000" +size = "0x00002000" +[[adsp.mem_zone]] +type = "SRAM" +base = "0xA000A000" +size = "0x100000" + +[[adsp.mem_alias]] +type = "uncached" +base = "0x9E000000" +[[adsp.mem_alias]] +type = "cached" +base = "0xBE000000" + +[cse] +partition_name = "ADSP" +[[cse.entry]] +name = "ADSP.man" +offset = "0x58" +length = "0x378" +[[cse.entry]] +name = "cavs0015.met" +offset = "0x400" +length = "0x60" +[[cse.entry]] +name = "cavs0015" +offset = "0x480" +length = "0x0" # calculated by rimage + +[css] + +[signed_pkg] +name = "ADSP" +[[signed_pkg.module]] +name = "cavs0015.met" + +[partition_info] +name = "ADSP" +[[partition_info.module]] +name = "cavs0015.met" + +[adsp_file] +[[adsp_file.comp]] +base_offset = "0x2000" + +[fw_desc.header] +name = "ADSPFW" +load_offset = "0x2000" diff --git a/tools/rimage/config/bdw.toml b/tools/rimage/config/bdw.toml new file mode 100644 index 000000000000..6b642fcd882e --- /dev/null +++ b/tools/rimage/config/bdw.toml @@ -0,0 +1,15 @@ +version = [1, 0] # use simple file write + +[adsp] +name = "bdw" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0" +size = "0x50000" +host_offset = "0x000A0000" +[[adsp.mem_zone]] +type = "DRAM" +base = "0x00400000" +size = "0xA0000" +host_offset = "0x0" diff --git a/tools/rimage/config/bsw.toml b/tools/rimage/config/bsw.toml new file mode 100644 index 000000000000..6746ca6cff34 --- /dev/null +++ b/tools/rimage/config/bsw.toml @@ -0,0 +1,15 @@ +version = [1, 0] # use simple file write + +[adsp] +name = "bsw" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0xFF2C0000" +size = "0x14000" +host_offset = "0x0C0000" +[[adsp.mem_zone]] +type = "DRAM" +base = "0xFF300000" +size = "0x28000" +host_offset = "0x100000" diff --git a/tools/rimage/config/byt.toml b/tools/rimage/config/byt.toml new file mode 100644 index 000000000000..4afd1c0dd523 --- /dev/null +++ b/tools/rimage/config/byt.toml @@ -0,0 +1,15 @@ +version = [1, 0] # use simple file write + +[adsp] +name = "byt" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0xFF2C0000" +size = "0x14000" +host_offset = "0x0C0000" +[[adsp.mem_zone]] +type = "DRAM" +base = "0xFF300000" +size = "0x28000" +host_offset = "0x100000" diff --git a/tools/rimage/config/cht.toml b/tools/rimage/config/cht.toml new file mode 100644 index 000000000000..2ed88370d16a --- /dev/null +++ b/tools/rimage/config/cht.toml @@ -0,0 +1,15 @@ +version = [1, 0] # use simple file write + +[adsp] +name = "cht" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0xFF2C0000" +size = "0x14000" +host_offset = "0x0C0000" +[[adsp.mem_zone]] +type = "DRAM" +base = "0xFF300000" +size = "0x28000" +host_offset = "0x100000" diff --git a/tools/rimage/config/cnl.toml b/tools/rimage/config/cnl.toml new file mode 100644 index 000000000000..ccf33fb68e2a --- /dev/null +++ b/tools/rimage/config/cnl.toml @@ -0,0 +1,61 @@ +version = [1, 8] + +[adsp] +name = "cnl" +image_size = "0x300000" # (47 + 1) bank * 64KB +alias_mask = "0xE0000000" + +[[adsp.mem_zone]] +type = "ROM" +base = "0xBEFE0000" +size = "0x00002000" +[[adsp.mem_zone]] +type = "IMR" +base = "0xB0038000" +size = "0x100000" +[[adsp.mem_zone]] +type = "SRAM" +base = "0xBE040000" +size = "0x100000" + +[[adsp.mem_alias]] +type = "uncached" +base = "0x9E000000" +[[adsp.mem_alias]] +type = "cached" +base = "0xBE000000" + +[cse] +partition_name = "ADSP" +[[cse.entry]] +name = "ADSP.man" +offset = "0x58" +length = "0x378" +[[cse.entry]] +name = "cavs0015.met" +offset = "0x400" +length = "0x60" +[[cse.entry]] +name = "cavs0015" +offset = "0x480" +length = "0x0" # calculated by rimage + +[css] + +[signed_pkg] +name = "ADSP" +[[signed_pkg.module]] +name = "cavs0015.met" + +[partition_info] +name = "ADSP" +[[partition_info.module]] +name = "cavs0015.met" + +[adsp_file] +[[adsp_file.comp]] +base_offset = "0x2000" + +[fw_desc.header] +name = "ADSPFW" +load_offset = "0x30000" diff --git a/tools/rimage/config/hsw.toml b/tools/rimage/config/hsw.toml new file mode 100644 index 000000000000..2f96a675b89d --- /dev/null +++ b/tools/rimage/config/hsw.toml @@ -0,0 +1,15 @@ +version = [1, 0] # use simple file write + +[adsp] +name = "hsw" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0" +size = "0x60000" +host_offset = "0x80000" +[[adsp.mem_zone]] +type = "DRAM" +base = "0x00400000" +size = "0x80000" +host_offset = "0x0" diff --git a/tools/rimage/config/icl.toml b/tools/rimage/config/icl.toml new file mode 100644 index 000000000000..f6e0fc9cb209 --- /dev/null +++ b/tools/rimage/config/icl.toml @@ -0,0 +1,61 @@ +version = [1, 8] + +[adsp] +name = "icl" +image_size = "0x300000" # (47 + 1) bank * 64KB +alias_mask = "0xE0000000" + +[[adsp.mem_zone]] +type = "ROM" +base = "0xBEFE0000" +size = "0x00002000" +[[adsp.mem_zone]] +type = "IMR" +base = "0xB0038000" +size = "0x100000" +[[adsp.mem_zone]] +type = "SRAM" +base = "0xBE040000" +size = "0x100000" + +[[adsp.mem_alias]] +type = "uncached" +base = "0x9E000000" +[[adsp.mem_alias]] +type = "cached" +base = "0xBE000000" + +[cse] +partition_name = "ADSP" +[[cse.entry]] +name = "ADSP.man" +offset = "0x58" +length = "0x378" +[[cse.entry]] +name = "cavs0015.met" +offset = "0x400" +length = "0x60" +[[cse.entry]] +name = "cavs0015" +offset = "0x480" +length = "0x0" # calculated by rimage + +[css] + +[signed_pkg] +name = "ADSP" +[[signed_pkg.module]] +name = "cavs0015.met" + +[partition_info] +name = "ADSP" +[[partition_info.module]] +name = "cavs0015.met" + +[adsp_file] +[[adsp_file.comp]] +base_offset = "0x2000" + +[fw_desc.header] +name = "ADSPFW" +load_offset = "0x30000" diff --git a/tools/rimage/config/imx8.toml b/tools/rimage/config/imx8.toml new file mode 100644 index 000000000000..865be902e840 --- /dev/null +++ b/tools/rimage/config/imx8.toml @@ -0,0 +1,20 @@ +version = [1, 0] # use simple file write + +[adsp] +name = "imx8" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0x596F8000" +size = "0x800" +host_offset = "0x10000" +[[adsp.mem_zone]] +type = "DRAM" +base = "0x596E8000" +size = "0x8000" +host_offset = "0x0" +[[adsp.mem_zone]] +type = "SRAM" +base = "0x92400000" +size = "0x800000" +host_offset = "0x0" diff --git a/tools/rimage/config/imx8m.toml b/tools/rimage/config/imx8m.toml new file mode 100644 index 000000000000..5b7ba20870bd --- /dev/null +++ b/tools/rimage/config/imx8m.toml @@ -0,0 +1,20 @@ +version = [1, 0] # use simple file write + +[adsp] +name = "imx8m" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0x3b6F8000" +size = "0x800" +host_offset = "0x10000" +[[adsp.mem_zone]] +type = "DRAM" +base = "0x3B6E8000" +size = "0x8000" +host_offset = "0x0" +[[adsp.mem_zone]] +type = "SRAM" +base = "0x92400000" +size = "0x800000" +host_offset = "0x0" diff --git a/tools/rimage/config/imx8ulp.toml b/tools/rimage/config/imx8ulp.toml new file mode 100644 index 000000000000..7fd4c16a52f3 --- /dev/null +++ b/tools/rimage/config/imx8ulp.toml @@ -0,0 +1,20 @@ +version = [1, 0] # use simple file write + +[adsp] +name = "imx8ulp" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0x21170000" +size = "0x10000" +host_offset = "0x0" +[[adsp.mem_zone]] +type = "DRAM" +base = "0x21180000" +size = "0x10000" +host_offset = "0x10000" +[[adsp.mem_zone]] +type = "SRAM" +base = "0x1a000000" +size = "0x800000" +host_offset = "0x0" diff --git a/tools/rimage/config/imx8x.toml b/tools/rimage/config/imx8x.toml new file mode 100644 index 000000000000..ea9059c174ae --- /dev/null +++ b/tools/rimage/config/imx8x.toml @@ -0,0 +1,20 @@ +version = [1, 0] # use simple file write + +[adsp] +name = "imx8x" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0x596F8000" +size = "0x800" +host_offset = "0x10000" +[[adsp.mem_zone]] +type = "DRAM" +base = "0x596e8000" +size = "0x8000" +host_offset = "0x0" +[[adsp.mem_zone]] +type = "SRAM" +base = "0x92400000" +size = "0x800000" +host_offset = "0x0" diff --git a/tools/rimage/config/jsl.toml b/tools/rimage/config/jsl.toml new file mode 100644 index 000000000000..bec0e6bd3a7e --- /dev/null +++ b/tools/rimage/config/jsl.toml @@ -0,0 +1,61 @@ +version = [1, 8] + +[adsp] +name = "icl" +image_size = "0x110000" # (16 + 1) bank * 64KB +alias_mask = "0xE0000000" + +[[adsp.mem_zone]] +type = "ROM" +base = "0xBEFE0000" +size = "0x00002000" +[[adsp.mem_zone]] +type = "IMR" +base = "0xB0038000" +size = "0x100000" +[[adsp.mem_zone]] +type = "SRAM" +base = "0xBE040000" +size = "0x100000" + +[[adsp.mem_alias]] +type = "uncached" +base = "0x9E000000" +[[adsp.mem_alias]] +type = "cached" +base = "0xBE000000" + +[cse] +partition_name = "ADSP" +[[cse.entry]] +name = "ADSP.man" +offset = "0x58" +length = "0x378" +[[cse.entry]] +name = "cavs0015.met" +offset = "0x400" +length = "0x60" +[[cse.entry]] +name = "cavs0015" +offset = "0x480" +length = "0x0" # calculated by rimage + +[css] + +[signed_pkg] +name = "ADSP" +[[signed_pkg.module]] +name = "cavs0015.met" + +[partition_info] +name = "ADSP" +[[partition_info.module]] +name = "cavs0015.met" + +[adsp_file] +[[adsp_file.comp]] +base_offset = "0x2000" + +[fw_desc.header] +name = "ADSPFW" +load_offset = "0x30000" diff --git a/tools/rimage/config/kbl.toml b/tools/rimage/config/kbl.toml new file mode 100644 index 000000000000..f1c83d594905 --- /dev/null +++ b/tools/rimage/config/kbl.toml @@ -0,0 +1,30 @@ +version = [1, 5] + +[adsp] +name = "kbl" +image_size = "0x200000" # (30 + 2) bank * 64KB +alias_mask = "0xE0000000" + +[[adsp.mem_zone]] +type = "ROM" +base = "0xBEFE0000" +size = "0x00002000" +[[adsp.mem_zone]] +type = "SRAM" +base = "0xA000A000" +size = "0x100000" + +[[adsp.mem_alias]] +type = "uncached" +base = "0x9E000000" +[[adsp.mem_alias]] +type = "cached" +base = "0xBE000000" + +[css] + +[fw_desc.header] +name = "ADSPFW" +load_offset = "0" +hw_buf_base_addr = "0xBE500000" +hw_buf_length = "0x4A000" diff --git a/tools/rimage/config/lnl.toml b/tools/rimage/config/lnl.toml new file mode 100644 index 000000000000..879ec9097231 --- /dev/null +++ b/tools/rimage/config/lnl.toml @@ -0,0 +1,587 @@ +version = [3, 0] + +[adsp] +name = "lnl" +image_size = "0x2C0000" # (22) bank * 128KB +alias_mask = "0xE0000000" + +[[adsp.mem_zone]] +type = "ROM" +base = "0x1FF80000" +size = "0x400" +[[adsp.mem_zone]] +type = "IMR" +base = "0xA104A000" +size = "0x2000" +[[adsp.mem_zone]] +type = "SRAM" +base = "0xa00f0000" +size = "0x100000" + +[[adsp.mem_alias]] +type = "uncached" +base = "0x40000000" +[[adsp.mem_alias]] +type = "cached" +base = "0xA0000000" + +[cse] +partition_name = "ADSP" +[[cse.entry]] +name = "ADSP.man" +offset = "0x5c" +length = "0x4b8" +[[cse.entry]] +name = "ADSP.met" +offset = "0x4c0" +length = "0x70" +[[cse.entry]] +name = "ADSP" +offset = "0x540" +length = "0x0" # calculated by rimage + +[css] + +[signed_pkg] +name = "ADSP" +[[signed_pkg.module]] +name = "ADSP.met" + +[adsp_file] +[[adsp_file.comp]] +base_offset = "0x2000" + +[fw_desc.header] +name = "ADSPFW" +load_offset = "0x40000" + +[module] +count = 25 + [[module.entry]] + name = "BRNGUP" + uuid = "2B79E4F3-4675-F649-89DF-3BC194A91AEB" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "0" + auto_start = "0" + + [[module.entry]] + name = "BASEFW" + uuid = "0E398C32-5ADE-BA4B-93B1-C50432280EE4" + affinity_mask = "3" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "0" + auto_start = "0" + + [[module.entry]] + name = "MIXIN" + uuid = "39656EB2-3B71-4049-8D3F-F92CD5C43C09" + affinity_mask = "0x1" + instance_count = "30" + domain_types = "0" + load_type = "0" + module_type = "1" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [ 0, 0, 0, 0, 296, 644000, 45, 60, 0, 0, 0, + 1, 0, 0, 0, 296, 669900, 48, 64, 0, 0, 0, + 2, 0, 0, 0, 296, 934000, 96, 128, 0, 0, 0, + 3, 0, 0, 0, 296, 1137000, 96, 128, 0, 0, 0, + 4, 0, 0, 0, 296, 1482000, 48, 64, 0, 0, 0, + 5, 0, 0, 0, 296, 1746000, 96, 128, 0, 0, 0, + 6, 0, 0, 0, 296, 2274000, 192, 256, 0, 0, 0, + 7, 0, 0, 0, 296, 2700000, 48, 64, 0, 0, 0, + 8, 0, 0, 0, 296, 2964000, 96, 128, 0, 0, 0, + 9, 0, 0, 0, 296, 3492000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "MIXOUT" + uuid = "3C56505A-24D7-418F-BDDC-C1F5A3AC2AE0" + affinity_mask = "0x1" + instance_count = "30" + domain_types = "0" + load_type = "0" + module_type = "2" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 520, 649600, 48, 64, 0, 0, 0, + 1, 0, 0, 0, 520, 966300, 96, 128, 0, 0, 0, + 2, 0, 0, 0, 520, 2101000, 48, 64, 0, 0, 0, + 3, 0, 0, 0, 520, 2500800, 192, 256, 0, 0, 0, + 4, 0, 0, 0, 520, 2616700, 192, 256, 0, 0, 0, + 5, 0, 0, 0, 520, 2964500, 192, 256, 0, 0, 0, + 6, 0, 0, 0, 520, 4202000, 96, 128, 0, 0, 0, + 7, 0, 0, 0, 520, 3730000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "COPIER" + uuid = "9BA00C83-CA12-4A83-943C-1FA2E82F9DDA" + affinity_mask = "0x1" + instance_count = "32" + domain_types = "0" + load_type = "0" + module_type = "3" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [ 0, 0, 0, 0, 280, 640100, 45, 60, 0, 0, 0, + 1, 0, 0, 0, 280, 1106300, 192, 192, 0, 0, 0, + 2, 0, 0, 0, 280, 1573000, 45, 45, 0, 0, 0, + 3, 0, 0, 0, 280, 2040600, 192, 256, 0, 0, 0, + 4, 0, 0, 0, 280, 2507500, 192, 256, 0, 0, 0, + 5, 0, 0, 0, 280, 2999000, 192, 256, 0, 0, 0, + 6, 0, 0, 0, 280, 3501000, 45, 60, 0, 0, 0, + 7, 0, 0, 0, 280, 3927000, 192, 256, 0, 0, 0, + 8, 0, 0, 0, 280, 4424000, 192, 256, 0, 0, 0, + 9, 0, 0, 0, 280, 4941000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "PEAKVOL" + uuid = "8A171323-94A3-4E1D-AFE9-FE5DBAA4C393" + affinity_mask = "0x1" + instance_count = "10" + domain_types = "0" + load_type = "0" + module_type = "4" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 480, 1114000, 48, 64, 0, 0, 0, + 1, 0, 0, 0, 480, 3321600, 192, 256, 0, 0, 0, + 2, 0, 0, 0, 480, 3786000, 192, 256, 0, 0, 0, + 3, 0, 0, 0, 480, 4333000, 48, 64, 0, 0, 0, + 4, 0, 0, 0, 480, 4910000, 192, 256, 0, 0, 0, + 5, 0, 0, 0, 480, 5441000, 192, 256, 0, 0, 0, + 6, 0, 0, 0, 480, 6265000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "GAIN" + uuid = "61BCA9A8-18D0-4A18-8E7B-2639219804B7" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 416, 914000, 48, 64, 0, 0, 0, + 1, 0, 0, 0, 416, 1321600, 192, 256, 0, 0, 0, + 2, 0, 0, 0, 416, 1786000, 192, 256, 0, 0, 0, + 3, 0, 0, 0, 416, 2333000, 48, 64, 0, 0, 0, + 4, 0, 0, 0, 416, 2910000, 192, 256, 0, 0, 0, + 5, 0, 0, 0, 416, 3441000, 192, 256, 0, 0, 0, + 6, 0, 0, 0, 416, 4265000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "ASRC" + uuid = "66B4402D-B468-42F2-81A7-B37121863DD4" + affinity_mask = "0x3" + instance_count = "2" + domain_types = "0" + + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + pin = [0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x45ff] + + mod_cfg = [0, 0, 0, 0, 20480, 4065600, 24, 22, 0, 0, 0, + 1, 0, 0, 0, 20480, 5616000, 8, 25, 0, 0, 0, + 2, 0, 0, 0, 20480, 7319200, 24, 27, 0, 0, 0, + 3, 0, 0, 0, 20480, 9155300, 8, 27, 0, 0, 0, + 4, 0, 0, 0, 20480, 10972600, 48, 54, 0, 0, 0, + 5, 0, 0, 0, 20480, 12661000, 16, 36, 0, 0, 0, + 6, 0, 0, 0, 20480, 14448500, 48, 96, 0, 0, 0, + 7, 0, 0, 0, 20480, 16145000, 19, 68, 0, 0, 0, + 8, 0, 0, 0, 20480, 17861300, 45, 102, 0, 0, 0, + 9, 0, 0, 0, 20480, 21425900, 8, 36, 0, 0, 0, + 10, 0, 0, 0, 20480, 22771000, 32, 102, 0, 0, 0, + 11, 0, 0, 0, 20480, 23439000, 48, 27, 0, 0, 0, + 12, 0, 0, 0, 20480, 33394000, 48, 51, 0, 0, 0, + 13, 0, 0, 0, 20480, 36140000, 16, 96, 0, 0, 0, + 14, 0, 0, 0, 20480, 38003000, 16, 68, 0, 0, 0, + 15, 0, 0, 0, 20480, 39787000, 45, 51, 0, 0, 0] + + [[module.entry]] + name = "SRC" + uuid = "E61BB28D-149A-4C1F-B709-46823EF5F5AE" + affinity_mask = "0x1" + #instance_count = "10" + domain_types = "0" + load_type = "0" + module_type = "7" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xffff, 0xc, 0x8, 0x05ff, + 1, 0, 0xf6c9, 0xc, 0x8, 0x05ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 12832, 1365500, 0, 0, 0, 1365, 0, + 1, 0, 0, 0, 12832, 2302300, 0, 0, 0, 2302, 0, + 2, 0, 0, 0, 12832, 3218200, 0, 0, 0, 3218, 0, + 3, 0, 0, 0, 12832, 4169700, 0, 0, 0, 4169, 0, + 4, 0, 0, 0, 12832, 5095100, 0, 0, 0, 5095, 0, + 5, 0, 0, 0, 12832, 6014800, 0, 0, 0, 6014, 0, + 6, 0, 0, 0, 12832, 6963500, 0, 0, 0, 6963, 0, + 7, 0, 0, 0, 12832, 7791000, 0, 0, 0, 7791, 0, + 8, 0, 0, 0, 12832, 8843000, 0, 0, 0, 8843, 0, + 9, 0, 0, 0, 12832, 9755100, 0, 0, 0, 9755, 0, + 10, 0, 0, 0, 12832, 10726500, 0, 0, 0, 10726, 0, + 11, 0, 0, 0, 12832, 11624100, 0, 0, 0, 11624, 0, + 12, 0, 0, 0, 12832, 12518700, 0, 0, 0, 12518, 0, + 13, 0, 0, 0, 12832, 13555000, 0, 0, 0, 13555, 0, + 14, 0, 0, 0, 12832, 14144500, 0, 0, 0, 14144, 0, + 15, 0, 0, 0, 12832, 15809800, 0, 0, 0, 15809, 0, + 16, 0, 0, 0, 12832, 16749000, 0, 0, 0, 16749, 0, + 17, 0, 0, 0, 12832, 18433500, 0, 0, 0, 18433, 0, + 18, 0, 0, 0, 12832, 19425900, 0, 0, 0, 19425, 0, + 19, 0, 0, 0, 12832, 20396900, 0, 0, 0, 20396, 0, + 20, 0, 0, 0, 12832, 20881000, 0, 0, 0, 20881, 0, + 21, 0, 0, 0, 12832, 23431000, 0, 0, 0, 23431, 0, + 22, 0, 0, 0, 12832, 30471000, 0, 0, 0, 30471, 0] + + [[module.entry]] + name = "MICSEL" + uuid = "32FE92C1-1E17-4FC2-9758-C7F3542E980A" + affinity_mask = "0x1" + instance_count = "8" + domain_types = "0" + load_type = "0" + init_config = "1" + module_type = "0xC" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xe, 0xa, 0x45ff, 1, 0, 0xfeef, 0xe, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 960, 488500, 16, 16, 0, 0, 0, + 1, 0, 0, 0, 960, 964500, 16, 16, 0, 0, 0, + 2, 0, 0, 0, 960, 2003000, 16, 16, 0, 0, 0] + + [[module.entry]] + name = "UPDWMIX" + uuid = "42F8060C-832F-4DBF-B247-51E961997B34" + affinity_mask = "0x1" + instance_count = "15" + domain_types = "0" + load_type = "0" + module_type = "5" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xffff, 0xc, 0x8, 0x05ff, + 1, 0, 0xffff, 0xc, 0x8, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 216, 706000, 12, 16, 0, 0, 0, + 1, 0, 0, 0, 216, 1271000, 8, 8, 0, 0, 0, + 2, 0, 0, 0, 216, 1839000, 89, 118, 0, 0, 0, + 3, 0, 0, 0, 216, 2435000, 48, 64, 0, 0, 0, + 4, 0, 0, 0, 216, 3343000, 192, 192, 0, 0, 0, + 5, 0, 0, 0, 216, 3961000, 177, 177, 0, 0, 0, + 6, 0, 0, 0, 216, 4238000, 192, 256, 0, 0, 0, + 7, 0, 0, 0, 216, 6691000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "PROBE" + uuid = "7CAD0808-AB10-CD23-EF45-12AB34CD56EF" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 100000, 48, 48, 0, 1000, 0] + + [[module.entry]] + name = "MUX" + uuid = "64ce6e35-857a-4878-ace8-e2a2f42e3069" + affinity_mask = "0x1" + instance_count = "15" + domain_types = "0" + load_type = "0" + module_type = "6" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 280, 460700, 16, 16, 0, 0, 0] + + [[module.entry]] + name = "KDTEST" + uuid = "EBA8D51F-7827-47B5-82EE-DE6E7743AF67" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "8" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 480, 1114000, 64, 64, 0, 0, 0] + + [[module.entry]] + name = "KPB" + uuid = "A8A0CB32-4A77-4DB1-85C7-53D7EE07BCE6" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "0xB" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 14400, 1114000, 16, 16, 0, 0, 0] + + # smart amp test module config + [[module.entry]] + name = "SMATEST" + uuid = "167A961E-8AE4-11EA-89F1-000C29CE1635" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + init_config = "1" + module_type = "0xD" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # eq iir module config + [[module.entry]] + name = "EQIIR" + uuid = "5150C0E6-27F9-4EC8-8351-C705B642D12F" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # eq fir module config + [[module.entry]] + name = "EQFIR" + uuid = "43A90CE7-f3A5-41Df-AC06-BA98651AE6A3" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # Aria module config + [[module.entry]] + name = "ARIA" + uuid = "99F7166D-372C-43EF-81F6-22007AA15F03" + affinity_mask = "0x1" + instance_count = "8" + domain_types = "0" + load_type = "0" + init_config = "1" + module_type = "30" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 260, 1063000, 16, 21, 0, 0, 0, + 1, 0, 0, 0, 260, 1873500, 192, 256, 0, 0, 0, + 2, 0, 0, 0, 260, 2680000, 32, 42, 0, 0, 0, + 3, 0, 0, 0, 260, 3591000, 64, 85, 0, 0, 0, + 4, 0, 0, 0, 260, 4477000, 96, 128, 0, 0, 0, + 5, 0, 0, 0, 260, 7195000, 192, 192, 0, 0, 0] + + # DRC module config + [[module.entry]] + name = "DRC" + uuid = "B36EE4DA-006F-47F9-A06D-FECBE2D8B6CE" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # Crossover module config + # Note: Crossover has init_config set to 1 to let kernel know that the base_cfg_ext needs to + # be appended to the IPC payload. The Extension is needed to know the output pin indices. + [[module.entry]] + name = "XOVER" + uuid = "948C9AD1-806A-4131-AD6C-B2BDA9E35A9F" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + init_config = "1" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # Multiband-DRC module config + [[module.entry]] + name = "MB_DRC" + uuid = "0D9F2256-8E4F-47B3-8448-239A334F1191" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # DCblock module config + [[module.entry]] + name = "DCBLOCK" + uuid = "B809EFAF-5681-42B1-9ED6-04BB012DD384" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + [[module.entry]] + name = "RTC_AEC" + uuid = "B780A0A6-269F-466F-B477-23DFA05AF758" + affinity_mask = "0x3" + instance_count = "1" + domain_types = "0" + load_type = "1" + module_type = "10" + init_config = "1" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0x8, 0x2, 0x2, 0x1, + 0, 0, 0x8, 0x2, 0x2, 0x4, + 1, 0, 0x8, 0x2, 0x2, 0x1] + + # TDFB module config + [[module.entry]] + name = "TDFB" + uuid = "DD511749-D9FA-455C-B3A7-13585693F1AF" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] diff --git a/tools/rimage/config/mt8186.toml b/tools/rimage/config/mt8186.toml new file mode 100644 index 000000000000..80b011b4bfd4 --- /dev/null +++ b/tools/rimage/config/mt8186.toml @@ -0,0 +1,15 @@ +version = [1, 0] # use simple file write + +[adsp] +name = "mt8186" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0x4e100000" +size = "0x00100000" +host_offset = "0x0" +[[adsp.mem_zone]] +type = "SRAM" +base = "0x60000000" +size = "0x00600000" +host_offset = "0x0" diff --git a/tools/rimage/config/mt8188.toml b/tools/rimage/config/mt8188.toml new file mode 100644 index 000000000000..0dcc4b4b3244 --- /dev/null +++ b/tools/rimage/config/mt8188.toml @@ -0,0 +1,15 @@ +version = [1, 0] # parse_adsp_config_v1_0() + +[adsp] +name = "mt8188" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0x4e100000" +size = "0x00080000" +host_offset = "0x0" +[[adsp.mem_zone]] +type = "SRAM" +base = "0x60000000" +size = "0x00600000" +host_offset = "0x0" diff --git a/tools/rimage/config/mt8195.toml b/tools/rimage/config/mt8195.toml new file mode 100644 index 000000000000..5c8abc92557a --- /dev/null +++ b/tools/rimage/config/mt8195.toml @@ -0,0 +1,15 @@ +version = [1, 0] # use simple file write + +[adsp] +name = "mt8195" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0x40000000" +size = "0x00040000" +host_offset = "0x0" +[[adsp.mem_zone]] +type = "SRAM" +base = "0x60000000" +size = "0x00600000" +host_offset = "0x0" diff --git a/tools/rimage/config/mtl.toml b/tools/rimage/config/mtl.toml new file mode 100644 index 000000000000..d401ac81eaba --- /dev/null +++ b/tools/rimage/config/mtl.toml @@ -0,0 +1,692 @@ +version = [3, 0] + +[adsp] +name = "mtl" +image_size = "0x2C0000" # (22) bank * 128KB +alias_mask = "0xE0000000" + +[[adsp.mem_zone]] +type = "ROM" +base = "0x1FF80000" +size = "0x400" +[[adsp.mem_zone]] +type = "IMR" +base = "0xA104A000" +size = "0x2000" +[[adsp.mem_zone]] +type = "SRAM" +base = "0xa00f0000" +size = "0x100000" + +[[adsp.mem_alias]] +type = "uncached" +base = "0x40000000" +[[adsp.mem_alias]] +type = "cached" +base = "0xA0000000" + +[cse] +partition_name = "ADSP" +[[cse.entry]] +name = "ADSP.man" +offset = "0x5c" +length = "0x4b8" +[[cse.entry]] +name = "ADSP.met" +offset = "0x4c0" +length = "0x70" +[[cse.entry]] +name = "ADSP" +offset = "0x540" +length = "0x0" # calculated by rimage + +[css] + +[signed_pkg] +name = "ADSP" +[[signed_pkg.module]] +name = "ADSP.met" + +[adsp_file] +[[adsp_file.comp]] +base_offset = "0x2000" + +[fw_desc.header] +name = "ADSPFW" +load_offset = "0x40000" + +[module] +count = 27 + [[module.entry]] + name = "BRNGUP" + uuid = "2B79E4F3-4675-F649-89DF-3BC194A91AEB" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "0" + auto_start = "0" + + [[module.entry]] + name = "BASEFW" + uuid = "0E398C32-5ADE-BA4B-93B1-C50432280EE4" + affinity_mask = "3" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "0" + auto_start = "0" + + [[module.entry]] + name = "MIXIN" + uuid = "39656EB2-3B71-4049-8D3F-F92CD5C43C09" + affinity_mask = "0x1" + instance_count = "30" + domain_types = "0" + load_type = "0" + module_type = "1" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [1, 0, 0, 0, 296, 4996000, 384, 384, 0, 4996, 0, + 2, 0, 0, 0, 296, 2652000, 384, 384, 0, 2652, 0, + 3, 0, 0, 0, 296, 2928000, 512, 512, 0, 2928, 0, + 4, 0, 0, 0, 296, 2572000, 128, 128, 0, 2572, 0, + 5, 0, 0, 0, 296, 3760000, 1536, 1536, 0, 3760, 0] + + [[module.entry]] + name = "MIXOUT" + uuid = "3C56505A-24D7-418F-BDDC-C1F5A3AC2AE0" + affinity_mask = "0x1" + instance_count = "30" + domain_types = "0" + load_type = "0" + module_type = "2" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [1, 0, 0, 0, 520, 2280000, 384, 384, 0, 2280, 0, + 2, 0, 0, 0, 520, 1988000, 384, 384, 0, 1988, 0, + 3, 0, 0, 0, 520, 7631000, 512, 512, 0, 7631, 0, + 4, 0, 0, 0, 520, 1953000, 128, 128, 0, 1953, 0, + 5, 0, 0, 0, 520, 2301000, 1536, 1536, 0, 2301, 0] + + [[module.entry]] + name = "COPIER" + uuid = "9BA00C83-CA12-4A83-943C-1FA2E82F9DDA" + affinity_mask = "0x1" + instance_count = "32" + domain_types = "0" + load_type = "0" + module_type = "3" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [1, 0, 0, 0, 280, 4918000, 768, 768, 0, 4918, 0, + 2, 0, 0, 0, 280, 6526000, 768, 768, 0, 6526, 0, + 3, 0, 0, 0, 280, 6388000, 384, 384, 0, 6388, 0, + 4, 0, 0, 0, 280, 4682000, 512, 512, 0, 4682, 0, + 5, 0, 0, 0, 280, 5738000, 512, 512, 0, 5738, 0, + 6, 0, 0, 0, 280, 6250000, 256, 256, 0, 6250, 0, + 7, 0, 0, 0, 280, 6460000, 768, 768, 0, 6460, 0, + 8, 0, 0, 0, 280, 7116000, 768, 768, 0, 7116, 0, + 9, 0, 0, 0, 280, 6008000, 384, 384, 0, 6008, 0, + 10, 0, 0, 0, 280, 6258000, 512, 512, 0, 6258, 0, + 11, 0, 0, 0, 280, 7188000, 1024, 1024, 0, 7188, 0, + 12, 0, 0, 0, 280, 7272000, 1536, 1536, 0, 7272, 0, + 13, 0, 0, 0, 280, 6290000, 768, 768, 0, 6290, 0, + 14, 0, 0, 0, 280, 6604000, 1024, 1024, 0, 6604, 0, + 15, 0, 0, 0, 280, 6198000, 384, 384, 0, 6198, 0, + 16, 0, 0, 0, 280, 6250000, 384, 384, 0, 6250, 0, + 17, 0, 0, 0, 280, 6258000, 256, 256, 0, 6258, 0, + 18, 0, 0, 0, 280, 4354000, 256, 256, 0, 4354, 0, + 19, 0, 0, 0, 280, 6198000, 256, 256, 0, 6198, 0, + 20, 0, 0, 0, 280, 6250000, 128, 128, 0, 6250, 0, + 21, 0, 0, 0, 280, 6250000, 128, 128, 0, 6250, 0, + 22, 0, 0, 0, 280, 6206000, 128, 128, 0, 6206, 0, + 23, 0, 0, 0, 280, 4170000, 64, 64, 0, 4170, 0, + 24, 0, 0, 0, 280, 4234000, 96, 96, 0, 4234, 0, + 25, 0, 0, 0, 280, 6198000, 96, 96, 0, 6198, 0, + 26, 0, 0, 0, 280, 6250000, 96, 96, 0, 6250, 0, + 27, 0, 0, 0, 280, 6198000, 192, 192, 0, 6198, 0, + 28, 0, 0, 0, 280, 6258000, 192, 192, 0, 6258, 0, + 29, 0, 0, 0, 280, 6392000, 720, 720, 0, 6392, 0, + 30, 0, 0, 0, 280, 6250000, 360, 360, 0, 6250, 0, + 31, 0, 0, 0, 280, 5326000, 360, 360, 0, 5326, 0, + 32, 0, 0, 0, 280, 6258000, 180, 180, 0, 6258, 0, + 33, 0, 0, 0, 280, 4354000, 256, 256, 0, 4354, 0, + 34, 0, 0, 0, 280, 4898000, 256, 256, 0, 4898, 0, + 35, 0, 0, 0, 280, 6246000, 128, 128, 0, 6246, 0, + 36, 0, 0, 0, 280, 6250000, 192, 192, 0, 6250, 0, + 37, 0, 0, 0, 280, 6250000, 48, 48, 0, 6250, 0, + 38, 0, 0, 0, 280, 4170000, 64, 64, 0, 4170, 0, + 39, 0, 0, 0, 280, 6198000, 64, 64, 0, 6198, 0, + 40, 0, 0, 0, 280, 6246000, 32, 32, 0, 6246, 0, + 41, 0, 0, 0, 280, 5272000, 192, 384, 0, 5272, 0] + + [[module.entry]] + name = "PEAKVOL" + uuid = "8A171323-94A3-4E1D-AFE9-FE5DBAA4C393" + affinity_mask = "0x1" + instance_count = "10" + domain_types = "0" + load_type = "0" + module_type = "4" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [1, 0, 0, 0, 480, 11667000, 384, 384, 0, 11667, 0, + 2, 0, 0, 0, 480, 5943000, 192, 192, 0, 5943, 0, + 3, 0, 0, 0, 480, 12567000, 720, 720, 0, 12567, 0, + 4, 0, 0, 0, 480, 7360000, 768, 768, 0, 7360, 0, + 5, 0, 0, 0, 480, 12236000, 1536, 1536, 0, 12236, 0] + + [[module.entry]] + name = "GAIN" + uuid = "61BCA9A8-18D0-4A18-8E7B-2639219804B7" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [1, 0, 0, 0, 416, 12100000, 1536, 1536, 0, 12100, 0, + 2, 0, 0, 0, 416, 10183000, 384, 384, 0, 10183, 0, + 3, 0, 0, 0, 416, 8192000, 512, 512, 0, 8192, 0, + 4, 0, 0, 0, 416, 10091000, 128, 128, 0, 10091, 0, + 5, 0, 0, 0, 416, 5908000, 768, 768, 0, 5908, 0] + + [[module.entry]] + name = "ASRC" + uuid = "66B4402D-B468-42F2-81A7-B37121863DD4" + affinity_mask = "0x3" + instance_count = "2" + domain_types = "0" + + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + pin = [0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x45ff] + + mod_cfg = [1, 0, 0, 0, 20480, 21808000, 64, 192, 0, 21808, 0, + 2, 0, 0, 0, 20480, 45820000, 64, 384, 0, 45820, 0, + 3, 0, 0, 0, 20480, 75236000, 512, 1440, 0, 75236, 0, + 4, 0, 0, 0, 20480, 79732000, 512, 1536, 0, 79732, 0, + 5, 0, 0, 0, 20480, 50411000, 184, 384, 0, 50411, 0, + 6, 0, 0, 0, 20480, 24236000, 192, 128, 0, 24236, 0, + 7, 0, 0, 0, 20480, 46753000, 192, 384, 0, 46753, 0, + 8, 0, 0, 0, 20480, 30032000, 256, 256, 0, 30032, 0, + 9, 0, 0, 0, 20480, 48676000, 256, 384, 0, 48676, 0, + 10, 0, 0, 0, 20480, 46548000, 360, 360, 0, 46548, 0, + 11, 0, 0, 0, 20480, 94372000, 1440, 1536, 0, 94372, 0, + 12, 0, 0, 0, 20480, 42912000, 1536, 512, 0, 42912, 0, + 13, 0, 0, 0, 20480, 31871000, 384, 192, 0, 31871, 0, + 14, 0, 0, 0, 20480, 34216000, 384, 256, 0, 34216, 0, + 15, 0, 0, 0, 20480, 83448000, 1536, 1440, 0, 83448, 0] + + [[module.entry]] + name = "SRC" + uuid = "E61BB28D-149A-4C1F-B709-46823EF5F5AE" + affinity_mask = "0x1" + #instance_count = "10" + domain_types = "0" + load_type = "0" + module_type = "7" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xffff, 0xc, 0x8, 0x05ff, + 1, 0, 0xf6c9, 0xc, 0x8, 0x05ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [1, 0, 0, 0, 12832, 15976000, 128, 512, 0, 15976, 0, + 2, 0, 0, 0, 12832, 15340000, 64, 256, 0, 15340, 0, + 3, 0, 0, 0, 12832, 21880000, 96, 512, 0, 21880, 0, + 4, 0, 0, 0, 12832, 19968000, 48, 256, 0, 19968, 0, + 5, 0, 0, 0, 12832, 18236000, 64, 256, 0, 18236, 0, + 6, 0, 0, 0, 12832, 15244000, 32, 256, 0, 15244, 0, + 7, 0, 0, 0, 12832, 56028000, 1536, 512, 0, 56028, 0, + 8, 0, 0, 0, 12832, 46740000, 768, 256, 0, 46740, 0, + 9, 0, 0, 0, 12832, 24656000, 768, 512, 0, 24656, 0, + 10, 0, 0, 0, 12832, 23516000, 384, 256, 0, 23516, 0, + 11, 0, 0, 0, 12832, 29368000, 384, 488, 0, 29368, 0, + 12, 0, 0, 0, 12832, 27164000, 192, 244, 0, 27164, 0, + 13, 0, 0, 0, 12832, 15892000, 384, 384, 0, 15892, 0, + 14, 0, 0, 0, 12832, 19916000, 192, 512, 0, 19916, 0, + 15, 0, 0, 0, 12832, 19176000, 96, 256, 0, 19176, 0, + 16, 0, 0, 0, 12832, 12676000, 192, 192, 0, 12676, 0, + 17, 0, 0, 0, 12832, 16280000, 384, 320, 0, 16280, 0, + 18, 0, 0, 0, 12832, 13076000, 192, 160, 0, 13076, 0, + 19, 0, 0, 0, 12832, 11440000, 384, 256, 0, 11440, 0, + 20, 0, 0, 0, 12832, 10996000, 192, 128, 0, 10996, 0, + 21, 0, 0, 0, 12832, 11428000, 384, 192, 0, 11428, 0, + 22, 0, 0, 0, 12832, 10740000, 192, 96, 0, 10740, 0, + 23, 0, 0, 0, 12832, 29936000, 360, 512, 0, 29936, 0, + 24, 0, 0, 0, 12832, 27696000, 180, 256, 0, 27696, 0, + 25, 0, 0, 0, 12832, 18368000, 256, 512, 0, 18368, 0, + 26, 0, 0, 0, 12832, 15204000, 128, 256, 0, 15204, 0] + + [[module.entry]] + name = "MICSEL" + uuid = "32FE92C1-1E17-4FC2-9758-C7F3542E980A" + affinity_mask = "0x1" + instance_count = "8" + domain_types = "0" + load_type = "0" + init_config = "1" + module_type = "0xC" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xe, 0xa, 0x45ff, 1, 0, 0xfeef, 0xe, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 960, 488500, 16, 16, 0, 0, 0, + 1, 0, 0, 0, 960, 964500, 16, 16, 0, 0, 0, + 2, 0, 0, 0, 960, 2003000, 16, 16, 0, 0, 0] + + [[module.entry]] + name = "UPDWMIX" + uuid = "42F8060C-832F-4DBF-B247-51E961997B34" + affinity_mask = "0x1" + instance_count = "15" + domain_types = "0" + load_type = "0" + module_type = "5" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xffff, 0xc, 0x8, 0x05ff, + 1, 0, 0xffff, 0xc, 0x8, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [1, 0, 0, 0, 216, 5044000, 384, 192, 0, 5044, 0, + 2, 0, 0, 0, 216, 2660000, 384, 384, 0, 2660, 0, + 3, 0, 0, 0, 216, 3164000, 576, 384, 0, 3164, 0, + 4, 0, 0, 0, 216, 3316000, 768, 384, 0, 3316, 0, + 5, 0, 0, 0, 216, 5264000, 768, 384, 0, 5264, 0, + 6, 0, 0, 0, 216, 5440000, 768, 384, 0, 5440, 0, + 7, 0, 0, 0, 216, 2888000, 768, 192, 0, 2888, 0, + 8, 0, 0, 0, 216, 2856000, 768, 192, 0, 2856, 0, + 9, 0, 0, 0, 216, 2876000, 768, 192, 0, 2876, 0, + 10, 0, 0, 0, 216, 2956000, 960, 192, 0, 2956, 0, + 11, 0, 0, 0, 216, 2888000, 1152, 192, 0, 2888, 0, + 12, 0, 0, 0, 216, 2888000, 1152, 192, 0, 2888, 0, + 13, 0, 0, 0, 216, 2816000, 1536, 192, 0, 2816, 0, + 14, 0, 0, 0, 216, 2468000, 192, 384, 0, 2468, 0, + 15, 0, 0, 0, 216, 3084000, 576, 384, 0, 3084, 0, + 16, 0, 0, 0, 216, 3442000, 960, 384, 0, 3442, 0, + 17, 0, 0, 0, 216, 3478000, 1152, 384, 0, 3478, 0, + 18, 0, 0, 0, 216, 3478000, 1152, 384, 0, 3478, 0, + 19, 0, 0, 0, 216, 3736000, 1536, 384, 0, 3736, 0, + 20, 0, 0, 0, 216, 3216000, 192, 1152, 0, 3216, 0, + 21, 0, 0, 0, 216, 3308000, 384, 1152, 0, 3308, 0, + 22, 0, 0, 0, 216, 3616000, 768, 1152, 0, 3616, 0, + 23, 0, 0, 0, 216, 3616000, 768, 1152, 0, 3616, 0, + 24, 0, 0, 0, 216, 4916000, 1536, 1152, 0, 4916, 0, + 25, 0, 0, 0, 216, 3228000, 192, 1152, 0, 3228, 0, + 26, 0, 0, 0, 216, 3452000, 384, 1152, 0, 3452, 0, + 27, 0, 0, 0, 216, 4016000, 768, 1152, 0, 4016, 0, + 28, 0, 0, 0, 216, 5080000, 1536, 1152, 0, 5080, 0, + 29, 0, 0, 0, 216, 3552000, 384, 1536, 0, 3552, 0, + 30, 0, 0, 0, 216, 3728000, 768, 1152, 0, 3728, 0] + + [[module.entry]] + name = "PROBE" + uuid = "7CAD0808-AB10-CD23-EF45-12AB34CD56EF" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 100000, 48, 48, 0, 1000, 0] + + [[module.entry]] + name = "MUX" + uuid = "64ce6e35-857a-4878-ace8-e2a2f42e3069" + affinity_mask = "0x1" + instance_count = "15" + domain_types = "0" + load_type = "0" + module_type = "6" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 280, 460700, 16, 16, 0, 0, 0] + + [[module.entry]] + name = "KDTEST" + uuid = "EBA8D51F-7827-47B5-82EE-DE6E7743AF67" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "8" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 480, 1114000, 64, 64, 0, 0, 0] + + [[module.entry]] + name = "KPB" + uuid = "A8A0CB32-4A77-4DB1-85C7-53D7EE07BCE6" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "0xB" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 14400, 1114000, 16, 16, 0, 0, 0] + + # smart amp test module config + [[module.entry]] + name = "SMATEST" + uuid = "167A961E-8AE4-11EA-89F1-000C29CE1635" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + init_config = "1" + module_type = "0xD" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 296, 5000000, 384, 384, 0, 5000, 0] + + # eq iir module config + [[module.entry]] + name = "EQIIR" + uuid = "5150C0E6-27F9-4EC8-8351-C705B642D12F" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 1000, 0, + 0, 0, 0, 0, 4096, 20663000, 768, 768, 0, 20663, 0] + + # eq fir module config + [[module.entry]] + name = "EQFIR" + uuid = "43A90CE7-f3A5-41Df-AC06-BA98651AE6A3" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # Aria module config + [[module.entry]] + name = "ARIA" + uuid = "99F7166D-372C-43EF-81F6-22007AA15F03" + affinity_mask = "0x1" + instance_count = "8" + domain_types = "0" + load_type = "0" + init_config = "1" + module_type = "30" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 260, 1063000, 16, 21, 0, 0, 0, + 1, 0, 0, 0, 260, 1873500, 192, 256, 0, 0, 0, + 2, 0, 0, 0, 260, 2680000, 32, 42, 0, 0, 0, + 3, 0, 0, 0, 260, 3591000, 64, 85, 0, 0, 0, + 4, 0, 0, 0, 260, 4477000, 96, 128, 0, 0, 0, + 5, 0, 0, 0, 260, 7195000, 192, 192, 0, 0, 0] + + # DRC module config + [[module.entry]] + name = "DRC" + uuid = "B36EE4DA-006F-47F9-A06D-FECBE2D8B6CE" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # Crossover module config + # Note: Crossover has init_config set to 1 to let kernel know that the base_cfg_ext needs to + # be appended to the IPC payload. The Extension is needed to know the output pin indices. + [[module.entry]] + name = "XOVER" + uuid = "948C9AD1-806A-4131-AD6C-B2BDA9E35A9F" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + init_config = "1" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # Multiband-DRC module config + [[module.entry]] + name = "MB_DRC" + uuid = "0D9F2256-8E4F-47B3-8448-239A334F1191" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # DCblock module config + [[module.entry]] + name = "DCBLOCK" + uuid = "B809EFAF-5681-42B1-9ED6-04BB012DD384" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + [[module.entry]] + name = "RTC_AEC" + uuid = "B780A0A6-269F-466F-B477-23DFA05AF758" + # bit #i = 1 means core #i is allowed. + affinity_mask = "0x7" + instance_count = "1" + domain_types = "1" + load_type = "1" + module_type = "10" + init_config = "1" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0x8, 0x2, 0x2, 0x1, + 0, 0, 0x8, 0x2, 0x2, 0x4, + 1, 0, 0x8, 0x2, 0x2, 0x1] + + # TDFB module config + [[module.entry]] + name = "TDFB" + uuid = "DD511749-D9FA-455C-B3A7-13585693F1AF" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # dts codec module config + [[module.entry]] + name = "DTS" + uuid = "D95FC34F-370F-4AC7-BC86-BFDC5BE241E6" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 296, 5000000, 384, 384, 0, 5000, 0] + + # SRC lite module config + [[module.entry]] + name = "SRC_LITE" + uuid = "33441051-44CD-466A-83A3-178478708AEA" + affinity_mask = "0x1" + #instance_count = "10" + domain_types = "0" + load_type = "0" + module_type = "0x1F" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xffff, 0xc, 0x8, 0x05ff, + 1, 0, 0xf6c9, 0xc, 0x8, 0x05ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 12832, 1365500, 0, 0, 0, 1365, 0, + 1, 0, 0, 0, 12832, 2302300, 0, 0, 0, 2302, 0, + 2, 0, 0, 0, 12832, 3218200, 0, 0, 0, 3218, 0, + 3, 0, 0, 0, 12832, 4169700, 0, 0, 0, 4169, 0, + 4, 0, 0, 0, 12832, 5095100, 0, 0, 0, 5095, 0, + 5, 0, 0, 0, 12832, 6014800, 0, 0, 0, 6014, 0, + 6, 0, 0, 0, 12832, 6963500, 0, 0, 0, 6963, 0, + 7, 0, 0, 0, 12832, 7791000, 0, 0, 0, 7791, 0, + 8, 0, 0, 0, 12832, 8843000, 0, 0, 0, 8843, 0, + 9, 0, 0, 0, 12832, 9755100, 0, 0, 0, 9755, 0, + 10, 0, 0, 0, 12832, 10726500, 0, 0, 0, 10726, 0, + 11, 0, 0, 0, 12832, 11624100, 0, 0, 0, 11624, 0, + 12, 0, 0, 0, 12832, 12518700, 0, 0, 0, 12518, 0, + 13, 0, 0, 0, 12832, 13555000, 0, 0, 0, 13555, 0, + 14, 0, 0, 0, 12832, 14144500, 0, 0, 0, 14144, 0, + 15, 0, 0, 0, 12832, 15809800, 0, 0, 0, 15809, 0, + 16, 0, 0, 0, 12832, 16749000, 0, 0, 0, 16749, 0, + 17, 0, 0, 0, 12832, 18433500, 0, 0, 0, 18433, 0, + 18, 0, 0, 0, 12832, 19425900, 0, 0, 0, 19425, 0, + 19, 0, 0, 0, 12832, 20396900, 0, 0, 0, 20396, 0, + 20, 0, 0, 0, 12832, 20881000, 0, 0, 0, 20881, 0, + 21, 0, 0, 0, 12832, 23431000, 0, 0, 0, 23431, 0, + 22, 0, 0, 0, 12832, 30471000, 0, 0, 0, 30471, 0] diff --git a/tools/rimage/config/rmb.toml b/tools/rimage/config/rmb.toml new file mode 100644 index 000000000000..7d43f3a3dc33 --- /dev/null +++ b/tools/rimage/config/rmb.toml @@ -0,0 +1,15 @@ +version = [1, 0] # use simple file write + +[adsp] +name = "rmb" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0x7F000000" +size = "0x40000" +host_offset = "0x0" +[[adsp.mem_zone]] +type = "DRAM" +base = "0xE0000000" +size = "0xE0000" +host_offset = "0x0" diff --git a/tools/rimage/config/rn.toml b/tools/rimage/config/rn.toml new file mode 100644 index 000000000000..d4e0b34b685c --- /dev/null +++ b/tools/rimage/config/rn.toml @@ -0,0 +1,15 @@ +version = [1, 0] # use simple file write + +[adsp] +name = "rn" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0x20000000" +size = "0x40000" +host_offset = "0x0" +[[adsp.mem_zone]] +type = "DRAM" +base = "0x21000000" +size = "0xE0000" +host_offset = "0x0" diff --git a/tools/rimage/config/skl.toml b/tools/rimage/config/skl.toml new file mode 100644 index 000000000000..0fff3a382bbf --- /dev/null +++ b/tools/rimage/config/skl.toml @@ -0,0 +1,30 @@ +version = [1, 5] + +[adsp] +name = "skl" +image_size = "0x200000" # (30 + 2) bank * 64KB +alias_mask = "0xE0000000" + +[[adsp.mem_zone]] +type = "ROM" +base = "0xBEFE0000" +size = "0x00002000" +[[adsp.mem_zone]] +type = "SRAM" +base = "0xA000A000" +size = "0x100000" + +[[adsp.mem_alias]] +type = "uncached" +base = "0x9E000000" +[[adsp.mem_alias]] +type = "cached" +base = "0xBE000000" + +[css] + +[fw_desc.header] +name = "ADSPFW" +load_offset = "0" +hw_buf_base_addr = "0xBE500000" +hw_buf_length = "0x4A000" diff --git a/tools/rimage/config/sue.toml b/tools/rimage/config/sue.toml new file mode 100644 index 000000000000..7579c7fcfb06 --- /dev/null +++ b/tools/rimage/config/sue.toml @@ -0,0 +1,31 @@ +version = [1, 5] + +[adsp] +name = "sue" +image_size = "0x300000" # (47 + 1) bank * 64KB +exec_boot_ldr = 1 +alias_mask = "0xE0000000" + +[[adsp.mem_zone]] +type = "ROM" +base = "0xBEFE0000" +size = "0x00002000" +[[adsp.mem_zone]] +type = "IMR" +base = "0xb0038000" +size = "0x100000" +[[adsp.mem_zone]] +type = "SRAM" +base = "0xbe000000" +size = "0x100000" + +[[adsp.mem_alias]] +type = "uncached" +base = "0x9E000000" +[[adsp.mem_alias]] +type = "cached" +base = "0xBE000000" + +[fw_desc.header] +name = "ADSPFW" +load_offset = "0x2000" diff --git a/tools/rimage/config/tgl-cavs.toml b/tools/rimage/config/tgl-cavs.toml new file mode 100644 index 000000000000..3811e2e170c7 --- /dev/null +++ b/tools/rimage/config/tgl-cavs.toml @@ -0,0 +1,515 @@ +version = [2, 5] + +[adsp] +name = "tgl" +image_size = "0x2F0000" +alias_mask = "0xE0000000" + +[[adsp.mem_zone]] +type = "ROM" +base = "0x9F180000" +size = "0x00002000" +[[adsp.mem_zone]] +type = "IMR" +base = "0xB0000000" +size = "0x1000000" +[[adsp.mem_zone]] +type = "HP-SRAM" +base = "0xBE000000" +size = "0x800000" +[[adsp.mem_zone]] +type = "LP-SRAM" +base = "0xBE800000" +size = "0x40" + +[[adsp.mem_alias]] +type = "uncached" +base = "0x9E000000" +[[adsp.mem_alias]] +type = "cached" +base = "0xBE000000" + +[cse] +partition_name = "ADSP" +[[cse.entry]] +name = "ADSP.man" +offset = "0x5c" +length = "0x464" +[[cse.entry]] +name = "cavs0015.met" +offset = "0x4c0" +length = "0x70" +[[cse.entry]] +name = "cavs0015" +offset = "0x540" +length = "0x0" # calculated by rimage + +[css] + +[signed_pkg] +name = "ADSP" +[[signed_pkg.module]] +name = "cavs0015.met" + +[adsp_file] +[[adsp_file.comp]] +base_offset = "0x2000" + +[fw_desc.header] +name = "ADSPFW" +load_offset = "0x30000" + +[module] +count = 22 + [[module.entry]] + name = "BRNGUP" + uuid = "61EB0CB9-34D8-4F59-A21D-04C54C21D3A4" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "0" + auto_start = "0" + + [[module.entry]] + name = "BASEFW" + uuid = "383B9BE2-3518-4DB0-8891-B1470A8914F8" + affinity_mask = "3" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "0" + auto_start = "0" + + [[module.entry]] + name = "MIXIN" + uuid = "39656EB2-3B71-4049-8D3F-F92CD5C43C09" + affinity_mask = "0x1" + instance_count = "30" + domain_types = "0" + load_type = "0" + module_type = "1" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [ 0, 0, 0, 0, 296, 644000, 45, 60, 0, 0, 0, + 1, 0, 0, 0, 296, 669900, 48, 64, 0, 0, 0, + 2, 0, 0, 0, 296, 934000, 96, 128, 0, 0, 0, + 3, 0, 0, 0, 296, 1137000, 96, 128, 0, 0, 0, + 4, 0, 0, 0, 296, 1482000, 48, 64, 0, 0, 0, + 5, 0, 0, 0, 296, 1746000, 96, 128, 0, 0, 0, + 6, 0, 0, 0, 296, 2274000, 192, 256, 0, 0, 0, + 7, 0, 0, 0, 296, 2700000, 48, 64, 0, 0, 0, + 8, 0, 0, 0, 296, 2964000, 96, 128, 0, 0, 0, + 9, 0, 0, 0, 296, 3492000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "MIXOUT" + uuid = "3C56505A-24D7-418F-BDDC-C1F5A3AC2AE0" + affinity_mask = "0x1" + instance_count = "30" + domain_types = "0" + load_type = "0" + module_type = "2" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [1, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 520, 649600, 48, 64, 0, 0, 0, + 1, 0, 0, 0, 520, 966300, 96, 128, 0, 0, 0, + 2, 0, 0, 0, 520, 2101000, 48, 64, 0, 0, 0, + 3, 0, 0, 0, 520, 2500800, 192, 256, 0, 0, 0, + 4, 0, 0, 0, 520, 2616700, 192, 256, 0, 0, 0, + 5, 0, 0, 0, 520, 2964500, 192, 256, 0, 0, 0, + 6, 0, 0, 0, 520, 4202000, 96, 128, 0, 0, 0, + 7, 0, 0, 0, 520, 3730000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "COPIER" + uuid = "9BA00C83-CA12-4A83-943C-1FA2E82F9DDA" + affinity_mask = "0x1" + instance_count = "32" + domain_types = "0" + load_type = "0" + module_type = "3" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [ 0, 0, 0, 0, 280, 640100, 45, 60, 0, 0, 0, + 1, 0, 0, 0, 280, 1106300, 192, 192, 0, 0, 0, + 2, 0, 0, 0, 280, 1573000, 45, 45, 0, 0, 0, + 3, 0, 0, 0, 280, 2040600, 192, 256, 0, 0, 0, + 4, 0, 0, 0, 280, 2507500, 192, 256, 0, 0, 0, + 5, 0, 0, 0, 280, 2999000, 192, 256, 0, 0, 0, + 6, 0, 0, 0, 280, 3501000, 45, 60, 0, 0, 0, + 7, 0, 0, 0, 280, 3927000, 192, 256, 0, 0, 0, + 8, 0, 0, 0, 280, 4424000, 192, 256, 0, 0, 0, + 9, 0, 0, 0, 280, 4941000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "PEAKVOL" + uuid = "8A171323-94A3-4E1D-AFE9-FE5DBAA4C393" + affinity_mask = "0x1" + instance_count = "10" + domain_types = "0" + load_type = "0" + module_type = "4" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 480, 1114000, 48, 64, 0, 0, 0, + 1, 0, 0, 0, 480, 3321600, 192, 256, 0, 0, 0, + 2, 0, 0, 0, 480, 3786000, 192, 256, 0, 0, 0, + 3, 0, 0, 0, 480, 4333000, 48, 64, 0, 0, 0, + 4, 0, 0, 0, 480, 4910000, 192, 256, 0, 0, 0, + 5, 0, 0, 0, 480, 5441000, 192, 256, 0, 0, 0, + 6, 0, 0, 0, 480, 6265000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "GAIN" + uuid = "61BCA9A8-18D0-4A18-8E7B-2639219804B7" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 416, 914000, 48, 64, 0, 0, 0, + 1, 0, 0, 0, 416, 1321600, 192, 256, 0, 0, 0, + 2, 0, 0, 0, 416, 1786000, 192, 256, 0, 0, 0, + 3, 0, 0, 0, 416, 2333000, 48, 64, 0, 0, 0, + 4, 0, 0, 0, 416, 2910000, 192, 256, 0, 0, 0, + 5, 0, 0, 0, 416, 3441000, 192, 256, 0, 0, 0, + 6, 0, 0, 0, 416, 4265000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "PROBE" + uuid = "7CAD0808-AB10-CD23-EF45-12AB34CD56EF" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 100000, 48, 48, 0, 1000, 0] + + [[module.entry]] + name = "SRCINTC" + uuid = "e61bb28d-149a-4c1f-b709-46823ef5f5ae" + affinity_mask = "0xF" + instance_count = "10" + domain_types = "0" + load_type = "0" + module_type = "0x7" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xffff, 0xc, 0x8, 0x45ff, + 1, 0, 0xf6c9, 0xc, 0x8, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 12832, 1365500, 0, 0, 0, 1365, 0, + 1, 0, 0, 0, 12832, 2302300, 0, 0, 0, 2302, 0, + 2, 0, 0, 0, 12832, 3218200, 0, 0, 0, 3218, 0, + 3, 0, 0, 0, 12832, 4169700, 0, 0, 0, 4169, 0, + 4, 0, 0, 0, 12832, 5095100, 0, 0, 0, 5095, 0, + 5, 0, 0, 0, 12832, 6014800, 0, 0, 0, 6014, 0, + 6, 0, 0, 0, 12832, 6963500, 0, 0, 0, 6963, 0, + 7, 0, 0, 0, 12832, 7791000, 0, 0, 0, 7791, 0, + 8, 0, 0, 0, 12832, 8843000, 0, 0, 0, 8843, 0, + 9, 0, 0, 0, 12832, 9755100, 0, 0, 0, 9755, 0, + 10, 0, 0, 0, 12832, 10726500, 0, 0, 0, 10726, 0, + 11, 0, 0, 0, 12832, 11624100, 0, 0, 0, 11624, 0, + 12, 0, 0, 0, 12832, 12518700, 0, 0, 0, 12518, 0, + 13, 0, 0, 0, 12832, 13555000, 0, 0, 0, 13555, 0, + 14, 0, 0, 0, 12832, 14144500, 0, 0, 0, 14144, 0, + 15, 0, 0, 0, 12832, 15809800, 0, 0, 0, 15809, 0, + 16, 0, 0, 0, 12832, 16749000, 0, 0, 0, 16749, 0, + 17, 0, 0, 0, 12832, 18433500, 0, 0, 0, 18433, 0, + 18, 0, 0, 0, 12832, 19425900, 0, 0, 0, 19425, 0, + 19, 0, 0, 0, 12832, 20396900, 0, 0, 0, 20396, 0, + 20, 0, 0, 0, 12832, 20881000, 0, 0, 0, 20881, 0, + 21, 0, 0, 0, 12832, 23431000, 0, 0, 0, 23431, 0, + 22, 0, 0, 0, 12832, 30471000, 0, 0, 0, 30471, 0] + + # smart amp test module config + [[module.entry]] + name = "SMATEST" + uuid = "167A961E-8AE4-11EA-89F1-000C29CE1635" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "0xD" + init_config = "1" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # eq iir module config + [[module.entry]] + name = "EQIIR" + uuid = "5150C0E6-27F9-4EC8-8351-C705B642D12F" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # eq fir module config + [[module.entry]] + name = "EQFIR" + uuid = "43A90CE7-f3A5-41Df-AC06-BA98651AE6A3" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + [[module.entry]] + name = "KDTEST" + uuid = "EBA8D51F-7827-47B5-82EE-DE6E7743AF67" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "1" + module_type = "8" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 480, 1114000, 64, 64, 0, 0, 0] + + [[module.entry]] + name = "KPB" + uuid = "D8218443-5FF3-4A4C-B388-6CFE07B9562E" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "1" + module_type = "0xB" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 14400, 1114000, 16, 16, 0, 0, 0] + + [[module.entry]] + name = "MICSEL" + uuid = "32FE92C1-1E17-4FC2-9758-C7F3542E980A" + affinity_mask = "0x1" + instance_count = "8" + domain_types = "0" + load_type = "0" + module_type = "0xC" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xe, 0xa, 0x45ff, 1, 0, 0xfeef, 0xe, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 960, 488500, 16, 16, 0, 0, 0, + 1, 0, 0, 0, 960, 964500, 16, 16, 0, 0, 0, + 2, 0, 0, 0, 960, 2003000, 16, 16, 0, 0, 0] + + # Aria module config + [[module.entry]] + name = "ARIA" + uuid = "99F7166D-372C-43EF-81F6-22007AA15F03" + affinity_mask = "0x1" + instance_count = "8" + domain_types = "0" + load_type = "0" + init_config = "1" + module_type = "30" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 260, 1063000, 16, 21, 0, 0, 0, + 1, 0, 0, 0, 260, 1873500, 192, 256, 0, 0, 0, + 2, 0, 0, 0, 260, 2680000, 32, 42, 0, 0, 0, + 3, 0, 0, 0, 260, 3591000, 64, 85, 0, 0, 0, + 4, 0, 0, 0, 260, 4477000, 96, 128, 0, 0, 0, + 5, 0, 0, 0, 260, 7195000, 192, 192, 0, 0, 0] + + # DRC module config + [[module.entry]] + name = "DRC" + uuid = "B36EE4DA-006F-47F9-A06D-FECBE2D8B6CE" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # Crossover module config + # Note: Crossover has init_config set to 1 to let kernel know that the base_cfg_ext needs to + # be appended to the IPC payload. The Extension is needed to know the output pin indices. + [[module.entry]] + name = "XOVER" + uuid = "948C9AD1-806A-4131-AD6C-B2BDA9E35A9F" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + init_config = "1" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # Multiband-DRC module config + [[module.entry]] + name = "MB_DRC" + uuid = "0D9F2256-8E4F-47B3-8448-239A334F1191" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # DCblock module config + [[module.entry]] + name = "DCBLOCK" + uuid = "B809EFAF-5681-42B1-9ED6-04BB012DD384" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # TDFB module config + [[module.entry]] + name = "TDFB" + uuid = "DD511749-D9FA-455C-B3A7-13585693F1AF" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + [[module.entry]] + name = "RTC_AEC" + uuid = "B780A0A6-269F-466F-B477-23DFA05AF758" + affinity_mask = "0x3" + instance_count = "1" + domain_types = "0" + load_type = "1" + module_type = "10" + init_config = "1" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0x8, 0x2, 0x2, 0x1, + 0, 0, 0x8, 0x2, 0x2, 0x4, + 1, 0, 0x8, 0x2, 0x2, 0x1] diff --git a/tools/rimage/config/tgl-h-cavs.toml b/tools/rimage/config/tgl-h-cavs.toml new file mode 100644 index 000000000000..e84736ea1fa0 --- /dev/null +++ b/tools/rimage/config/tgl-h-cavs.toml @@ -0,0 +1,515 @@ +version = [2, 5] + +[adsp] +name = "tgl" +image_size = "0x1F0000" # (30 + 1) bank * 64KB +alias_mask = "0xE0000000" + +[[adsp.mem_zone]] +type = "ROM" +base = "0x9F180000" +size = "0x00002000" +[[adsp.mem_zone]] +type = "IMR" +base = "0xB0000000" +size = "0x1000000" +[[adsp.mem_zone]] +type = "HP-SRAM" +base = "0xBE000000" +size = "0x800000" +[[adsp.mem_zone]] +type = "LP-SRAM" +base = "0xBE800000" +size = "0x40" + +[[adsp.mem_alias]] +type = "uncached" +base = "0x9E000000" +[[adsp.mem_alias]] +type = "cached" +base = "0xBE000000" + +[cse] +partition_name = "ADSP" +[[cse.entry]] +name = "ADSP.man" +offset = "0x5c" +length = "0x464" +[[cse.entry]] +name = "cavs0015.met" +offset = "0x4c0" +length = "0x70" +[[cse.entry]] +name = "cavs0015" +offset = "0x540" +length = "0x0" # calculated by rimage + +[css] + +[signed_pkg] +name = "ADSP" +[[signed_pkg.module]] +name = "cavs0015.met" + +[adsp_file] +[[adsp_file.comp]] +base_offset = "0x2000" + +[fw_desc.header] +name = "ADSPFW" +load_offset = "0x30000" + +[module] +count = 22 + [[module.entry]] + name = "BRNGUP" + uuid = "61EB0CB9-34D8-4F59-A21D-04C54C21D3A4" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "0" + auto_start = "0" + + [[module.entry]] + name = "BASEFW" + uuid = "383B9BE2-3518-4DB0-8891-B1470A8914F8" + affinity_mask = "3" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "0" + auto_start = "0" + + [[module.entry]] + name = "MIXIN" + uuid = "39656EB2-3B71-4049-8D3F-F92CD5C43C09" + affinity_mask = "0x1" + instance_count = "30" + domain_types = "0" + load_type = "0" + module_type = "1" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [ 0, 0, 0, 0, 296, 644000, 45, 60, 0, 0, 0, + 1, 0, 0, 0, 296, 669900, 48, 64, 0, 0, 0, + 2, 0, 0, 0, 296, 934000, 96, 128, 0, 0, 0, + 3, 0, 0, 0, 296, 1137000, 96, 128, 0, 0, 0, + 4, 0, 0, 0, 296, 1482000, 48, 64, 0, 0, 0, + 5, 0, 0, 0, 296, 1746000, 96, 128, 0, 0, 0, + 6, 0, 0, 0, 296, 2274000, 192, 256, 0, 0, 0, + 7, 0, 0, 0, 296, 2700000, 48, 64, 0, 0, 0, + 8, 0, 0, 0, 296, 2964000, 96, 128, 0, 0, 0, + 9, 0, 0, 0, 296, 3492000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "MIXOUT" + uuid = "3C56505A-24D7-418F-BDDC-C1F5A3AC2AE0" + affinity_mask = "0x1" + instance_count = "30" + domain_types = "0" + load_type = "0" + module_type = "2" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [1, 0, 0xfeef, 0xc, 0x8, 0x45ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 1, 0, 0xfeef, 0xc, 0x8, 0x1ff, + 0, 0, 0xfeef, 0xc, 0x8, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 520, 649600, 48, 64, 0, 0, 0, + 1, 0, 0, 0, 520, 966300, 96, 128, 0, 0, 0, + 2, 0, 0, 0, 520, 2101000, 48, 64, 0, 0, 0, + 3, 0, 0, 0, 520, 2500800, 192, 256, 0, 0, 0, + 4, 0, 0, 0, 520, 2616700, 192, 256, 0, 0, 0, + 5, 0, 0, 0, 520, 2964500, 192, 256, 0, 0, 0, + 6, 0, 0, 0, 520, 4202000, 96, 128, 0, 0, 0, + 7, 0, 0, 0, 520, 3730000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "COPIER" + uuid = "9BA00C83-CA12-4A83-943C-1FA2E82F9DDA" + affinity_mask = "0x1" + instance_count = "32" + domain_types = "0" + load_type = "0" + module_type = "3" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [ 0, 0, 0, 0, 280, 640100, 45, 60, 0, 0, 0, + 1, 0, 0, 0, 280, 1106300, 192, 192, 0, 0, 0, + 2, 0, 0, 0, 280, 1573000, 45, 45, 0, 0, 0, + 3, 0, 0, 0, 280, 2040600, 192, 256, 0, 0, 0, + 4, 0, 0, 0, 280, 2507500, 192, 256, 0, 0, 0, + 5, 0, 0, 0, 280, 2999000, 192, 256, 0, 0, 0, + 6, 0, 0, 0, 280, 3501000, 45, 60, 0, 0, 0, + 7, 0, 0, 0, 280, 3927000, 192, 256, 0, 0, 0, + 8, 0, 0, 0, 280, 4424000, 192, 256, 0, 0, 0, + 9, 0, 0, 0, 280, 4941000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "PEAKVOL" + uuid = "8A171323-94A3-4E1D-AFE9-FE5DBAA4C393" + affinity_mask = "0x1" + instance_count = "10" + domain_types = "0" + load_type = "0" + module_type = "4" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 480, 1114000, 48, 64, 0, 0, 0, + 1, 0, 0, 0, 480, 3321600, 192, 256, 0, 0, 0, + 2, 0, 0, 0, 480, 3786000, 192, 256, 0, 0, 0, + 3, 0, 0, 0, 480, 4333000, 48, 64, 0, 0, 0, + 4, 0, 0, 0, 480, 4910000, 192, 256, 0, 0, 0, + 5, 0, 0, 0, 480, 5441000, 192, 256, 0, 0, 0, + 6, 0, 0, 0, 480, 6265000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "GAIN" + uuid = "61BCA9A8-18D0-4A18-8E7B-2639219804B7" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 416, 914000, 48, 64, 0, 0, 0, + 1, 0, 0, 0, 416, 1321600, 192, 256, 0, 0, 0, + 2, 0, 0, 0, 416, 1786000, 192, 256, 0, 0, 0, + 3, 0, 0, 0, 416, 2333000, 48, 64, 0, 0, 0, + 4, 0, 0, 0, 416, 2910000, 192, 256, 0, 0, 0, + 5, 0, 0, 0, 416, 3441000, 192, 256, 0, 0, 0, + 6, 0, 0, 0, 416, 4265000, 192, 256, 0, 0, 0] + + [[module.entry]] + name = "PROBE" + uuid = "7CAD0808-AB10-CD23-EF45-12AB34CD56EF" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 100000, 48, 48, 0, 1000, 0] + + [[module.entry]] + name = "SRCINTC" + uuid = "e61bb28d-149a-4c1f-b709-46823ef5f5ae" + affinity_mask = "0xF" + instance_count = "10" + domain_types = "0" + load_type = "0" + module_type = "0x7" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xffff, 0xc, 0x8, 0x45ff, + 1, 0, 0xf6c9, 0xc, 0x8, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 12832, 1365500, 0, 0, 0, 1365, 0, + 1, 0, 0, 0, 12832, 2302300, 0, 0, 0, 2302, 0, + 2, 0, 0, 0, 12832, 3218200, 0, 0, 0, 3218, 0, + 3, 0, 0, 0, 12832, 4169700, 0, 0, 0, 4169, 0, + 4, 0, 0, 0, 12832, 5095100, 0, 0, 0, 5095, 0, + 5, 0, 0, 0, 12832, 6014800, 0, 0, 0, 6014, 0, + 6, 0, 0, 0, 12832, 6963500, 0, 0, 0, 6963, 0, + 7, 0, 0, 0, 12832, 7791000, 0, 0, 0, 7791, 0, + 8, 0, 0, 0, 12832, 8843000, 0, 0, 0, 8843, 0, + 9, 0, 0, 0, 12832, 9755100, 0, 0, 0, 9755, 0, + 10, 0, 0, 0, 12832, 10726500, 0, 0, 0, 10726, 0, + 11, 0, 0, 0, 12832, 11624100, 0, 0, 0, 11624, 0, + 12, 0, 0, 0, 12832, 12518700, 0, 0, 0, 12518, 0, + 13, 0, 0, 0, 12832, 13555000, 0, 0, 0, 13555, 0, + 14, 0, 0, 0, 12832, 14144500, 0, 0, 0, 14144, 0, + 15, 0, 0, 0, 12832, 15809800, 0, 0, 0, 15809, 0, + 16, 0, 0, 0, 12832, 16749000, 0, 0, 0, 16749, 0, + 17, 0, 0, 0, 12832, 18433500, 0, 0, 0, 18433, 0, + 18, 0, 0, 0, 12832, 19425900, 0, 0, 0, 19425, 0, + 19, 0, 0, 0, 12832, 20396900, 0, 0, 0, 20396, 0, + 20, 0, 0, 0, 12832, 20881000, 0, 0, 0, 20881, 0, + 21, 0, 0, 0, 12832, 23431000, 0, 0, 0, 23431, 0, + 22, 0, 0, 0, 12832, 30471000, 0, 0, 0, 30471, 0] + + # smart amp test module config + [[module.entry]] + name = "SMATEST" + uuid = "167A961E-8AE4-11EA-89F1-000C29CE1635" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + module_type = "0xD" + init_config = "1" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # eq iir module config + [[module.entry]] + name = "EQIIR" + uuid = "5150C0E6-27F9-4EC8-8351-C705B642D12F" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # eq fir module config + [[module.entry]] + name = "EQFIR" + uuid = "43A90CE7-f3A5-41Df-AC06-BA98651AE6A3" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + [[module.entry]] + name = "KDTEST" + uuid = "EBA8D51F-7827-47B5-82EE-DE6E7743AF67" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "1" + module_type = "8" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 480, 1114000, 64, 64, 0, 0, 0] + + [[module.entry]] + name = "KPB" + uuid = "D8218443-5FF3-4A4C-B388-6CFE07B9562E" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "1" + module_type = "0xB" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 14400, 1114000, 16, 16, 0, 0, 0] + + [[module.entry]] + name = "MICSEL" + uuid = "32FE92C1-1E17-4FC2-9758-C7F3542E980A" + affinity_mask = "0x1" + instance_count = "8" + domain_types = "0" + load_type = "0" + module_type = "0xC" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xe, 0xa, 0x45ff, 1, 0, 0xfeef, 0xe, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 960, 488500, 16, 16, 0, 0, 0, + 1, 0, 0, 0, 960, 964500, 16, 16, 0, 0, 0, + 2, 0, 0, 0, 960, 2003000, 16, 16, 0, 0, 0] + + # Aria module config + [[module.entry]] + name = "ARIA" + uuid = "99F7166D-372C-43EF-81F6-22007AA15F03" + affinity_mask = "0x1" + instance_count = "8" + domain_types = "0" + load_type = "0" + init_config = "1" + module_type = "30" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 260, 1063000, 16, 21, 0, 0, 0, + 1, 0, 0, 0, 260, 1873500, 192, 256, 0, 0, 0, + 2, 0, 0, 0, 260, 2680000, 32, 42, 0, 0, 0, + 3, 0, 0, 0, 260, 3591000, 64, 85, 0, 0, 0, + 4, 0, 0, 0, 260, 4477000, 96, 128, 0, 0, 0, + 5, 0, 0, 0, 260, 7195000, 192, 192, 0, 0, 0] + + # DRC module config + [[module.entry]] + name = "DRC" + uuid = "B36EE4DA-006F-47F9-A06D-FECBE2D8B6CE" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # Crossover module config + # Note: Crossover has init_config set to 1 to let kernel know that the base_cfg_ext needs to + # be appended to the IPC payload. The Extension is needed to know the output pin indices. + [[module.entry]] + name = "XOVER" + uuid = "948C9AD1-806A-4131-AD6C-B2BDA9E35A9F" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + init_config = "1" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # Multiband-DRC module config + [[module.entry]] + name = "MB_DRC" + uuid = "0D9F2256-8E4F-47B3-8448-239A334F1191" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # DCblock module config + [[module.entry]] + name = "DCBLOCK" + uuid = "B809EFAF-5681-42B1-9ED6-04BB012DD384" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + # TDFB module config + [[module.entry]] + name = "TDFB" + uuid = "DD511749-D9FA-455C-B3A7-13585693F1AF" + affinity_mask = "0x1" + instance_count = "40" + domain_types = "0" + load_type = "0" + module_type = "9" + auto_start = "0" + sched_caps = [1, 0x00008000] + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xf, 0x45ff, 1, 0, 0xfeef, 0xf, 0xf, 0x1ff] + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] + + [[module.entry]] + name = "RTC_AEC" + uuid = "B780A0A6-269F-466F-B477-23DFA05AF758" + affinity_mask = "0x3" + instance_count = "1" + domain_types = "0" + load_type = "1" + module_type = "10" + init_config = "1" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0x8, 0x2, 0x2, 0x1, + 0, 0, 0x8, 0x2, 0x2, 0x4, + 1, 0, 0x8, 0x2, 0x2, 0x1] diff --git a/tools/rimage/config/tgl-h.toml b/tools/rimage/config/tgl-h.toml new file mode 100644 index 000000000000..997e1a832899 --- /dev/null +++ b/tools/rimage/config/tgl-h.toml @@ -0,0 +1,56 @@ +version = [2, 5] + +[adsp] +name = "tgl" +image_size = "0x1F0000" # (30 + 1) bank * 64KB +alias_mask = "0xE0000000" + +[[adsp.mem_zone]] +type = "ROM" +base = "0x9F180000" +size = "0x00002000" +[[adsp.mem_zone]] +type = "IMR" +base = "0xB0038000" +size = "0x100000" +[[adsp.mem_zone]] +type = "SRAM" +base = "0xBE040000" +size = "0x100000" + +[[adsp.mem_alias]] +type = "uncached" +base = "0x9E000000" +[[adsp.mem_alias]] +type = "cached" +base = "0xBE000000" + +[cse] +partition_name = "ADSP" +[[cse.entry]] +name = "ADSP.man" +offset = "0x5c" +length = "0x464" +[[cse.entry]] +name = "cavs0015.met" +offset = "0x4c0" +length = "0x70" +[[cse.entry]] +name = "cavs0015" +offset = "0x540" +length = "0x0" # calculated by rimage + +[css] + +[signed_pkg] +name = "ADSP" +[[signed_pkg.module]] +name = "cavs0015.met" + +[adsp_file] +[[adsp_file.comp]] +base_offset = "0x2000" + +[fw_desc.header] +name = "ADSPFW" +load_offset = "0x30000" diff --git a/tools/rimage/config/tgl.toml b/tools/rimage/config/tgl.toml new file mode 100644 index 000000000000..9a64c694c7f8 --- /dev/null +++ b/tools/rimage/config/tgl.toml @@ -0,0 +1,56 @@ +version = [2, 5] + +[adsp] +name = "tgl" +image_size = "0x2F0000" # (46 + 1) bank * 64KB +alias_mask = "0xE0000000" + +[[adsp.mem_zone]] +type = "ROM" +base = "0x9F180000" +size = "0x00002000" +[[adsp.mem_zone]] +type = "IMR" +base = "0xB0038000" +size = "0x100000" +[[adsp.mem_zone]] +type = "SRAM" +base = "0xBE040000" +size = "0x100000" + +[[adsp.mem_alias]] +type = "uncached" +base = "0x9E000000" +[[adsp.mem_alias]] +type = "cached" +base = "0xBE000000" + +[cse] +partition_name = "ADSP" +[[cse.entry]] +name = "ADSP.man" +offset = "0x5c" +length = "0x464" +[[cse.entry]] +name = "cavs0015.met" +offset = "0x4c0" +length = "0x70" +[[cse.entry]] +name = "cavs0015" +offset = "0x540" +length = "0x0" # calculated by rimage + +[css] + +[signed_pkg] +name = "ADSP" +[[signed_pkg.module]] +name = "cavs0015.met" + +[adsp_file] +[[adsp_file.comp]] +base_offset = "0x2000" + +[fw_desc.header] +name = "ADSPFW" +load_offset = "0x30000" diff --git a/tools/rimage/config/vangogh.toml b/tools/rimage/config/vangogh.toml new file mode 100644 index 000000000000..c5acdb9c9ba3 --- /dev/null +++ b/tools/rimage/config/vangogh.toml @@ -0,0 +1,15 @@ +version = [1, 0] # use simple file write + +[adsp] +name = "vangogh" + +[[adsp.mem_zone]] +type = "IRAM" +base = "0x20000000" +size = "0x40000" +host_offset = "0x0" +[[adsp.mem_zone]] +type = "DRAM" +base = "0xE0000000" +size = "0x100000" +host_offset = "0x0" diff --git a/tools/rimage/scripts/checkpatch.pl b/tools/rimage/scripts/checkpatch.pl new file mode 100755 index 000000000000..ce33a3b0ac98 --- /dev/null +++ b/tools/rimage/scripts/checkpatch.pl @@ -0,0 +1,6845 @@ +#!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 +# +# (c) 2001, Dave Jones. (the file handling bit) +# (c) 2005, Joel Schopp (the ugly bit) +# (c) 2007,2008, Andy Whitcroft (new conditions, test suite) +# (c) 2008-2010 Andy Whitcroft +# (c) 2010-2018 Joe Perches + +use strict; +use warnings; +use POSIX; +use File::Basename; +use Cwd 'abs_path'; +use Term::ANSIColor qw(:constants); +use Encode qw(decode encode); + +my $P = $0; +my $D = dirname(abs_path($P)); + +my $V = '0.32'; + +use Getopt::Long qw(:config no_auto_abbrev); + +my $SOF = 1; # enables SOF-specific behaviour +my $quiet = 0; +my $tree = 1; +my $chk_signoff = 1; +my $chk_patch = 1; +my $tst_only; +my $emacs = 0; +my $terse = 0; +my $showfile = 0; +my $file = 0; +my $git = 0; +my %git_commits = (); +my $check = 0; +my $check_orig = 0; +my $summary = 1; +my $mailback = 0; +my $summary_file = 0; +my $show_types = 0; +my $list_types = 0; +my $fix = 0; +my $fix_inplace = 0; +my $root; +my %debug; +my %camelcase = (); +my %use_type = (); +my @use = (); +my %ignore_type = (); +my @ignore = (); +my $help = 0; +my $configuration_file = ".checkpatch.conf"; +my $max_line_length = 100; +my $ignore_perl_version = 0; +my $minimum_perl_version = 5.10.0; +my $min_conf_desc_length = 4; +my $spelling_file = "$D/spelling.txt"; +my $codespell = 0; +my $codespellfile = "/usr/share/codespell/dictionary.txt"; +my $conststructsfile = "$D/const_structs.checkpatch"; +my $typedefsfile = ""; +my $color = "auto"; +my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE +# git output parsing needs US English output, so first set backtick child process LANGUAGE +my $git_command ='export LANGUAGE=en_US.UTF-8; git'; + +sub help { + my ($exitcode) = @_; + + print << "EOM"; +Usage: $P [OPTION]... [FILE]... +Version: $V + +Options: + -q, --quiet quiet + --no-tree run without a kernel tree + --no-signoff do not check for 'Signed-off-by' line + --patch treat FILE as patchfile (default) + --emacs emacs compile window format + --terse one line per report + --showfile emit diffed file position, not input file position + -g, --git treat FILE as a single commit or git revision range + single git commit with: + + ^ + ~n + multiple git commits with: + .. + ... + - + git merges are ignored + -f, --file treat FILE as regular source file + --subjective, --strict enable more subjective tests + --list-types list the possible message types + --types TYPE(,TYPE2...) show only these comma separated message types + --ignore TYPE(,TYPE2...) ignore various comma separated message types + --show-types show the specific message type in the output + --max-line-length=n set the maximum line length, (default $max_line_length) + if exceeded, warn on patches + requires --strict for use with --file + --min-conf-desc-length=n set the min description length, if shorter, warn + --root=PATH PATH to the kernel tree root + --no-summary suppress the per-file summary + --mailback only produce a report in case of warnings/errors + --summary-file include the filename in summary + --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of + 'values', 'possible', 'type', and 'attr' (default + is all off) + --test-only=WORD report only warnings/errors containing WORD + literally + --fix EXPERIMENTAL - may create horrible results + If correctable single-line errors exist, create + ".EXPERIMENTAL-checkpatch-fixes" + with potential errors corrected to the preferred + checkpatch style + --fix-inplace EXPERIMENTAL - may create horrible results + Is the same as --fix, but overwrites the input + file. It's your fault if there's no backup or git + --ignore-perl-version override checking of perl version. expect + runtime errors. + --codespell Use the codespell dictionary for spelling/typos + (default:/usr/share/codespell/dictionary.txt) + --codespellfile Use this codespell dictionary + --typedefsfile Read additional types from this file + --color[=WHEN] Use colors 'always', 'never', or only when output + is a terminal ('auto'). Default is 'auto'. + -h, --help, --version display this help and exit + +When FILE is - read standard input. +EOM + + exit($exitcode); +} + +sub uniq { + my %seen; + return grep { !$seen{$_}++ } @_; +} + +sub list_types { + my ($exitcode) = @_; + + my $count = 0; + + local $/ = undef; + + open(my $script, '<', abs_path($P)) or + die "$P: Can't read '$P' $!\n"; + + my $text = <$script>; + close($script); + + my @types = (); + # Also catch when type or level is passed through a variable + for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { + push (@types, $_); + } + @types = sort(uniq(@types)); + print("#\tMessage type\n\n"); + foreach my $type (@types) { + print(++$count . "\t" . $type . "\n"); + } + + exit($exitcode); +} + +my $conf = which_conf($configuration_file); +if (-f $conf) { + my @conf_args; + open(my $conffile, '<', "$conf") + or warn "$P: Can't find a readable $configuration_file file $!\n"; + + while (<$conffile>) { + my $line = $_; + + $line =~ s/\s*\n?$//g; + $line =~ s/^\s*//g; + $line =~ s/\s+/ /g; + + next if ($line =~ m/^\s*#/); + next if ($line =~ m/^\s*$/); + + my @words = split(" ", $line); + foreach my $word (@words) { + last if ($word =~ m/^#/); + push (@conf_args, $word); + } + } + close($conffile); + unshift(@ARGV, @conf_args) if @conf_args; +} + +# Perl's Getopt::Long allows options to take optional arguments after a space. +# Prevent --color by itself from consuming other arguments +foreach (@ARGV) { + if ($_ eq "--color" || $_ eq "-color") { + $_ = "--color=$color"; + } +} + +GetOptions( + 'q|quiet+' => \$quiet, + 'tree!' => \$tree, + 'signoff!' => \$chk_signoff, + 'patch!' => \$chk_patch, + 'emacs!' => \$emacs, + 'terse!' => \$terse, + 'showfile!' => \$showfile, + 'f|file!' => \$file, + 'g|git!' => \$git, + 'subjective!' => \$check, + 'strict!' => \$check, + 'ignore=s' => \@ignore, + 'types=s' => \@use, + 'show-types!' => \$show_types, + 'list-types!' => \$list_types, + 'max-line-length=i' => \$max_line_length, + 'min-conf-desc-length=i' => \$min_conf_desc_length, + 'root=s' => \$root, + 'summary!' => \$summary, + 'mailback!' => \$mailback, + 'summary-file!' => \$summary_file, + 'fix!' => \$fix, + 'fix-inplace!' => \$fix_inplace, + 'ignore-perl-version!' => \$ignore_perl_version, + 'debug=s' => \%debug, + 'test-only=s' => \$tst_only, + 'codespell!' => \$codespell, + 'codespellfile=s' => \$codespellfile, + 'typedefsfile=s' => \$typedefsfile, + 'color=s' => \$color, + 'no-color' => \$color, #keep old behaviors of -nocolor + 'nocolor' => \$color, #keep old behaviors of -nocolor + 'h|help' => \$help, + 'version' => \$help +) or help(1); + +help(0) if ($help); + +list_types(0) if ($list_types); + +$fix = 1 if ($fix_inplace); +$check_orig = $check; + +my $exit = 0; + +my $perl_version_ok = 1; +if ($^V && $^V lt $minimum_perl_version) { + $perl_version_ok = 0; + printf "$P: requires at least perl version %vd\n", $minimum_perl_version; + exit(1) if (!$ignore_perl_version); +} + +#if no filenames are given, push '-' to read patch from stdin +if ($#ARGV < 0) { + push(@ARGV, '-'); +} + +if ($color =~ /^[01]$/) { + $color = !$color; +} elsif ($color =~ /^always$/i) { + $color = 1; +} elsif ($color =~ /^never$/i) { + $color = 0; +} elsif ($color =~ /^auto$/i) { + $color = (-t STDOUT); +} else { + die "Invalid color mode: $color\n"; +} + +sub hash_save_array_words { + my ($hashRef, $arrayRef) = @_; + + my @array = split(/,/, join(',', @$arrayRef)); + foreach my $word (@array) { + $word =~ s/\s*\n?$//g; + $word =~ s/^\s*//g; + $word =~ s/\s+/ /g; + $word =~ tr/[a-z]/[A-Z]/; + + next if ($word =~ m/^\s*#/); + next if ($word =~ m/^\s*$/); + + $hashRef->{$word}++; + } +} + +sub hash_show_words { + my ($hashRef, $prefix) = @_; + + if (keys %$hashRef) { + print "\nNOTE: $prefix message types:"; + foreach my $word (sort keys %$hashRef) { + print " $word"; + } + print "\n"; + } +} + +hash_save_array_words(\%ignore_type, \@ignore); +hash_save_array_words(\%use_type, \@use); + +my $dbg_values = 0; +my $dbg_possible = 0; +my $dbg_type = 0; +my $dbg_attr = 0; +for my $key (keys %debug) { + ## no critic + eval "\${dbg_$key} = '$debug{$key}';"; + die "$@" if ($@); +} + +my $rpt_cleaners = 0; + +if ($terse) { + $emacs = 1; + $quiet++; +} + +if ($tree) { + if (defined $root) { + if (!top_of_kernel_tree($root)) { + die "$P: $root: --root does not point at a valid tree\n"; + } + } else { + if (top_of_kernel_tree('.')) { + $root = '.'; + } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && + top_of_kernel_tree($1)) { + $root = $1; + } + } + + if (!defined $root) { + print "Must be run from the top-level dir. of a kernel tree\n"; + exit(2); + } +} + +my $emitted_corrupt = 0; + +our $Ident = qr{ + [A-Za-z_][A-Za-z\d_]* + (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* + }x; +our $Storage = qr{extern|static|asmlinkage}; +our $Sparse = qr{ + __user| + __kernel| + __force| + __iomem| + __must_check| + __kprobes| + __ref| + __refconst| + __refdata| + __rcu| + __private + }x; +our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; +our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; +our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; +our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; +our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; + +# Notes to $Attribute: +# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check +our $Attribute = qr{ + const| + __percpu| + __nocast| + __safe| + __bitwise| + __packed__| + __packed2__| + __naked| + __maybe_unused| + __always_unused| + __noreturn| + __used| + __cold| + __pure| + __noclone| + __deprecated| + __read_mostly| + __ro_after_init| + __kprobes| + $InitAttribute| + ____cacheline_aligned| + ____cacheline_aligned_in_smp| + ____cacheline_internodealigned_in_smp| + __weak + }x; +our $Modifier; +our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; +our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; +our $Lval = qr{$Ident(?:$Member)*}; + +our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; +our $Binary = qr{(?i)0b[01]+$Int_type?}; +our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; +our $Int = qr{[0-9]+$Int_type?}; +our $Octal = qr{0[0-7]+$Int_type?}; +our $String = qr{"[X\t]*"}; +our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; +our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; +our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; +our $Float = qr{$Float_hex|$Float_dec|$Float_int}; +our $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; +our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; +our $Compare = qr{<=|>=|==|!=|<|(?}; +our $Arithmetic = qr{\+|-|\*|\/|%}; +our $Operators = qr{ + <=|>=|==|!=| + =>|->|<<|>>|<|>|!|~| + &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic + }x; + +our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; + +our $BasicType; +our $NonptrType; +our $NonptrTypeMisordered; +our $NonptrTypeWithAttr; +our $Type; +our $TypeMisordered; +our $Declare; +our $DeclareMisordered; + +our $NON_ASCII_UTF8 = qr{ + [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 +}x; + +our $UTF8 = qr{ + [\x09\x0A\x0D\x20-\x7E] # ASCII + | $NON_ASCII_UTF8 +}x; + +our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; +our $typeOtherOSTypedefs = qr{(?x: + u_(?:char|short|int|long) | # bsd + u(?:nchar|short|int|long) # sysv +)}; +our $typeKernelTypedefs = qr{(?x: + (?:__)?(?:u|s|be|le)(?:8|16|32|64)| + atomic_t +)}; +our $typeTypedefs = qr{(?x: + $typeC99Typedefs\b| + $typeOtherOSTypedefs\b| + $typeKernelTypedefs\b +)}; + +our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; + +our $logFunctions = qr{(?x: + printk(?:_ratelimited|_once|_deferred_once|_deferred|)| + (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| + TP_printk| + WARN(?:_RATELIMIT|_ONCE|)| + panic| + MODULE_[A-Z_]+| + seq_vprintf|seq_printf|seq_puts| + trace[a-z_]+ +)}; + +our $allocFunctions = qr{(?x: + (?:(?:devm_)? + (?:kv|k|v)[czm]alloc(?:_node|_array)? | + kstrdup(?:_const)? | + kmemdup(?:_nul)?) | + (?:\w+)?alloc_skb(?:ip_align)? | + # dev_alloc_skb/netdev_alloc_skb, et al + dma_alloc_coherent +)}; + +our $signature_tags = qr{(?xi: + Signed-off-by:| + Co-developed-by:| + Acked-by:| + Tested-by:| + Reviewed-by:| + Reported-by:| + Suggested-by:| + To:| + Cc: +)}; + +our @typeListMisordered = ( + qr{char\s+(?:un)?signed}, + qr{int\s+(?:(?:un)?signed\s+)?short\s}, + qr{int\s+short(?:\s+(?:un)?signed)}, + qr{short\s+int(?:\s+(?:un)?signed)}, + qr{(?:un)?signed\s+int\s+short}, + qr{short\s+(?:un)?signed}, + qr{long\s+int\s+(?:un)?signed}, + qr{int\s+long\s+(?:un)?signed}, + qr{long\s+(?:un)?signed\s+int}, + qr{int\s+(?:un)?signed\s+long}, + qr{int\s+(?:un)?signed}, + qr{int\s+long\s+long\s+(?:un)?signed}, + qr{long\s+long\s+int\s+(?:un)?signed}, + qr{long\s+long\s+(?:un)?signed\s+int}, + qr{long\s+long\s+(?:un)?signed}, + qr{long\s+(?:un)?signed}, +); + +our @typeList = ( + qr{void}, + qr{(?:(?:un)?signed\s+)?char}, + qr{(?:(?:un)?signed\s+)?short\s+int}, + qr{(?:(?:un)?signed\s+)?short}, + qr{(?:(?:un)?signed\s+)?int}, + qr{(?:(?:un)?signed\s+)?long\s+int}, + qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, + qr{(?:(?:un)?signed\s+)?long\s+long}, + qr{(?:(?:un)?signed\s+)?long}, + qr{(?:un)?signed}, + qr{float}, + qr{double}, + qr{bool}, + qr{struct\s+$Ident}, + qr{union\s+$Ident}, + qr{enum\s+$Ident}, + qr{${Ident}_t}, + qr{${Ident}_handler}, + qr{${Ident}_handler_fn}, + @typeListMisordered, +); + +our $C90_int_types = qr{(?x: + long\s+long\s+int\s+(?:un)?signed| + long\s+long\s+(?:un)?signed\s+int| + long\s+long\s+(?:un)?signed| + (?:(?:un)?signed\s+)?long\s+long\s+int| + (?:(?:un)?signed\s+)?long\s+long| + int\s+long\s+long\s+(?:un)?signed| + int\s+(?:(?:un)?signed\s+)?long\s+long| + + long\s+int\s+(?:un)?signed| + long\s+(?:un)?signed\s+int| + long\s+(?:un)?signed| + (?:(?:un)?signed\s+)?long\s+int| + (?:(?:un)?signed\s+)?long| + int\s+long\s+(?:un)?signed| + int\s+(?:(?:un)?signed\s+)?long| + + int\s+(?:un)?signed| + (?:(?:un)?signed\s+)?int +)}; + +our @typeListFile = (); +our @typeListWithAttr = ( + @typeList, + qr{struct\s+$InitAttribute\s+$Ident}, + qr{union\s+$InitAttribute\s+$Ident}, +); + +our @modifierList = ( + qr{fastcall}, +); +our @modifierListFile = (); + +our @mode_permission_funcs = ( + ["module_param", 3], + ["module_param_(?:array|named|string)", 4], + ["module_param_array_named", 5], + ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], + ["proc_create(?:_data|)", 2], + ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], + ["IIO_DEV_ATTR_[A-Z_]+", 1], + ["SENSOR_(?:DEVICE_|)ATTR_2", 2], + ["SENSOR_TEMPLATE(?:_2|)", 3], + ["__ATTR", 2], +); + +#Create a search pattern for all these functions to speed up a loop below +our $mode_perms_search = ""; +foreach my $entry (@mode_permission_funcs) { + $mode_perms_search .= '|' if ($mode_perms_search ne ""); + $mode_perms_search .= $entry->[0]; +} +$mode_perms_search = "(?:${mode_perms_search})"; + +our %deprecated_apis = ( + "synchronize_rcu_bh" => "synchronize_rcu", + "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited", + "call_rcu_bh" => "call_rcu", + "rcu_barrier_bh" => "rcu_barrier", + "synchronize_sched" => "synchronize_rcu", + "synchronize_sched_expedited" => "synchronize_rcu_expedited", + "call_rcu_sched" => "call_rcu", + "rcu_barrier_sched" => "rcu_barrier", + "get_state_synchronize_sched" => "get_state_synchronize_rcu", + "cond_synchronize_sched" => "cond_synchronize_rcu", +); + +#Create a search pattern for all these strings to speed up a loop below +our $deprecated_apis_search = ""; +foreach my $entry (keys %deprecated_apis) { + $deprecated_apis_search .= '|' if ($deprecated_apis_search ne ""); + $deprecated_apis_search .= $entry; +} +$deprecated_apis_search = "(?:${deprecated_apis_search})"; + +our $mode_perms_world_writable = qr{ + S_IWUGO | + S_IWOTH | + S_IRWXUGO | + S_IALLUGO | + 0[0-7][0-7][2367] +}x; + +our %mode_permission_string_types = ( + "S_IRWXU" => 0700, + "S_IRUSR" => 0400, + "S_IWUSR" => 0200, + "S_IXUSR" => 0100, + "S_IRWXG" => 0070, + "S_IRGRP" => 0040, + "S_IWGRP" => 0020, + "S_IXGRP" => 0010, + "S_IRWXO" => 0007, + "S_IROTH" => 0004, + "S_IWOTH" => 0002, + "S_IXOTH" => 0001, + "S_IRWXUGO" => 0777, + "S_IRUGO" => 0444, + "S_IWUGO" => 0222, + "S_IXUGO" => 0111, +); + +#Create a search pattern for all these strings to speed up a loop below +our $mode_perms_string_search = ""; +foreach my $entry (keys %mode_permission_string_types) { + $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); + $mode_perms_string_search .= $entry; +} +our $single_mode_perms_string_search = "(?:${mode_perms_string_search})"; +our $multi_mode_perms_string_search = qr{ + ${single_mode_perms_string_search} + (?:\s*\|\s*${single_mode_perms_string_search})* +}x; + +sub perms_to_octal { + my ($string) = @_; + + return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/); + + my $val = ""; + my $oval = ""; + my $to = 0; + my $curpos = 0; + my $lastpos = 0; + while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { + $curpos = pos($string); + my $match = $2; + my $omatch = $1; + last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); + $lastpos = $curpos; + $to |= $mode_permission_string_types{$match}; + $val .= '\s*\|\s*' if ($val ne ""); + $val .= $match; + $oval .= $omatch; + } + $oval =~ s/^\s*\|\s*//; + $oval =~ s/\s*\|\s*$//; + return sprintf("%04o", $to); +} + +our $allowed_asm_includes = qr{(?x: + irq| + memory| + time| + reboot +)}; +# memory.h: ARM has a custom one + +# Load common spelling mistakes and build regular expression list. +my $misspellings; +my %spelling_fix; + +if (open(my $spelling, '<', $spelling_file)) { + while (<$spelling>) { + my $line = $_; + + $line =~ s/\s*\n?$//g; + $line =~ s/^\s*//g; + + next if ($line =~ m/^\s*#/); + next if ($line =~ m/^\s*$/); + + my ($suspect, $fix) = split(/\|\|/, $line); + + $spelling_fix{$suspect} = $fix; + } + close($spelling); +} else { + warn "No typos will be found - file '$spelling_file': $!\n"; +} + +if ($codespell) { + if (open(my $spelling, '<', $codespellfile)) { + while (<$spelling>) { + my $line = $_; + + $line =~ s/\s*\n?$//g; + $line =~ s/^\s*//g; + + next if ($line =~ m/^\s*#/); + next if ($line =~ m/^\s*$/); + next if ($line =~ m/, disabled/i); + + $line =~ s/,.*$//; + + my ($suspect, $fix) = split(/->/, $line); + + $spelling_fix{$suspect} = $fix; + } + close($spelling); + } else { + warn "No codespell typos will be found - file '$codespellfile': $!\n"; + } +} + +$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; + +sub read_words { + my ($wordsRef, $file) = @_; + + if (open(my $words, '<', $file)) { + while (<$words>) { + my $line = $_; + + $line =~ s/\s*\n?$//g; + $line =~ s/^\s*//g; + + next if ($line =~ m/^\s*#/); + next if ($line =~ m/^\s*$/); + if ($line =~ /\s/) { + print("$file: '$line' invalid - ignored\n"); + next; + } + + $$wordsRef .= '|' if ($$wordsRef ne ""); + $$wordsRef .= $line; + } + close($file); + return 1; + } + + return 0; +} + +my $const_structs = ""; +read_words(\$const_structs, $conststructsfile) + or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; + +my $typeOtherTypedefs = ""; +if (length($typedefsfile)) { + read_words(\$typeOtherTypedefs, $typedefsfile) + or warn "No additional types will be considered - file '$typedefsfile': $!\n"; +} +$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne ""); + +sub build_types { + my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; + my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; + my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; + my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; + $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; + $BasicType = qr{ + (?:$typeTypedefs\b)| + (?:${all}\b) + }x; + $NonptrType = qr{ + (?:$Modifier\s+|const\s+)* + (?: + (?:typeof|__typeof__)\s*\([^\)]*\)| + (?:$typeTypedefs\b)| + (?:${all}\b) + ) + (?:\s+$Modifier|\s+const)* + }x; + $NonptrTypeMisordered = qr{ + (?:$Modifier\s+|const\s+)* + (?: + (?:${Misordered}\b) + ) + (?:\s+$Modifier|\s+const)* + }x; + $NonptrTypeWithAttr = qr{ + (?:$Modifier\s+|const\s+)* + (?: + (?:typeof|__typeof__)\s*\([^\)]*\)| + (?:$typeTypedefs\b)| + (?:${allWithAttr}\b) + ) + (?:\s+$Modifier|\s+const)* + }x; + $Type = qr{ + $NonptrType + (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? + (?:\s+$Inline|\s+$Modifier)* + }x; + $TypeMisordered = qr{ + $NonptrTypeMisordered + (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? + (?:\s+$Inline|\s+$Modifier)* + }x; + $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; + $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; +} +build_types(); + +our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; + +# Using $balanced_parens, $LvalOrFunc, or $FuncArg +# requires at least perl version v5.10.0 +# Any use must be runtime checked with $^V + +our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; +our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; +our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; + +our $declaration_macros = qr{(?x: + (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| + (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| + (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(| + (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\( +)}; + +sub deparenthesize { + my ($string) = @_; + return "" if (!defined($string)); + + while ($string =~ /^\s*\(.*\)\s*$/) { + $string =~ s@^\s*\(\s*@@; + $string =~ s@\s*\)\s*$@@; + } + + $string =~ s@\s+@ @g; + + return $string; +} + +sub seed_camelcase_file { + my ($file) = @_; + + return if (!(-f $file)); + + local $/; + + open(my $include_file, '<', "$file") + or warn "$P: Can't read '$file' $!\n"; + my $text = <$include_file>; + close($include_file); + + my @lines = split('\n', $text); + + foreach my $line (@lines) { + next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); + if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { + $camelcase{$1} = 1; + } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { + $camelcase{$1} = 1; + } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { + $camelcase{$1} = 1; + } + } +} + +sub is_maintained_obsolete { + my ($filename) = @_; + + return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); + + my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; + + return $status =~ /obsolete/i; +} + +sub is_SPDX_License_valid { + my ($license) = @_; + + return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$root/.git")); + + my $root_path = abs_path($root); + my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`; + return 0 if ($status ne ""); + return 1; +} + +my $camelcase_seeded = 0; +sub seed_camelcase_includes { + return if ($camelcase_seeded); + + my $files; + my $camelcase_cache = ""; + my @include_files = (); + + $camelcase_seeded = 1; + + if (-e ".git") { + my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`; + chomp $git_last_include_commit; + $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; + } else { + my $last_mod_date = 0; + $files = `find $root/include -name "*.h"`; + @include_files = split('\n', $files); + foreach my $file (@include_files) { + my $date = POSIX::strftime("%Y%m%d%H%M", + localtime((stat $file)[9])); + $last_mod_date = $date if ($last_mod_date < $date); + } + $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; + } + + if ($camelcase_cache ne "" && -f $camelcase_cache) { + open(my $camelcase_file, '<', "$camelcase_cache") + or warn "$P: Can't read '$camelcase_cache' $!\n"; + while (<$camelcase_file>) { + chomp; + $camelcase{$_} = 1; + } + close($camelcase_file); + + return; + } + + if (-e ".git") { + $files = `${git_command} ls-files "include/*.h"`; + @include_files = split('\n', $files); + } + + foreach my $file (@include_files) { + seed_camelcase_file($file); + } + + if ($camelcase_cache ne "") { + unlink glob ".checkpatch-camelcase.*"; + open(my $camelcase_file, '>', "$camelcase_cache") + or warn "$P: Can't write '$camelcase_cache' $!\n"; + foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { + print $camelcase_file ("$_\n"); + } + close($camelcase_file); + } +} + +sub git_commit_info { + my ($commit, $id, $desc) = @_; + + return ($id, $desc) if ((which("git") eq "") || !(-e ".git")); + + my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`; + $output =~ s/^\s*//gm; + my @lines = split("\n", $output); + + return ($id, $desc) if ($#lines < 0); + + if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) { +# Maybe one day convert this block of bash into something that returns +# all matching commit ids, but it's very slow... +# +# echo "checking commits $1..." +# git rev-list --remotes | grep -i "^$1" | +# while read line ; do +# git log --format='%H %s' -1 $line | +# echo "commit $(cut -c 1-12,41-)" +# done + } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) { + $id = undef; + } else { + $id = substr($lines[0], 0, 12); + $desc = substr($lines[0], 41); + } + + return ($id, $desc); +} + +$chk_signoff = 0 if ($file); + +my @rawlines = (); +my @lines = (); +my @fixed = (); +my @fixed_inserted = (); +my @fixed_deleted = (); +my $fixlinenr = -1; + +# If input is git commits, extract all commits from the commit expressions. +# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. +die "$P: No git repository found\n" if ($git && !-e ".git"); + +if ($git) { + my @commits = (); + foreach my $commit_expr (@ARGV) { + my $git_range; + if ($commit_expr =~ m/^(.*)-(\d+)$/) { + $git_range = "-$2 $1"; + } elsif ($commit_expr =~ m/\.\./) { + $git_range = "$commit_expr"; + } else { + $git_range = "-1 $commit_expr"; + } + my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`; + foreach my $line (split(/\n/, $lines)) { + $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; + next if (!defined($1) || !defined($2)); + my $sha1 = $1; + my $subject = $2; + unshift(@commits, $sha1); + $git_commits{$sha1} = $subject; + } + } + die "$P: no git commits after extraction!\n" if (@commits == 0); + @ARGV = @commits; +} + +my $vname; +$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"}; +for my $filename (@ARGV) { + my $FILE; + if ($git) { + open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || + die "$P: $filename: git format-patch failed - $!\n"; + } elsif ($file) { + open($FILE, '-|', "diff -u /dev/null $filename") || + die "$P: $filename: diff failed - $!\n"; + } elsif ($filename eq '-') { + open($FILE, '<&STDIN'); + } else { + open($FILE, '<', "$filename") || + die "$P: $filename: open failed - $!\n"; + } + if ($filename eq '-') { + $vname = 'Your patch'; + } elsif ($git) { + $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; + } else { + $vname = $filename; + } + while (<$FILE>) { + chomp; + push(@rawlines, $_); + } + close($FILE); + + if ($#ARGV > 0 && $quiet == 0) { + print '-' x length($vname) . "\n"; + print "$vname\n"; + print '-' x length($vname) . "\n"; + } + + if (!process($filename)) { + $exit = 1; + } + @rawlines = (); + @lines = (); + @fixed = (); + @fixed_inserted = (); + @fixed_deleted = (); + $fixlinenr = -1; + @modifierListFile = (); + @typeListFile = (); + build_types(); +} + +if (!$quiet) { + hash_show_words(\%use_type, "Used"); + hash_show_words(\%ignore_type, "Ignored"); + + if (!$perl_version_ok) { + print << "EOM" + +NOTE: perl $^V is not modern enough to detect all possible issues. + An upgrade to at least perl $minimum_perl_version is suggested. +EOM + } + if ($exit) { + print << "EOM" + +NOTE: If any of the errors are false positives, please report + them to the maintainer, see CHECKPATCH in MAINTAINERS. +EOM + } +} + +exit($exit); + +sub top_of_kernel_tree { + my ($root) = @_; + + my @tree_check = ( + "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", + "README", "Documentation", "arch", "include", "drivers", + "fs", "init", "ipc", "kernel", "lib", "scripts", + ); + + if ($SOF) { + @tree_check = ( + "LICENCE", "README.md", "rimage", "tools", + "scripts", "doc", "src", "CODEOWNERS", + "CMakeLists.txt", + ); + } + + foreach my $check (@tree_check) { + if (! -e $root . '/' . $check) { + return 0; + } + } + return 1; +} + +sub parse_email { + my ($formatted_email) = @_; + + my $name = ""; + my $address = ""; + my $comment = ""; + + if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { + $name = $1; + $address = $2; + $comment = $3 if defined $3; + } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { + $address = $1; + $comment = $2 if defined $2; + } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { + $address = $1; + $comment = $2 if defined $2; + $formatted_email =~ s/\Q$address\E.*$//; + $name = $formatted_email; + $name = trim($name); + $name =~ s/^\"|\"$//g; + # If there's a name left after stripping spaces and + # leading quotes, and the address doesn't have both + # leading and trailing angle brackets, the address + # is invalid. ie: + # "joe smith joe@smith.com" bad + # "joe smith ]+>$/) { + $name = ""; + $address = ""; + $comment = ""; + } + } + + $name = trim($name); + $name =~ s/^\"|\"$//g; + $address = trim($address); + $address =~ s/^\<|\>$//g; + + if ($name =~ /[^\w \-]/i) { ##has "must quote" chars + $name =~ s/(?"; + } + + return $formatted_email; +} + +sub which { + my ($bin) = @_; + + foreach my $path (split(/:/, $ENV{PATH})) { + if (-e "$path/$bin") { + return "$path/$bin"; + } + } + + return ""; +} + +sub which_conf { + my ($conf) = @_; + + foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { + if (-e "$path/$conf") { + return "$path/$conf"; + } + } + + return ""; +} + +sub expand_tabs { + my ($str) = @_; + + my $res = ''; + my $n = 0; + for my $c (split(//, $str)) { + if ($c eq "\t") { + $res .= ' '; + $n++; + for (; ($n % 8) != 0; $n++) { + $res .= ' '; + } + next; + } + $res .= $c; + $n++; + } + + return $res; +} +sub copy_spacing { + (my $res = shift) =~ tr/\t/ /c; + return $res; +} + +sub line_stats { + my ($line) = @_; + + # Drop the diff line leader and expand tabs + $line =~ s/^.//; + $line = expand_tabs($line); + + # Pick the indent from the front of the line. + my ($white) = ($line =~ /^(\s*)/); + + return (length($line), length($white)); +} + +my $sanitise_quote = ''; + +sub sanitise_line_reset { + my ($in_comment) = @_; + + if ($in_comment) { + $sanitise_quote = '*/'; + } else { + $sanitise_quote = ''; + } +} +sub sanitise_line { + my ($line) = @_; + + my $res = ''; + my $l = ''; + + my $qlen = 0; + my $off = 0; + my $c; + + # Always copy over the diff marker. + $res = substr($line, 0, 1); + + for ($off = 1; $off < length($line); $off++) { + $c = substr($line, $off, 1); + + # Comments we are whacking completely including the begin + # and end, all to $;. + if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { + $sanitise_quote = '*/'; + + substr($res, $off, 2, "$;$;"); + $off++; + next; + } + if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { + $sanitise_quote = ''; + substr($res, $off, 2, "$;$;"); + $off++; + next; + } + if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { + $sanitise_quote = '//'; + + substr($res, $off, 2, $sanitise_quote); + $off++; + next; + } + + # A \ in a string means ignore the next character. + if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && + $c eq "\\") { + substr($res, $off, 2, 'XX'); + $off++; + next; + } + # Regular quotes. + if ($c eq "'" || $c eq '"') { + if ($sanitise_quote eq '') { + $sanitise_quote = $c; + + substr($res, $off, 1, $c); + next; + } elsif ($sanitise_quote eq $c) { + $sanitise_quote = ''; + } + } + + #print "c<$c> SQ<$sanitise_quote>\n"; + if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { + substr($res, $off, 1, $;); + } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { + substr($res, $off, 1, $;); + } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { + substr($res, $off, 1, 'X'); + } else { + substr($res, $off, 1, $c); + } + } + + if ($sanitise_quote eq '//') { + $sanitise_quote = ''; + } + + # The pathname on a #include may be surrounded by '<' and '>'. + if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { + my $clean = 'X' x length($1); + $res =~ s@\<.*\>@<$clean>@; + + # The whole of a #error is a string. + } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { + my $clean = 'X' x length($1); + $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; + } + + if ($allow_c99_comments && $res =~ m@(//.*$)@) { + my $match = $1; + $res =~ s/\Q$match\E/"$;" x length($match)/e; + } + + return $res; +} + +sub get_quoted_string { + my ($line, $rawline) = @_; + + return "" if (!defined($line) || !defined($rawline)); + return "" if ($line !~ m/($String)/g); + return substr($rawline, $-[0], $+[0] - $-[0]); +} + +sub ctx_statement_block { + my ($linenr, $remain, $off) = @_; + my $line = $linenr - 1; + my $blk = ''; + my $soff = $off; + my $coff = $off - 1; + my $coff_set = 0; + + my $loff = 0; + + my $type = ''; + my $level = 0; + my @stack = (); + my $p; + my $c; + my $len = 0; + + my $remainder; + while (1) { + @stack = (['', 0]) if ($#stack == -1); + + #warn "CSB: blk<$blk> remain<$remain>\n"; + # If we are about to drop off the end, pull in more + # context. + if ($off >= $len) { + for (; $remain > 0; $line++) { + last if (!defined $lines[$line]); + next if ($lines[$line] =~ /^-/); + $remain--; + $loff = $len; + $blk .= $lines[$line] . "\n"; + $len = length($blk); + $line++; + last; + } + # Bail if there is no further context. + #warn "CSB: blk<$blk> off<$off> len<$len>\n"; + if ($off >= $len) { + last; + } + if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { + $level++; + $type = '#'; + } + } + $p = $c; + $c = substr($blk, $off, 1); + $remainder = substr($blk, $off); + + #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; + + # Handle nested #if/#else. + if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { + push(@stack, [ $type, $level ]); + } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { + ($type, $level) = @{$stack[$#stack - 1]}; + } elsif ($remainder =~ /^#\s*endif\b/) { + ($type, $level) = @{pop(@stack)}; + } + + # Statement ends at the ';' or a close '}' at the + # outermost level. + if ($level == 0 && $c eq ';') { + last; + } + + # An else is really a conditional as long as its not else if + if ($level == 0 && $coff_set == 0 && + (!defined($p) || $p =~ /(?:\s|\}|\+)/) && + $remainder =~ /^(else)(?:\s|{)/ && + $remainder !~ /^else\s+if\b/) { + $coff = $off + length($1) - 1; + $coff_set = 1; + #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; + #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; + } + + if (($type eq '' || $type eq '(') && $c eq '(') { + $level++; + $type = '('; + } + if ($type eq '(' && $c eq ')') { + $level--; + $type = ($level != 0)? '(' : ''; + + if ($level == 0 && $coff < $soff) { + $coff = $off; + $coff_set = 1; + #warn "CSB: mark coff<$coff>\n"; + } + } + if (($type eq '' || $type eq '{') && $c eq '{') { + $level++; + $type = '{'; + } + if ($type eq '{' && $c eq '}') { + $level--; + $type = ($level != 0)? '{' : ''; + + if ($level == 0) { + if (substr($blk, $off + 1, 1) eq ';') { + $off++; + } + last; + } + } + # Preprocessor commands end at the newline unless escaped. + if ($type eq '#' && $c eq "\n" && $p ne "\\") { + $level--; + $type = ''; + $off++; + last; + } + $off++; + } + # We are truly at the end, so shuffle to the next line. + if ($off == $len) { + $loff = $len + 1; + $line++; + $remain--; + } + + my $statement = substr($blk, $soff, $off - $soff + 1); + my $condition = substr($blk, $soff, $coff - $soff + 1); + + #warn "STATEMENT<$statement>\n"; + #warn "CONDITION<$condition>\n"; + + #print "coff<$coff> soff<$off> loff<$loff>\n"; + + return ($statement, $condition, + $line, $remain + 1, $off - $loff + 1, $level); +} + +sub statement_lines { + my ($stmt) = @_; + + # Strip the diff line prefixes and rip blank lines at start and end. + $stmt =~ s/(^|\n)./$1/g; + $stmt =~ s/^\s*//; + $stmt =~ s/\s*$//; + + my @stmt_lines = ($stmt =~ /\n/g); + + return $#stmt_lines + 2; +} + +sub statement_rawlines { + my ($stmt) = @_; + + my @stmt_lines = ($stmt =~ /\n/g); + + return $#stmt_lines + 2; +} + +sub statement_block_size { + my ($stmt) = @_; + + $stmt =~ s/(^|\n)./$1/g; + $stmt =~ s/^\s*{//; + $stmt =~ s/}\s*$//; + $stmt =~ s/^\s*//; + $stmt =~ s/\s*$//; + + my @stmt_lines = ($stmt =~ /\n/g); + my @stmt_statements = ($stmt =~ /;/g); + + my $stmt_lines = $#stmt_lines + 2; + my $stmt_statements = $#stmt_statements + 1; + + if ($stmt_lines > $stmt_statements) { + return $stmt_lines; + } else { + return $stmt_statements; + } +} + +sub ctx_statement_full { + my ($linenr, $remain, $off) = @_; + my ($statement, $condition, $level); + + my (@chunks); + + # Grab the first conditional/block pair. + ($statement, $condition, $linenr, $remain, $off, $level) = + ctx_statement_block($linenr, $remain, $off); + #print "F: c<$condition> s<$statement> remain<$remain>\n"; + push(@chunks, [ $condition, $statement ]); + if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { + return ($level, $linenr, @chunks); + } + + # Pull in the following conditional/block pairs and see if they + # could continue the statement. + for (;;) { + ($statement, $condition, $linenr, $remain, $off, $level) = + ctx_statement_block($linenr, $remain, $off); + #print "C: c<$condition> s<$statement> remain<$remain>\n"; + last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); + #print "C: push\n"; + push(@chunks, [ $condition, $statement ]); + } + + return ($level, $linenr, @chunks); +} + +sub ctx_block_get { + my ($linenr, $remain, $outer, $open, $close, $off) = @_; + my $line; + my $start = $linenr - 1; + my $blk = ''; + my @o; + my @c; + my @res = (); + + my $level = 0; + my @stack = ($level); + for ($line = $start; $remain > 0; $line++) { + next if ($rawlines[$line] =~ /^-/); + $remain--; + + $blk .= $rawlines[$line]; + + # Handle nested #if/#else. + if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { + push(@stack, $level); + } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { + $level = $stack[$#stack - 1]; + } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { + $level = pop(@stack); + } + + foreach my $c (split(//, $lines[$line])) { + ##print "C<$c>L<$level><$open$close>O<$off>\n"; + if ($off > 0) { + $off--; + next; + } + + if ($c eq $close && $level > 0) { + $level--; + last if ($level == 0); + } elsif ($c eq $open) { + $level++; + } + } + + if (!$outer || $level <= 1) { + push(@res, $rawlines[$line]); + } + + last if ($level == 0); + } + + return ($level, @res); +} +sub ctx_block_outer { + my ($linenr, $remain) = @_; + + my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); + return @r; +} +sub ctx_block { + my ($linenr, $remain) = @_; + + my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); + return @r; +} +sub ctx_statement { + my ($linenr, $remain, $off) = @_; + + my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); + return @r; +} +sub ctx_block_level { + my ($linenr, $remain) = @_; + + return ctx_block_get($linenr, $remain, 0, '{', '}', 0); +} +sub ctx_statement_level { + my ($linenr, $remain, $off) = @_; + + return ctx_block_get($linenr, $remain, 0, '(', ')', $off); +} + +sub ctx_locate_comment { + my ($first_line, $end_line) = @_; + + # Catch a comment on the end of the line itself. + my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); + return $current_comment if (defined $current_comment); + + # Look through the context and try and figure out if there is a + # comment. + my $in_comment = 0; + $current_comment = ''; + for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { + my $line = $rawlines[$linenr - 1]; + #warn " $line\n"; + if ($linenr == $first_line and $line =~ m@^.\s*\*@) { + $in_comment = 1; + } + if ($line =~ m@/\*@) { + $in_comment = 1; + } + if (!$in_comment && $current_comment ne '') { + $current_comment = ''; + } + $current_comment .= $line . "\n" if ($in_comment); + if ($line =~ m@\*/@) { + $in_comment = 0; + } + } + + chomp($current_comment); + return($current_comment); +} +sub ctx_has_comment { + my ($first_line, $end_line) = @_; + my $cmt = ctx_locate_comment($first_line, $end_line); + + ##print "LINE: $rawlines[$end_line - 1 ]\n"; + ##print "CMMT: $cmt\n"; + + return ($cmt ne ''); +} + +sub raw_line { + my ($linenr, $cnt) = @_; + + my $offset = $linenr - 1; + $cnt++; + + my $line; + while ($cnt) { + $line = $rawlines[$offset++]; + next if (defined($line) && $line =~ /^-/); + $cnt--; + } + + return $line; +} + +sub get_stat_real { + my ($linenr, $lc) = @_; + + my $stat_real = raw_line($linenr, 0); + for (my $count = $linenr + 1; $count <= $lc; $count++) { + $stat_real = $stat_real . "\n" . raw_line($count, 0); + } + + return $stat_real; +} + +sub get_stat_here { + my ($linenr, $cnt, $here) = @_; + + my $herectx = $here . "\n"; + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + + return $herectx; +} + +sub cat_vet { + my ($vet) = @_; + my ($res, $coded); + + $res = ''; + while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { + $res .= $1; + if ($2 ne '') { + $coded = sprintf("^%c", unpack('C', $2) + 64); + $res .= $coded; + } + } + $res =~ s/$/\$/; + + return $res; +} + +my $av_preprocessor = 0; +my $av_pending; +my @av_paren_type; +my $av_pend_colon; + +sub annotate_reset { + $av_preprocessor = 0; + $av_pending = '_'; + @av_paren_type = ('E'); + $av_pend_colon = 'O'; +} + +sub annotate_values { + my ($stream, $type) = @_; + + my $res; + my $var = '_' x length($stream); + my $cur = $stream; + + print "$stream\n" if ($dbg_values > 1); + + while (length($cur)) { + @av_paren_type = ('E') if ($#av_paren_type < 0); + print " <" . join('', @av_paren_type) . + "> <$type> <$av_pending>" if ($dbg_values > 1); + if ($cur =~ /^(\s+)/o) { + print "WS($1)\n" if ($dbg_values > 1); + if ($1 =~ /\n/ && $av_preprocessor) { + $type = pop(@av_paren_type); + $av_preprocessor = 0; + } + + } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { + print "CAST($1)\n" if ($dbg_values > 1); + push(@av_paren_type, $type); + $type = 'c'; + + } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { + print "DECLARE($1)\n" if ($dbg_values > 1); + $type = 'T'; + + } elsif ($cur =~ /^($Modifier)\s*/) { + print "MODIFIER($1)\n" if ($dbg_values > 1); + $type = 'T'; + + } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { + print "DEFINE($1,$2)\n" if ($dbg_values > 1); + $av_preprocessor = 1; + push(@av_paren_type, $type); + if ($2 ne '') { + $av_pending = 'N'; + } + $type = 'E'; + + } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { + print "UNDEF($1)\n" if ($dbg_values > 1); + $av_preprocessor = 1; + push(@av_paren_type, $type); + + } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { + print "PRE_START($1)\n" if ($dbg_values > 1); + $av_preprocessor = 1; + + push(@av_paren_type, $type); + push(@av_paren_type, $type); + $type = 'E'; + + } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { + print "PRE_RESTART($1)\n" if ($dbg_values > 1); + $av_preprocessor = 1; + + push(@av_paren_type, $av_paren_type[$#av_paren_type]); + + $type = 'E'; + + } elsif ($cur =~ /^(\#\s*(?:endif))/o) { + print "PRE_END($1)\n" if ($dbg_values > 1); + + $av_preprocessor = 1; + + # Assume all arms of the conditional end as this + # one does, and continue as if the #endif was not here. + pop(@av_paren_type); + push(@av_paren_type, $type); + $type = 'E'; + + } elsif ($cur =~ /^(\\\n)/o) { + print "PRECONT($1)\n" if ($dbg_values > 1); + + } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { + print "ATTR($1)\n" if ($dbg_values > 1); + $av_pending = $type; + $type = 'N'; + + } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { + print "SIZEOF($1)\n" if ($dbg_values > 1); + if (defined $2) { + $av_pending = 'V'; + } + $type = 'N'; + + } elsif ($cur =~ /^(if|while|for)\b/o) { + print "COND($1)\n" if ($dbg_values > 1); + $av_pending = 'E'; + $type = 'N'; + + } elsif ($cur =~/^(case)/o) { + print "CASE($1)\n" if ($dbg_values > 1); + $av_pend_colon = 'C'; + $type = 'N'; + + } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { + print "KEYWORD($1)\n" if ($dbg_values > 1); + $type = 'N'; + + } elsif ($cur =~ /^(\()/o) { + print "PAREN('$1')\n" if ($dbg_values > 1); + push(@av_paren_type, $av_pending); + $av_pending = '_'; + $type = 'N'; + + } elsif ($cur =~ /^(\))/o) { + my $new_type = pop(@av_paren_type); + if ($new_type ne '_') { + $type = $new_type; + print "PAREN('$1') -> $type\n" + if ($dbg_values > 1); + } else { + print "PAREN('$1')\n" if ($dbg_values > 1); + } + + } elsif ($cur =~ /^($Ident)\s*\(/o) { + print "FUNC($1)\n" if ($dbg_values > 1); + $type = 'V'; + $av_pending = 'V'; + + } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { + if (defined $2 && $type eq 'C' || $type eq 'T') { + $av_pend_colon = 'B'; + } elsif ($type eq 'E') { + $av_pend_colon = 'L'; + } + print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); + $type = 'V'; + + } elsif ($cur =~ /^($Ident|$Constant)/o) { + print "IDENT($1)\n" if ($dbg_values > 1); + $type = 'V'; + + } elsif ($cur =~ /^($Assignment)/o) { + print "ASSIGN($1)\n" if ($dbg_values > 1); + $type = 'N'; + + } elsif ($cur =~/^(;|{|})/) { + print "END($1)\n" if ($dbg_values > 1); + $type = 'E'; + $av_pend_colon = 'O'; + + } elsif ($cur =~/^(,)/) { + print "COMMA($1)\n" if ($dbg_values > 1); + $type = 'C'; + + } elsif ($cur =~ /^(\?)/o) { + print "QUESTION($1)\n" if ($dbg_values > 1); + $type = 'N'; + + } elsif ($cur =~ /^(:)/o) { + print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); + + substr($var, length($res), 1, $av_pend_colon); + if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { + $type = 'E'; + } else { + $type = 'N'; + } + $av_pend_colon = 'O'; + + } elsif ($cur =~ /^(\[)/o) { + print "CLOSE($1)\n" if ($dbg_values > 1); + $type = 'N'; + + } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { + my $variant; + + print "OPV($1)\n" if ($dbg_values > 1); + if ($type eq 'V') { + $variant = 'B'; + } else { + $variant = 'U'; + } + + substr($var, length($res), 1, $variant); + $type = 'N'; + + } elsif ($cur =~ /^($Operators)/o) { + print "OP($1)\n" if ($dbg_values > 1); + if ($1 ne '++' && $1 ne '--') { + $type = 'N'; + } + + } elsif ($cur =~ /(^.)/o) { + print "C($1)\n" if ($dbg_values > 1); + } + if (defined $1) { + $cur = substr($cur, length($1)); + $res .= $type x length($1); + } + } + + return ($res, $var); +} + +sub possible { + my ($possible, $line) = @_; + my $notPermitted = qr{(?: + ^(?: + $Modifier| + $Storage| + $Type| + DEFINE_\S+ + )$| + ^(?: + goto| + return| + case| + else| + asm|__asm__| + do| + \#| + \#\#| + )(?:\s|$)| + ^(?:typedef|struct|enum)\b + )}x; + warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); + if ($possible !~ $notPermitted) { + # Check for modifiers. + $possible =~ s/\s*$Storage\s*//g; + $possible =~ s/\s*$Sparse\s*//g; + if ($possible =~ /^\s*$/) { + + } elsif ($possible =~ /\s/) { + $possible =~ s/\s*$Type\s*//g; + for my $modifier (split(' ', $possible)) { + if ($modifier !~ $notPermitted) { + warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); + push(@modifierListFile, $modifier); + } + } + + } else { + warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); + push(@typeListFile, $possible); + } + build_types(); + } else { + warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); + } +} + +my $prefix = ''; + +sub show_type { + my ($type) = @_; + + $type =~ tr/[a-z]/[A-Z]/; + + return defined $use_type{$type} if (scalar keys %use_type > 0); + + return !defined $ignore_type{$type}; +} + +sub report { + my ($level, $type, $msg) = @_; + + if (!show_type($type) || + (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { + return 0; + } + my $output = ''; + if ($color) { + if ($level eq 'ERROR') { + $output .= RED; + } elsif ($level eq 'WARNING') { + $output .= YELLOW; + } else { + $output .= GREEN; + } + } + $output .= $prefix . $level . ':'; + if ($show_types) { + $output .= BLUE if ($color); + $output .= "$type:"; + } + $output .= RESET if ($color); + $output .= ' ' . $msg . "\n"; + + if ($showfile) { + my @lines = split("\n", $output, -1); + splice(@lines, 1, 1); + $output = join("\n", @lines); + } + $output = (split('\n', $output))[0] . "\n" if ($terse); + + push(our @report, $output); + + return 1; +} + +sub report_dump { + our @report; +} + +sub fixup_current_range { + my ($lineRef, $offset, $length) = @_; + + if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { + my $o = $1; + my $l = $2; + my $no = $o + $offset; + my $nl = $l + $length; + $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; + } +} + +sub fix_inserted_deleted_lines { + my ($linesRef, $insertedRef, $deletedRef) = @_; + + my $range_last_linenr = 0; + my $delta_offset = 0; + + my $old_linenr = 0; + my $new_linenr = 0; + + my $next_insert = 0; + my $next_delete = 0; + + my @lines = (); + + my $inserted = @{$insertedRef}[$next_insert++]; + my $deleted = @{$deletedRef}[$next_delete++]; + + foreach my $old_line (@{$linesRef}) { + my $save_line = 1; + my $line = $old_line; #don't modify the array + if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename + $delta_offset = 0; + } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk + $range_last_linenr = $new_linenr; + fixup_current_range(\$line, $delta_offset, 0); + } + + while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { + $deleted = @{$deletedRef}[$next_delete++]; + $save_line = 0; + fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); + } + + while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { + push(@lines, ${$inserted}{'LINE'}); + $inserted = @{$insertedRef}[$next_insert++]; + $new_linenr++; + fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); + } + + if ($save_line) { + push(@lines, $line); + $new_linenr++; + } + + $old_linenr++; + } + + return @lines; +} + +sub fix_insert_line { + my ($linenr, $line) = @_; + + my $inserted = { + LINENR => $linenr, + LINE => $line, + }; + push(@fixed_inserted, $inserted); +} + +sub fix_delete_line { + my ($linenr, $line) = @_; + + my $deleted = { + LINENR => $linenr, + LINE => $line, + }; + + push(@fixed_deleted, $deleted); +} + +sub ERROR { + my ($type, $msg) = @_; + + if (report("ERROR", $type, $msg)) { + our $clean = 0; + our $cnt_error++; + return 1; + } + return 0; +} +sub WARN { + my ($type, $msg) = @_; + + if (report("WARNING", $type, $msg)) { + our $clean = 0; + our $cnt_warn++; + return 1; + } + return 0; +} +sub CHK { + my ($type, $msg) = @_; + + if ($check && report("CHECK", $type, $msg)) { + our $clean = 0; + our $cnt_chk++; + return 1; + } + return 0; +} + +sub check_absolute_file { + my ($absolute, $herecurr) = @_; + my $file = $absolute; + + ##print "absolute<$absolute>\n"; + + # See if any suffix of this path is a path within the tree. + while ($file =~ s@^[^/]*/@@) { + if (-f "$root/$file") { + ##print "file<$file>\n"; + last; + } + } + if (! -f _) { + return 0; + } + + # It is, so see if the prefix is acceptable. + my $prefix = $absolute; + substr($prefix, -length($file)) = ''; + + ##print "prefix<$prefix>\n"; + if ($prefix ne ".../") { + WARN("USE_RELATIVE_PATH", + "use relative pathname instead of absolute in changelog text\n" . $herecurr); + } +} + +sub trim { + my ($string) = @_; + + $string =~ s/^\s+|\s+$//g; + + return $string; +} + +sub ltrim { + my ($string) = @_; + + $string =~ s/^\s+//; + + return $string; +} + +sub rtrim { + my ($string) = @_; + + $string =~ s/\s+$//; + + return $string; +} + +sub string_find_replace { + my ($string, $find, $replace) = @_; + + $string =~ s/$find/$replace/g; + + return $string; +} + +sub tabify { + my ($leading) = @_; + + my $source_indent = 8; + my $max_spaces_before_tab = $source_indent - 1; + my $spaces_to_tab = " " x $source_indent; + + #convert leading spaces to tabs + 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; + #Remove spaces before a tab + 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; + + return "$leading"; +} + +sub pos_last_openparen { + my ($line) = @_; + + my $pos = 0; + + my $opens = $line =~ tr/\(/\(/; + my $closes = $line =~ tr/\)/\)/; + + my $last_openparen = 0; + + if (($opens == 0) || ($closes >= $opens)) { + return -1; + } + + my $len = length($line); + + for ($pos = 0; $pos < $len; $pos++) { + my $string = substr($line, $pos); + if ($string =~ /^($FuncArg|$balanced_parens)/) { + $pos += length($1) - 1; + } elsif (substr($line, $pos, 1) eq '(') { + $last_openparen = $pos; + } elsif (index($string, '(') == -1) { + last; + } + } + + return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; +} + +sub process { + my $filename = shift; + + my $linenr=0; + my $prevline=""; + my $prevrawline=""; + my $stashline=""; + my $stashrawline=""; + + my $length; + my $indent; + my $previndent=0; + my $stashindent=0; + + our $clean = 1; + my $signoff = 0; + my $author = ''; + my $authorsignoff = 0; + my $is_patch = 0; + my $is_binding_patch = -1; + my $in_header_lines = $file ? 0 : 1; + my $in_commit_log = 0; #Scanning lines before patch + my $has_commit_log = 0; #Encountered lines before patch + my $commit_log_lines = 0; #Number of commit log lines + my $commit_log_possible_stack_dump = 0; + my $commit_log_long_line = 0; + my $commit_log_has_diff = 0; + my $reported_maintainer_file = 0; + my $reported_abi_update = 0; + my $last_abi_file = ''; + my $non_utf8_charset = 0; + + my $last_blank_line = 0; + my $last_coalesced_string_linenr = -1; + + our @report = (); + our $cnt_lines = 0; + our $cnt_error = 0; + our $cnt_warn = 0; + our $cnt_chk = 0; + + # Trace the real file/line as we go. + my $realfile = ''; + my $realline = 0; + my $realcnt = 0; + my $here = ''; + my $context_function; #undef'd unless there's a known function + my $in_comment = 0; + my $comment_edge = 0; + my $first_line = 0; + my $p1_prefix = ''; + + my $prev_values = 'E'; + + # suppression flags + my %suppress_ifbraces; + my %suppress_whiletrailers; + my %suppress_export; + my $suppress_statement = 0; + + my %signatures = (); + + # Pre-scan the patch sanitizing the lines. + # Pre-scan the patch looking for any __setup documentation. + # + my @setup_docs = (); + my $setup_docs = 0; + + my $camelcase_file_seeded = 0; + + my $checklicenseline = 1; + + sanitise_line_reset(); + my $line; + foreach my $rawline (@rawlines) { + $linenr++; + $line = $rawline; + + push(@fixed, $rawline) if ($fix); + + if ($rawline=~/^\+\+\+\s+(\S+)/) { + $setup_docs = 0; + if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) { + $setup_docs = 1; + } + #next; + } + if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { + $realline=$1-1; + if (defined $2) { + $realcnt=$3+1; + } else { + $realcnt=1+1; + } + $in_comment = 0; + + # Guestimate if this is a continuing comment. Run + # the context looking for a comment "edge". If this + # edge is a close comment then we must be in a comment + # at context start. + my $edge; + my $cnt = $realcnt; + for (my $ln = $linenr + 1; $cnt > 0; $ln++) { + next if (defined $rawlines[$ln - 1] && + $rawlines[$ln - 1] =~ /^-/); + $cnt--; + #print "RAW<$rawlines[$ln - 1]>\n"; + last if (!defined $rawlines[$ln - 1]); + if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && + $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { + ($edge) = $1; + last; + } + } + if (defined $edge && $edge eq '*/') { + $in_comment = 1; + } + + # Guestimate if this is a continuing comment. If this + # is the start of a diff block and this line starts + # ' *' then it is very likely a comment. + if (!defined $edge && + $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) + { + $in_comment = 1; + } + + ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; + sanitise_line_reset($in_comment); + + } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { + # Standardise the strings and chars within the input to + # simplify matching -- only bother with positive lines. + $line = sanitise_line($rawline); + } + + # Check if ABI is being updated. If so, there's probably no need to + # emit the "does ABI need updating?" message on file add/move/delete + if ($SOF && + ($line =~ /\+#define SOF_ABI_MAJOR*/ || + $line =~ /\+#define SOF_ABI_MINOR*/ || + $line =~ /\+#define SOF_ABI_PATCH*/)) { + $reported_abi_update = 1; + } + + push(@lines, $line); + + if ($realcnt > 1) { + $realcnt-- if ($line =~ /^(?:\+| |$)/); + } else { + $realcnt = 0; + } + + #print "==>$rawline\n"; + #print "-->$line\n"; + + if ($setup_docs && $line =~ /^\+/) { + push(@setup_docs, $line); + } + } + + $prefix = ''; + + $realcnt = 0; + $linenr = 0; + $fixlinenr = -1; + foreach my $line (@lines) { + $linenr++; + $fixlinenr++; + my $sline = $line; #copy of $line + $sline =~ s/$;/ /g; #with comments as spaces + + my $rawline = $rawlines[$linenr - 1]; + +# check if it's a mode change, rename or start of a patch + if (!$in_commit_log && + ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ || + ($line =~ /^rename (?:from|to) \S+\s*$/ || + $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) { + $is_patch = 1; + } + +#extract the line range in the file after the patch is applied + if (!$in_commit_log && + $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { + my $context = $4; + $is_patch = 1; + $first_line = $linenr + 1; + $realline=$1-1; + if (defined $2) { + $realcnt=$3+1; + } else { + $realcnt=1+1; + } + annotate_reset(); + $prev_values = 'E'; + + %suppress_ifbraces = (); + %suppress_whiletrailers = (); + %suppress_export = (); + $suppress_statement = 0; + if ($context =~ /\b(\w+)\s*\(/) { + $context_function = $1; + } else { + undef $context_function; + } + next; + +# track the line number as we move through the hunk, note that +# new versions of GNU diff omit the leading space on completely +# blank context lines so we need to count that too. + } elsif ($line =~ /^( |\+|$)/) { + $realline++; + $realcnt-- if ($realcnt != 0); + + # Measure the line length and indent. + ($length, $indent) = line_stats($rawline); + + # Track the previous line. + ($prevline, $stashline) = ($stashline, $line); + ($previndent, $stashindent) = ($stashindent, $indent); + ($prevrawline, $stashrawline) = ($stashrawline, $rawline); + + #warn "line<$line>\n"; + + } elsif ($realcnt == 1) { + $realcnt--; + } + + my $hunk_line = ($realcnt != 0); + + $here = "#$linenr: " if (!$file); + $here = "#$realline: " if ($file); + + my $found_file = 0; + # extract the filename as it passes + if ($line =~ /^diff --git.*?(\S+)$/) { + $realfile = $1; + $realfile =~ s@^([^/]*)/@@ if (!$file); + $in_commit_log = 0; + $found_file = 1; + } elsif ($line =~ /^\+\+\+\s+(\S+)/) { + $realfile = $1; + $realfile =~ s@^([^/]*)/@@ if (!$file); + $in_commit_log = 0; + + $p1_prefix = $1; + if (!$file && $tree && $p1_prefix ne '' && + -e "$root/$p1_prefix") { + WARN("PATCH_PREFIX", + "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); + } + + if ($realfile =~ m@^include/asm/@) { + ERROR("MODIFIED_INCLUDE_ASM", + "do not modify files in include/asm, change architecture specific files in include/asm-\n" . "$here$rawline\n"); + } + $found_file = 1; + } + +#make up the handle for any error we report on this line + if ($showfile) { + $prefix = "$realfile:$realline: " + } elsif ($emacs) { + if ($file) { + $prefix = "$filename:$realline: "; + } else { + $prefix = "$filename:$linenr: "; + } + } + + if ($found_file) { + if (is_maintained_obsolete($realfile)) { + WARN("OBSOLETE", + "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); + } + if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { + $check = 1; + } else { + $check = $check_orig; + } + $checklicenseline = 1; + + if ($realfile !~ /^MAINTAINERS/) { + my $last_binding_patch = $is_binding_patch; + + $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@; + + if (($last_binding_patch != -1) && + ($last_binding_patch ^ $is_binding_patch)) { + WARN("DT_SPLIT_BINDING_PATCH", + "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n"); + } + } + + next; + } + + $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); + + my $hereline = "$here\n$rawline\n"; + my $herecurr = "$here\n$rawline\n"; + my $hereprev = "$here\n$prevrawline\n$rawline\n"; + + $cnt_lines++ if ($realcnt != 0); + +# Verify the existence of a commit log if appropriate +# 2 is used because a $signature is counted in $commit_log_lines + if ($in_commit_log) { + if ($line !~ /^\s*$/) { + $commit_log_lines++; #could be a $signature + } + } elsif ($has_commit_log && $commit_log_lines < 2) { + WARN("COMMIT_MESSAGE", + "Missing commit description - Add an appropriate one\n"); + $commit_log_lines = 2; #warn only once + } + +# Check if the commit log has what seems like a diff which can confuse patch + if ($in_commit_log && !$commit_log_has_diff && + (($line =~ m@^\s+diff\b.*a/[\w/]+@ && + $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) || + $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || + $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { + ERROR("DIFF_IN_COMMIT_MSG", + "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); + $commit_log_has_diff = 1; + } + +# Check for incorrect file permissions + if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { + my $permhere = $here . "FILE: $realfile\n"; + if ($realfile !~ m@scripts/@ && + $realfile !~ /\.(py|pl|awk|sh)$/) { + ERROR("EXECUTE_PERMISSIONS", + "do not set execute permissions for source files\n" . $permhere); + } + } + +# Check the patch for a From: + if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) { + $author = $1; + $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i); + $author =~ s/"//g; + } + +# Check the patch for a signoff: + if ($line =~ /^\s*signed-off-by:/i) { + $signoff++; + $in_commit_log = 0; + if ($author ne '') { + my $l = $line; + $l =~ s/"//g; + if ($l =~ /^\s*signed-off-by:\s*\Q$author\E/i) { + $authorsignoff = 1; + } + } + } + + +# Check if MAINTAINERS is being updated. If so, there's probably no need to +# emit the "does MAINTAINERS need updating?" message on file add/move/delete + if ($line =~ /^\s*MAINTAINERS\s*\|/) { + $reported_maintainer_file = 1; + } + +# Check signature styles + if (!$in_header_lines && + $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { + my $space_before = $1; + my $sign_off = $2; + my $space_after = $3; + my $email = $4; + my $ucfirst_sign_off = ucfirst(lc($sign_off)); + + if ($sign_off !~ /$signature_tags/) { + WARN("BAD_SIGN_OFF", + "Non-standard signature: $sign_off\n" . $herecurr); + } + if (defined $space_before && $space_before ne "") { + if (WARN("BAD_SIGN_OFF", + "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] = + "$ucfirst_sign_off $email"; + } + } + if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { + if (WARN("BAD_SIGN_OFF", + "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] = + "$ucfirst_sign_off $email"; + } + + } + if (!defined $space_after || $space_after ne " ") { + if (WARN("BAD_SIGN_OFF", + "Use a single space after $ucfirst_sign_off\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] = + "$ucfirst_sign_off $email"; + } + } + + my ($email_name, $email_address, $comment) = parse_email($email); + my $suggested_email = format_email(($email_name, $email_address)); + if ($suggested_email eq "") { + ERROR("BAD_SIGN_OFF", + "Unrecognized email address: '$email'\n" . $herecurr); + } else { + my $dequoted = $suggested_email; + $dequoted =~ s/^"//; + $dequoted =~ s/" $comment" ne $email && + "$suggested_email$comment" ne $email) { + WARN("BAD_SIGN_OFF", + "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); + } + } + +# Check for duplicate signatures + my $sig_nospace = $line; + $sig_nospace =~ s/\s//g; + $sig_nospace = lc($sig_nospace); + if (defined $signatures{$sig_nospace}) { + WARN("BAD_SIGN_OFF", + "Duplicate signature\n" . $herecurr); + } else { + $signatures{$sig_nospace} = 1; + } + +# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email + if ($sign_off =~ /^co-developed-by:$/i) { + if ($email eq $author) { + WARN("BAD_SIGN_OFF", + "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline); + } + if (!defined $lines[$linenr]) { + WARN("BAD_SIGN_OFF", + "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline); + } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) { + WARN("BAD_SIGN_OFF", + "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); + } elsif ($1 ne $email) { + WARN("BAD_SIGN_OFF", + "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); + } + } + } + +# Check email subject for common tools that don't need to be mentioned + if ($in_header_lines && + $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { + WARN("EMAIL_SUBJECT", + "A patch subject line should describe the change not the tool that found it\n" . $herecurr); + } + +# Check for unwanted Gerrit info + if ($in_commit_log && $line =~ /^\s*change-id:/i) { + ERROR("GERRIT_CHANGE_ID", + "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr); + } + +# Check if the commit log is in a possible stack dump + if ($in_commit_log && !$commit_log_possible_stack_dump && + ($line =~ /^\s*(?:WARNING:|BUG:)/ || + $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || + # timestamp + $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) || + $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ || + $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) { + # stack dump address styles + $commit_log_possible_stack_dump = 1; + } + +# Check for line lengths > 75 in commit log, warn once + if ($in_commit_log && !$commit_log_long_line && + length($line) > 75 && + !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || + # file delta changes + $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ || + # filename then : + $line =~ /^\s*(?:Fixes:|Link:)/i || + # A Fixes: or Link: line + $commit_log_possible_stack_dump)) { + WARN("COMMIT_LOG_LONG_LINE", + "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); + $commit_log_long_line = 1; + } + +# Reset possible stack dump if a blank line is found + if ($in_commit_log && $commit_log_possible_stack_dump && + $line =~ /^\s*$/) { + $commit_log_possible_stack_dump = 0; + } + +# Check for git id commit length and improperly formed commit descriptions + if ($in_commit_log && !$commit_log_possible_stack_dump && + $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i && + $line !~ /^This reverts commit [0-9a-f]{7,40}/ && + ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || + ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && + $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && + $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { + my $init_char = "c"; + my $orig_commit = ""; + my $short = 1; + my $long = 0; + my $case = 1; + my $space = 1; + my $hasdesc = 0; + my $hasparens = 0; + my $id = '0123456789ab'; + my $orig_desc = "commit description"; + my $description = ""; + + if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { + $init_char = $1; + $orig_commit = lc($2); + } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) { + $orig_commit = lc($1); + } + + $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i); + $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); + $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); + $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); + if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { + $orig_desc = $1; + $hasparens = 1; + } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && + defined $rawlines[$linenr] && + $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { + $orig_desc = $1; + $hasparens = 1; + } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && + defined $rawlines[$linenr] && + $rawlines[$linenr] =~ /^\s*[^"]+"\)/) { + $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; + $orig_desc = $1; + $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; + $orig_desc .= " " . $1; + $hasparens = 1; + } + + ($id, $description) = git_commit_info($orig_commit, + $id, $orig_desc); + + if (defined($id) && + ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) { + ERROR("GIT_COMMIT_ID", + "Please use git commit description style 'commit <12+ chars of sha1> (\"\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr); + } + } + +# Check for added, moved or deleted files + if (!$SOF && + (!$reported_maintainer_file && !$in_commit_log && + ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || + $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || + ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && + (defined($1) || defined($2)))))) { + $is_patch = 1; + $reported_maintainer_file = 1; + WARN("FILE_PATH_CHANGES", + "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); + } + +# Check for wrappage within a valid hunk of the file + if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { + ERROR("CORRUPTED_PATCH", + "patch seems to be corrupt (line wrapped?)\n" . + $herecurr) if (!$emitted_corrupt++); + } + +# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php + if (($realfile =~ /^$/ || $line =~ /^\+/) && + $rawline !~ m/^$UTF8*$/) { + my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); + + my $blank = copy_spacing($rawline); + my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; + my $hereptr = "$hereline$ptr\n"; + + CHK("INVALID_UTF8", + "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); + } + +# Check if it's the start of a commit log +# (not a header line and we haven't seen the patch filename) + if ($in_header_lines && $realfile =~ /^$/ && + !($rawline =~ /^\s+(?:\S|$)/ || + $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { + $in_header_lines = 0; + $in_commit_log = 1; + $has_commit_log = 1; + } + +# Check if there is UTF-8 in a commit log when a mail header has explicitly +# declined it, i.e defined some charset where it is missing. + if ($in_header_lines && + $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && + $1 !~ /utf-8/i) { + $non_utf8_charset = 1; + } + + if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && + $rawline =~ /$NON_ASCII_UTF8/) { + WARN("UTF8_BEFORE_PATCH", + "8-bit UTF-8 used in possible commit log\n" . $herecurr); + } + +# Check for absolute kernel paths in commit message + if ($tree && $in_commit_log) { + while ($line =~ m{(?:^|\s)(/\S*)}g) { + my $file = $1; + + if ($file =~ m{^(.*?)(?::\d+)+:?$} && + check_absolute_file($1, $herecurr)) { + # + } else { + check_absolute_file($file, $herecurr); + } + } + } + +# Check for various typo / spelling mistakes + if (defined($misspellings) && + ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { + while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) { + my $typo = $1; + my $typo_fix = $spelling_fix{lc($typo)}; + $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); + $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); + my $msg_level = \&WARN; + $msg_level = \&CHK if ($file); + if (&{$msg_level}("TYPO_SPELLING", + "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; + } + } + } + +# check for invalid commit id + if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) { + my $id; + my $description; + ($id, $description) = git_commit_info($2, undef, undef); + if (!defined($id)) { + WARN("UNKNOWN_COMMIT_ID", + "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr); + } + } + +# ignore non-hunk lines and lines being removed + next if (!$hunk_line || $line =~ /^-/); + +#trailing whitespace + if ($line =~ /^\+.*\015/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + if (ERROR("DOS_LINE_ENDINGS", + "DOS line endings\n" . $herevet) && + $fix) { + $fixed[$fixlinenr] =~ s/[\s\015]+$//; + } + } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + if (ERROR("TRAILING_WHITESPACE", + "trailing whitespace\n" . $herevet) && + $fix) { + $fixed[$fixlinenr] =~ s/\s+$//; + } + + $rpt_cleaners = 1; + } + +# Check for FSF mailing addresses. + if ($rawline =~ /\bwrite to the Free/i || + $rawline =~ /\b675\s+Mass\s+Ave/i || + $rawline =~ /\b59\s+Temple\s+Pl/i || + $rawline =~ /\b51\s+Franklin\s+St/i) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + my $msg_level = \&ERROR; + $msg_level = \&CHK if ($file); + &{$msg_level}("FSF_MAILING_ADDRESS", + "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet) + } + +# check for Kconfig help text having a real description +# Only applies when adding the entry originally, after that we do not have +# sufficient context to determine whether it is indeed long enough. + if ($realfile =~ /Kconfig/ && + # 'choice' is usually the last thing on the line (though + # Kconfig supports named choices), so use a word boundary + # (\b) rather than a whitespace character (\s) + $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) { + my $length = 0; + my $cnt = $realcnt; + my $ln = $linenr + 1; + my $f; + my $is_start = 0; + my $is_end = 0; + for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { + $f = $lines[$ln - 1]; + $cnt-- if ($lines[$ln - 1] !~ /^-/); + $is_end = $lines[$ln - 1] =~ /^\+/; + + next if ($f =~ /^-/); + last if (!$file && $f =~ /^\@\@/); + + if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) { + $is_start = 1; + } elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) { + if ($lines[$ln - 1] =~ "---help---") { + WARN("CONFIG_DESCRIPTION", + "prefer 'help' over '---help---' for new help texts\n" . $herecurr); + } + $length = -1; + } + + $f =~ s/^.//; + $f =~ s/#.*//; + $f =~ s/^\s+//; + next if ($f =~ /^$/); + + # This only checks context lines in the patch + # and so hopefully shouldn't trigger false + # positives, even though some of these are + # common words in help texts + if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice| + if|endif|menu|endmenu|source)\b/x) { + $is_end = 1; + last; + } + $length++; + } + if ($is_start && $is_end && $length < $min_conf_desc_length) { + WARN("CONFIG_DESCRIPTION", + "please write a paragraph that describes the config symbol fully\n" . $herecurr); + } + #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; + } + +# check for MAINTAINERS entries that don't have the right form + if ($realfile =~ /^MAINTAINERS$/ && + $rawline =~ /^\+[A-Z]:/ && + $rawline !~ /^\+[A-Z]:\t\S/) { + if (WARN("MAINTAINERS_STYLE", + "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; + } + } + +# discourage the use of boolean for type definition attributes of Kconfig options + if ($realfile =~ /Kconfig/ && + $line =~ /^\+\s*\bboolean\b/) { + WARN("CONFIG_TYPE_BOOLEAN", + "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); + } + + if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && + ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { + my $flag = $1; + my $replacement = { + 'EXTRA_AFLAGS' => 'asflags-y', + 'EXTRA_CFLAGS' => 'ccflags-y', + 'EXTRA_CPPFLAGS' => 'cppflags-y', + 'EXTRA_LDFLAGS' => 'ldflags-y', + }; + + WARN("DEPRECATED_VARIABLE", + "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); + } + +# check for DT compatible documentation + if (defined $root && + (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || + ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { + + my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; + + my $dt_path = $root . "/Documentation/devicetree/bindings/"; + my $vp_file = $dt_path . "vendor-prefixes.yaml"; + + foreach my $compat (@compats) { + my $compat2 = $compat; + $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; + my $compat3 = $compat; + $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; + `grep -Erq "$compat|$compat2|$compat3" $dt_path`; + if ( $? >> 8 ) { + WARN("UNDOCUMENTED_DT_STRING", + "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); + } + + next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; + my $vendor = $1; + `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`; + if ( $? >> 8 ) { + WARN("UNDOCUMENTED_DT_STRING", + "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); + } + } + } + +# check for using SPDX license tag at beginning of files + if ($realline == $checklicenseline) { + if ($rawline =~ /^[ \+]\s*\#\!\s*\//) { + $checklicenseline = 2; + } elsif ($rawline =~ /^\+/) { + my $comment = ""; + if ($realfile =~ /\.(h|s|S)$/) { + $comment = '/*'; + } elsif ($realfile =~ /\.(c|dts|dtsi)$/) { + $comment = '//'; + } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc)$/) { + $comment = '#'; + } elsif ($realfile =~ /\.rst$/) { + $comment = '..'; + } + +# check SPDX comment style for .[chsS] files + if ($realfile =~ /\.[chsS]$/ && + $rawline =~ /SPDX-License-Identifier:/ && + $rawline !~ m@^\+\s*\Q$comment\E\s*@) { + WARN("SPDX_LICENSE_TAG", + "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr); + } + + if ($comment !~ /^$/ && + $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) { + WARN("SPDX_LICENSE_TAG", + "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); + } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) { + my $spdx_license = $1; + if (!is_SPDX_License_valid($spdx_license)) { + WARN("SPDX_LICENSE_TAG", + "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); + } + } + } + } + +# check we are in a valid source file if not then ignore this hunk + next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); + +# check for using SPDX-License-Identifier on the wrong line number + if ($realline != $checklicenseline && + $rawline =~ /\bSPDX-License-Identifier:/ && + substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) { + WARN("SPDX_LICENSE_TAG", + "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr); + } + +# line length limit (with some exclusions) +# +# There are a few types of lines that may extend beyond $max_line_length: +# logging functions like pr_info that end in a string +# lines with a single string +# #defines that are a single string +# lines with an RFC3986 like URL +# +# There are 3 different line length message types: +# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length +# LONG_LINE_STRING a string starts before but extends beyond $max_line_length +# LONG_LINE all other lines longer than $max_line_length +# +# if LONG_LINE is ignored, the other 2 types are also ignored +# + + if ($line =~ /^\+/ && $length > $max_line_length) { + my $msg_type = "LONG_LINE"; + + # Check the allowed long line types first + + # logging functions that end in a string that starts + # before $max_line_length + if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && + length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { + $msg_type = ""; + + # lines with only strings (w/ possible termination) + # #defines with only strings + } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || + $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { + $msg_type = ""; + + # More special cases + } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ || + $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) { + $msg_type = ""; + + # URL ($rawline is used in case the URL is in a comment) + } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) { + $msg_type = ""; + + # Otherwise set the alternate message types + + # a comment starts before $max_line_length + } elsif ($line =~ /($;[\s$;]*)$/ && + length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { + $msg_type = "LONG_LINE_COMMENT" + + # a quoted string starts before $max_line_length + } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && + length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { + $msg_type = "LONG_LINE_STRING" + } + + if ($msg_type ne "" && + (show_type("LONG_LINE") || show_type($msg_type))) { + my $msg_level = \&WARN; + $msg_level = \&CHK if ($file); + &{$msg_level}($msg_type, + "line length of $length exceeds $max_line_length columns\n" . $herecurr); + } + } + +# check for adding lines without a newline. + if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { + WARN("MISSING_EOF_NEWLINE", + "adding a line without newline at end of file\n" . $herecurr); + } + +# check we are in a valid source file C or perl if not then ignore this hunk + next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); + +# at the beginning of a line any tabs must come first and anything +# more than 8 must use tabs. + if ($rawline =~ /^\+\s* \t\s*\S/ || + $rawline =~ /^\+\s* \s*/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + $rpt_cleaners = 1; + if (ERROR("CODE_INDENT", + "code indent should use tabs where possible\n" . $herevet) && + $fix) { + $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; + } + } + +# check for space before tabs. + if ($rawline =~ /^\+/ && $rawline =~ / \t/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + if (WARN("SPACE_BEFORE_TAB", + "please, no space before tabs\n" . $herevet) && + $fix) { + while ($fixed[$fixlinenr] =~ + s/(^\+.*) {8,8}\t/$1\t\t/) {} + while ($fixed[$fixlinenr] =~ + s/(^\+.*) +\t/$1\t/) {} + } + } + +# check for assignments on the start of a line + if ($sline =~ /^\+\s+($Assignment)[^=]/) { + CHK("ASSIGNMENT_CONTINUATIONS", + "Assignment operator '$1' should be on the previous line\n" . $hereprev); + } + +# check for && or || at the start of a line + if ($rawline =~ /^\+\s*(&&|\|\|)/) { + CHK("LOGICAL_CONTINUATIONS", + "Logical continuations should be on the previous line\n" . $hereprev); + } + +# check indentation starts on a tab stop + if ($perl_version_ok && + $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { + my $indent = length($1); + if ($indent % 8) { + if (WARN("TABSTOP", + "Statements should start on a tabstop\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e; + } + } + } + +# check multi-line statement indentation matches previous line + if ($perl_version_ok && + $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { + $prevline =~ /^\+(\t*)(.*)$/; + my $oldindent = $1; + my $rest = $2; + + my $pos = pos_last_openparen($rest); + if ($pos >= 0) { + $line =~ /^(\+| )([ \t]*)/; + my $newindent = $2; + + my $goodtabindent = $oldindent . + "\t" x ($pos / 8) . + " " x ($pos % 8); + my $goodspaceindent = $oldindent . " " x $pos; + + if ($newindent ne $goodtabindent && + $newindent ne $goodspaceindent) { + + if (CHK("PARENTHESIS_ALIGNMENT", + "Alignment should match open parenthesis\n" . $hereprev) && + $fix && $line =~ /^\+/) { + $fixed[$fixlinenr] =~ + s/^\+[ \t]*/\+$goodtabindent/; + } + } + } + } + +# check for space after cast like "(int) foo" or "(struct foo) bar" +# avoid checking a few false positives: +# "sizeof(<type>)" or "__alignof__(<type>)" +# function pointer declarations like "(*foo)(int) = bar;" +# structure definitions like "(struct foo) { 0 };" +# multiline macros that define functions +# known attributes or the __attribute__ keyword + if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && + (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { + if (CHK("SPACING", + "No space is necessary after a cast\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ + s/(\(\s*$Type\s*\))[ \t]+/$1/; + } + } + +# Block comment styles +# Networking with an initial /* + if ($realfile =~ m@^(drivers/net/|net/)@ && + $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && + $rawline =~ /^\+[ \t]*\*/ && + $realline > 2) { + WARN("NETWORKING_BLOCK_COMMENT_STYLE", + "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); + } + +# UAPI ABI version + if ($SOF && $realfile ne $last_abi_file && + $realfile =~ m@^(src/include/ipc/|src/include/kernel/|src/include/user/)@ && + $rawline =~ /^\+/ && + !$reported_abi_update) { + $last_abi_file = $realfile; + WARN("ABI update ??", + "Please update ABI in accordance with http://semver.org\n" . $hereprev); + } + +# Block comments use * on subsequent lines + if ($prevline =~ /$;[ \t]*$/ && #ends in comment + $prevrawline =~ /^\+.*?\/\*/ && #starting /* + $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ + $rawline =~ /^\+/ && #line is new + $rawline !~ /^\+[ \t]*\*/) { #no leading * + WARN("BLOCK_COMMENT_STYLE", + "Block comments use * on subsequent lines\n" . $hereprev); + } + +# Block comments use */ on trailing lines + if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ + $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ + $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ + $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ + WARN("BLOCK_COMMENT_STYLE", + "Block comments use a trailing */ on a separate line\n" . $herecurr); + } + +# Block comment * alignment + if ($prevline =~ /$;[ \t]*$/ && #ends in comment + $line =~ /^\+[ \t]*$;/ && #leading comment + $rawline =~ /^\+[ \t]*\*/ && #leading * + (($prevrawline =~ /^\+.*?\/\*/ && #leading /* + $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ + $prevrawline =~ /^\+[ \t]*\*/)) { #leading * + my $oldindent; + $prevrawline =~ m@^\+([ \t]*/?)\*@; + if (defined($1)) { + $oldindent = expand_tabs($1); + } else { + $prevrawline =~ m@^\+(.*/?)\*@; + $oldindent = expand_tabs($1); + } + $rawline =~ m@^\+([ \t]*)\*@; + my $newindent = $1; + $newindent = expand_tabs($newindent); + if (length($oldindent) ne length($newindent)) { + WARN("BLOCK_COMMENT_STYLE", + "Block comments should align the * on each line\n" . $hereprev); + } + } + +# check for missing blank lines after struct/union declarations +# with exceptions for various attributes and macros + if ($prevline =~ /^[\+ ]};?\s*$/ && + $line =~ /^\+/ && + !($line =~ /^\+\s*$/ || + $line =~ /^\+\s*EXPORT_SYMBOL/ || + $line =~ /^\+\s*MODULE_/i || + $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || + $line =~ /^\+[a-z_]*init/ || + $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || + $line =~ /^\+\s*DECLARE/ || + $line =~ /^\+\s*builtin_[\w_]*driver/ || + $line =~ /^\+\s*__setup/)) { + if (CHK("LINE_SPACING", + "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && + $fix) { + fix_insert_line($fixlinenr, "\+"); + } + } + +# check for multiple consecutive blank lines + if ($prevline =~ /^[\+ ]\s*$/ && + $line =~ /^\+\s*$/ && + $last_blank_line != ($linenr - 1)) { + if (CHK("LINE_SPACING", + "Please don't use multiple blank lines\n" . $hereprev) && + $fix) { + fix_delete_line($fixlinenr, $rawline); + } + + $last_blank_line = $linenr; + } + +# check for missing blank lines after declarations + if ($sline =~ /^\+\s+\S/ && #Not at char 1 + # actual declarations + ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || + # function pointer declarations + $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || + # foo bar; where foo is some local typedef or #define + $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || + # known declaration macros + $prevline =~ /^\+\s+$declaration_macros/) && + # for "else if" which can look like "$Ident $Ident" + !($prevline =~ /^\+\s+$c90_Keywords\b/ || + # other possible extensions of declaration lines + $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || + # not starting a section or a macro "\" extended line + $prevline =~ /(?:\{\s*|\\)$/) && + # looks like a declaration + !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || + # function pointer declarations + $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || + # foo bar; where foo is some local typedef or #define + $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || + # known declaration macros + $sline =~ /^\+\s+$declaration_macros/ || + # start of struct or union or enum + $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ || + # start or end of block or continuation of declaration + $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || + # bitfield continuation + $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || + # other possible extensions of declaration lines + $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) && + # indentation of previous and current line are the same + (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) { + if (WARN("LINE_SPACING", + "Missing a blank line after declarations\n" . $hereprev) && + $fix) { + fix_insert_line($fixlinenr, "\+"); + } + } + +# check for spaces at the beginning of a line. +# Exceptions: +# 1) within comments +# 2) indented preprocessor commands +# 3) hanging labels + if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + if (WARN("LEADING_SPACE", + "please, no spaces at the start of a line\n" . $herevet) && + $fix) { + $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; + } + } + +# check we are in a valid C source file if not then ignore this hunk + next if ($realfile !~ /\.(h|c)$/); + +# check for unusual line ending [ or ( + if ($line =~ /^\+.*([\[\(])\s*$/) { + CHK("OPEN_ENDED_LINE", + "Lines should not end with a '$1'\n" . $herecurr); + } + +# check if this appears to be the start function declaration, save the name + if ($sline =~ /^\+\{\s*$/ && + $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { + $context_function = $1; + } + +# check if this appears to be the end of function declaration + if ($sline =~ /^\+\}\s*$/) { + undef $context_function; + } + +# check indentation of any line with a bare else +# (but not if it is a multiple line "if (foo) return bar; else return baz;") +# if the previous line is a break or return and is indented 1 tab more... + if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { + my $tabs = length($1) + 1; + if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || + ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && + defined $lines[$linenr] && + $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { + WARN("UNNECESSARY_ELSE", + "else is not generally useful after a break or return\n" . $hereprev); + } + } + +# check indentation of a line with a break; +# if the previous line is a goto or return and is indented the same # of tabs + if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { + my $tabs = $1; + if ($prevline =~ /^\+$tabs(?:goto|return)\b/) { + WARN("UNNECESSARY_BREAK", + "break is not useful after a goto or return\n" . $hereprev); + } + } + +# check for RCS/CVS revision markers + if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { + WARN("CVS_KEYWORD", + "CVS style keyword markers, these will _not_ be updated\n". $herecurr); + } + +# check for old HOTPLUG __dev<foo> section markings + if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { + WARN("HOTPLUG_SECTION", + "Using $1 is unnecessary\n" . $herecurr); + } + +# Check for potential 'bare' types + my ($stat, $cond, $line_nr_next, $remain_next, $off_next, + $realline_next); +#print "LINE<$line>\n"; + if ($linenr > $suppress_statement && + $realcnt && $sline =~ /.\s*\S/) { + ($stat, $cond, $line_nr_next, $remain_next, $off_next) = + ctx_statement_block($linenr, $realcnt, 0); + $stat =~ s/\n./\n /g; + $cond =~ s/\n./\n /g; + +#print "linenr<$linenr> <$stat>\n"; + # If this statement has no statement boundaries within + # it there is no point in retrying a statement scan + # until we hit end of it. + my $frag = $stat; $frag =~ s/;+\s*$//; + if ($frag !~ /(?:{|;)/) { +#print "skip<$line_nr_next>\n"; + $suppress_statement = $line_nr_next; + } + + # Find the real next line. + $realline_next = $line_nr_next; + if (defined $realline_next && + (!defined $lines[$realline_next - 1] || + substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { + $realline_next++; + } + + my $s = $stat; + $s =~ s/{.*$//s; + + # Ignore goto labels. + if ($s =~ /$Ident:\*$/s) { + + # Ignore functions being called + } elsif ($s =~ /^.\s*$Ident\s*\(/s) { + + } elsif ($s =~ /^.\s*else\b/s) { + + # declarations always start with types + } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?((?:\s*$Ident)+?)\b(?:\s+$Sparse)?\s*\**\s*(?:$Ident|\(\*[^\)]*\))(?:\s*$Modifier)?\s*(?:;|=|,|\()/s) { + my $type = $1; + $type =~ s/\s+/ /g; + possible($type, "A:" . $s); + + # definitions in global scope can only start with types + } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { + possible($1, "B:" . $s); + } + + # any (foo ... *) is a pointer cast, and foo is a type + while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { + possible($1, "C:" . $s); + } + + # Check for any sort of function declaration. + # int foo(something bar, other baz); + # void (*store_gdt)(x86_descr_ptr *); + if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { + my ($name_len) = length($1); + + my $ctx = $s; + substr($ctx, 0, $name_len + 1, ''); + $ctx =~ s/\)[^\)]*$//; + + for my $arg (split(/\s*,\s*/, $ctx)) { + if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { + + possible($1, "D:" . $s); + } + } + } + + } + +# +# Checks which may be anchored in the context. +# + +# Check for switch () and associated case and default +# statements should be at the same indent. + if ($line=~/\bswitch\s*\(.*\)/) { + my $err = ''; + my $sep = ''; + my @ctx = ctx_block_outer($linenr, $realcnt); + shift(@ctx); + for my $ctx (@ctx) { + my ($clen, $cindent) = line_stats($ctx); + if ($ctx =~ /^\+\s*(case\s+|default:)/ && + $indent != $cindent) { + $err .= "$sep$ctx\n"; + $sep = ''; + } else { + $sep = "[...]\n"; + } + } + if ($err ne '') { + ERROR("SWITCH_CASE_INDENT_LEVEL", + "switch and case should be at the same indent\n$hereline$err"); + } + } + +# if/while/etc brace do not go on next line, unless defining a do while loop, +# or if that brace on the next line is for something else + if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { + my $pre_ctx = "$1$2"; + + my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); + + if ($line =~ /^\+\t{6,}/) { + WARN("DEEP_INDENTATION", + "Too many leading tabs - consider code refactoring\n" . $herecurr); + } + + my $ctx_cnt = $realcnt - $#ctx - 1; + my $ctx = join("\n", @ctx); + + my $ctx_ln = $linenr; + my $ctx_skip = $realcnt; + + while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && + defined $lines[$ctx_ln - 1] && + $lines[$ctx_ln - 1] =~ /^-/)) { + ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; + $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); + $ctx_ln++; + } + + #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; + #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; + + if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { + ERROR("OPEN_BRACE", + "that open brace { should be on the previous line\n" . + "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); + } + if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && + $ctx =~ /\)\s*\;\s*$/ && + defined $lines[$ctx_ln - 1]) + { + my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); + if ($nindent > $indent) { + WARN("TRAILING_SEMICOLON", + "trailing semicolon indicates no statements, indent implies otherwise\n" . + "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); + } + } + } + +# Check relative indent for conditionals and blocks. + if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { + ($stat, $cond, $line_nr_next, $remain_next, $off_next) = + ctx_statement_block($linenr, $realcnt, 0) + if (!defined $stat); + my ($s, $c) = ($stat, $cond); + + substr($s, 0, length($c), ''); + + # remove inline comments + $s =~ s/$;/ /g; + $c =~ s/$;/ /g; + + # Find out how long the conditional actually is. + my @newlines = ($c =~ /\n/gs); + my $cond_lines = 1 + $#newlines; + + # Make sure we remove the line prefixes as we have + # none on the first line, and are going to readd them + # where necessary. + $s =~ s/\n./\n/gs; + while ($s =~ /\n\s+\\\n/) { + $cond_lines += $s =~ s/\n\s+\\\n/\n/g; + } + + # We want to check the first line inside the block + # starting at the end of the conditional, so remove: + # 1) any blank line termination + # 2) any opening brace { on end of the line + # 3) any do (...) { + my $continuation = 0; + my $check = 0; + $s =~ s/^.*\bdo\b//; + $s =~ s/^\s*{//; + if ($s =~ s/^\s*\\//) { + $continuation = 1; + } + if ($s =~ s/^\s*?\n//) { + $check = 1; + $cond_lines++; + } + + # Also ignore a loop construct at the end of a + # preprocessor statement. + if (($prevline =~ /^.\s*#\s*define\s/ || + $prevline =~ /\\\s*$/) && $continuation == 0) { + $check = 0; + } + + my $cond_ptr = -1; + $continuation = 0; + while ($cond_ptr != $cond_lines) { + $cond_ptr = $cond_lines; + + # If we see an #else/#elif then the code + # is not linear. + if ($s =~ /^\s*\#\s*(?:else|elif)/) { + $check = 0; + } + + # Ignore: + # 1) blank lines, they should be at 0, + # 2) preprocessor lines, and + # 3) labels. + if ($continuation || + $s =~ /^\s*?\n/ || + $s =~ /^\s*#\s*?/ || + $s =~ /^\s*$Ident\s*:/) { + $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; + if ($s =~ s/^.*?\n//) { + $cond_lines++; + } + } + } + + my (undef, $sindent) = line_stats("+" . $s); + my $stat_real = raw_line($linenr, $cond_lines); + + # Check if either of these lines are modified, else + # this is not this patch's fault. + if (!defined($stat_real) || + $stat !~ /^\+/ && $stat_real !~ /^\+/) { + $check = 0; + } + if (defined($stat_real) && $cond_lines > 1) { + $stat_real = "[...]\n$stat_real"; + } + + #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n"; + + if ($check && $s ne '' && + (($sindent % 8) != 0 || + ($sindent < $indent) || + ($sindent == $indent && + ($s !~ /^\s*(?:\}|\{|else\b)/)) || + ($sindent > $indent + 8))) { + WARN("SUSPECT_CODE_INDENT", + "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); + } + } + + # Track the 'values' across context and added lines. + my $opline = $line; $opline =~ s/^./ /; + my ($curr_values, $curr_vars) = + annotate_values($opline . "\n", $prev_values); + $curr_values = $prev_values . $curr_values; + if ($dbg_values) { + my $outline = $opline; $outline =~ s/\t/ /g; + print "$linenr > .$outline\n"; + print "$linenr > $curr_values\n"; + print "$linenr > $curr_vars\n"; + } + $prev_values = substr($curr_values, -1); + +#ignore lines not being added + next if ($line =~ /^[^\+]/); + +# check for dereferences that span multiple lines + if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && + $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { + $prevline =~ /($Lval\s*(?:\.|->))\s*$/; + my $ref = $1; + $line =~ /^.\s*($Lval)/; + $ref .= $1; + $ref =~ s/\s//g; + WARN("MULTILINE_DEREFERENCE", + "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); + } + +# check for declarations of signed or unsigned without int + while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { + my $type = $1; + my $var = $2; + $var = "" if (!defined $var); + if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { + my $sign = $1; + my $pointer = $2; + + $pointer = "" if (!defined $pointer); + + if (WARN("UNSPECIFIED_INT", + "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && + $fix) { + my $decl = trim($sign) . " int "; + my $comp_pointer = $pointer; + $comp_pointer =~ s/\s//g; + $decl .= $comp_pointer; + $decl = rtrim($decl) if ($var eq ""); + $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; + } + } + } + +# TEST: allow direct testing of the type matcher. + if ($dbg_type) { + if ($line =~ /^.\s*$Declare\s*$/) { + ERROR("TEST_TYPE", + "TEST: is type\n" . $herecurr); + } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { + ERROR("TEST_NOT_TYPE", + "TEST: is not type ($1 is)\n". $herecurr); + } + next; + } +# TEST: allow direct testing of the attribute matcher. + if ($dbg_attr) { + if ($line =~ /^.\s*$Modifier\s*$/) { + ERROR("TEST_ATTR", + "TEST: is attr\n" . $herecurr); + } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { + ERROR("TEST_NOT_ATTR", + "TEST: is not attr ($1 is)\n". $herecurr); + } + next; + } + +# check for initialisation to aggregates open brace on the next line + if ($line =~ /^.\s*{/ && + $prevline =~ /(?:^|[^=])=\s*$/) { + if (ERROR("OPEN_BRACE", + "that open brace { should be on the previous line\n" . $hereprev) && + $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { + fix_delete_line($fixlinenr - 1, $prevrawline); + fix_delete_line($fixlinenr, $rawline); + my $fixedline = $prevrawline; + $fixedline =~ s/\s*=\s*$/ = {/; + fix_insert_line($fixlinenr, $fixedline); + $fixedline = $line; + $fixedline =~ s/^(.\s*)\{\s*/$1/; + fix_insert_line($fixlinenr, $fixedline); + } + } + +# +# Checks which are anchored on the added line. +# + +# check for malformed paths in #include statements (uses RAW line) + if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { + my $path = $1; + if ($path =~ m{//}) { + ERROR("MALFORMED_INCLUDE", + "malformed #include filename\n" . $herecurr); + } + if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { + ERROR("UAPI_INCLUDE", + "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); + } + } + +# no C99 // comments + if ($line =~ m{//}) { + if (ERROR("C99_COMMENTS", + "do not use C99 // comments\n" . $herecurr) && + $fix) { + my $line = $fixed[$fixlinenr]; + if ($line =~ /\/\/(.*)$/) { + my $comment = trim($1); + $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; + } + } + } + # Remove C99 comments. + $line =~ s@//.*@@; + $opline =~ s@//.*@@; + +# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider +# the whole statement. +#print "APW <$lines[$realline_next - 1]>\n"; + if (defined $realline_next && + exists $lines[$realline_next - 1] && + !defined $suppress_export{$realline_next} && + ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || + $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { + # Handle definitions which produce identifiers with + # a prefix: + # XXX(foo); + # EXPORT_SYMBOL(something_foo); + my $name = $1; + if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && + $name =~ /^${Ident}_$2/) { +#print "FOO C name<$name>\n"; + $suppress_export{$realline_next} = 1; + + } elsif ($stat !~ /(?: + \n.}\s*$| + ^.DEFINE_$Ident\(\Q$name\E\)| + ^.DECLARE_$Ident\(\Q$name\E\)| + ^.LIST_HEAD\(\Q$name\E\)| + ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| + \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() + )/x) { +#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; + $suppress_export{$realline_next} = 2; + } else { + $suppress_export{$realline_next} = 1; + } + } + if (!defined $suppress_export{$linenr} && + $prevline =~ /^.\s*$/ && + ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || + $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { +#print "FOO B <$lines[$linenr - 1]>\n"; + $suppress_export{$linenr} = 2; + } + if (defined $suppress_export{$linenr} && + $suppress_export{$linenr} == 2) { + WARN("EXPORT_SYMBOL", + "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); + } + +# check for global initialisers. + if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) { + if (ERROR("GLOBAL_INITIALISERS", + "do not initialise globals to $1\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; + } + } +# check for static initialisers. + if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { + if (ERROR("INITIALISED_STATIC", + "do not initialise statics to $1\n" . + $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; + } + } + +# check for misordered declarations of char/short/int/long with signed/unsigned + while ($sline =~ m{(\b$TypeMisordered\b)}g) { + my $tmp = trim($1); + WARN("MISORDERED_TYPE", + "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); + } + +# check for unnecessary <signed> int declarations of short/long/long long + while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) { + my $type = trim($1); + next if ($type !~ /\bint\b/); + next if ($type !~ /\b(?:short|long\s+long|long)\b/); + my $new_type = $type; + $new_type =~ s/\b\s*int\s*\b/ /; + $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /; + $new_type =~ s/^const\s+//; + $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/); + $new_type = "const $new_type" if ($type =~ /^const\b/); + $new_type =~ s/\s+/ /g; + $new_type = trim($new_type); + if (WARN("UNNECESSARY_INT", + "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/; + } + } + +# check for static const char * arrays. + if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { + WARN("STATIC_CONST_CHAR_ARRAY", + "static const char * array should probably be static const char * const\n" . + $herecurr); + } + +# check for initialized const char arrays that should be static const + if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) { + if (WARN("STATIC_CONST_CHAR_ARRAY", + "const array should probably be static const\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/; + } + } + +# check for static char foo[] = "bar" declarations. + if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { + WARN("STATIC_CONST_CHAR_ARRAY", + "static char array declaration should probably be static const char\n" . + $herecurr); + } + +# check for const <foo> const where <foo> is not a pointer or array type + if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { + my $found = $1; + if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { + WARN("CONST_CONST", + "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); + } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { + WARN("CONST_CONST", + "'const $found const' should probably be 'const $found'\n" . $herecurr); + } + } + +# check for non-global char *foo[] = {"bar", ...} declarations. + if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { + WARN("STATIC_CONST_CHAR_ARRAY", + "char * array declaration might be better as static const\n" . + $herecurr); + } + +# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) + if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { + my $array = $1; + if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) { + my $array_div = $1; + if (WARN("ARRAY_SIZE", + "Prefer ARRAY_SIZE($array)\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; + } + } + } + +# check for function declarations without arguments like "int foo()" + if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) { + if (ERROR("FUNCTION_WITHOUT_ARGS", + "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; + } + } + +# check for new typedefs, only function parameters and sparse annotations +# make sense. + if ($line =~ /\btypedef\s/ && + $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && + $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && + $line !~ /\b$typeTypedefs\b/ && + $line !~ /\b__bitwise\b/) { + WARN("NEW_TYPEDEFS", + "do not add new typedefs\n" . $herecurr); + } + +# * goes on variable not on type + # (char*[ const]) + while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { + #print "AA<$1>\n"; + my ($ident, $from, $to) = ($1, $2, $2); + + # Should start with a space. + $to =~ s/^(\S)/ $1/; + # Should not end with a space. + $to =~ s/\s+$//; + # '*'s should not have spaces between. + while ($to =~ s/\*\s+\*/\*\*/) { + } + +## print "1: from<$from> to<$to> ident<$ident>\n"; + if ($from ne $to) { + if (ERROR("POINTER_LOCATION", + "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && + $fix) { + my $sub_from = $ident; + my $sub_to = $ident; + $sub_to =~ s/\Q$from\E/$to/; + $fixed[$fixlinenr] =~ + s@\Q$sub_from\E@$sub_to@; + } + } + } + while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { + #print "BB<$1>\n"; + my ($match, $from, $to, $ident) = ($1, $2, $2, $3); + + # Should start with a space. + $to =~ s/^(\S)/ $1/; + # Should not end with a space. + $to =~ s/\s+$//; + # '*'s should not have spaces between. + while ($to =~ s/\*\s+\*/\*\*/) { + } + # Modifiers should have spaces. + $to =~ s/(\b$Modifier$)/$1 /; + +## print "2: from<$from> to<$to> ident<$ident>\n"; + if ($from ne $to && $ident !~ /^$Modifier$/) { + if (ERROR("POINTER_LOCATION", + "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && + $fix) { + + my $sub_from = $match; + my $sub_to = $match; + $sub_to =~ s/\Q$from\E/$to/; + $fixed[$fixlinenr] =~ + s@\Q$sub_from\E@$sub_to@; + } + } + } + +# avoid BUG() or BUG_ON() + if ($line =~ /\b(?:BUG|BUG_ON)\b/) { + my $msg_level = \&WARN; + $msg_level = \&CHK if ($file); + &{$msg_level}("AVOID_BUG", + "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); + } + +# avoid LINUX_VERSION_CODE + if ($line =~ /\bLINUX_VERSION_CODE\b/) { + WARN("LINUX_VERSION_CODE", + "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); + } + +# check for uses of printk_ratelimit + if ($line =~ /\bprintk_ratelimit\s*\(/) { + WARN("PRINTK_RATELIMITED", + "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); + } + +# printk should use KERN_* levels + if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) { + WARN("PRINTK_WITHOUT_KERN_LEVEL", + "printk() should include KERN_<LEVEL> facility level\n" . $herecurr); + } + + if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { + my $orig = $1; + my $level = lc($orig); + $level = "warn" if ($level eq "warning"); + my $level2 = $level; + $level2 = "dbg" if ($level eq "debug"); + WARN("PREFER_PR_LEVEL", + "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); + } + + if ($line =~ /\bpr_warning\s*\(/) { + if (WARN("PREFER_PR_LEVEL", + "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ + s/\bpr_warning\b/pr_warn/; + } + } + + if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { + my $orig = $1; + my $level = lc($orig); + $level = "warn" if ($level eq "warning"); + $level = "dbg" if ($level eq "debug"); + WARN("PREFER_DEV_LEVEL", + "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); + } + +# ENOSYS means "bad syscall nr" and nothing else. This will have a small +# number of false positives, but assembly files are not checked, so at +# least the arch entry code will not trigger this warning. + if ($line =~ /\bENOSYS\b/) { + WARN("ENOSYS", + "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); + } + +# function brace can't be on same line, except for #defines of do while, +# or if closed on same line + if ($perl_version_ok && + $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && + $sline !~ /\#\s*define\b.*do\s*\{/ && + $sline !~ /}/) { + if (ERROR("OPEN_BRACE", + "open brace '{' following function definitions go on the next line\n" . $herecurr) && + $fix) { + fix_delete_line($fixlinenr, $rawline); + my $fixed_line = $rawline; + $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/; + my $line1 = $1; + my $line2 = $2; + fix_insert_line($fixlinenr, ltrim($line1)); + fix_insert_line($fixlinenr, "\+{"); + if ($line2 !~ /^\s*$/) { + fix_insert_line($fixlinenr, "\+\t" . trim($line2)); + } + } + } + +# open braces for enum, union and struct go on the same line. + if ($line =~ /^.\s*{/ && + $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { + if (ERROR("OPEN_BRACE", + "open brace '{' following $1 go on the same line\n" . $hereprev) && + $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { + fix_delete_line($fixlinenr - 1, $prevrawline); + fix_delete_line($fixlinenr, $rawline); + my $fixedline = rtrim($prevrawline) . " {"; + fix_insert_line($fixlinenr, $fixedline); + $fixedline = $rawline; + $fixedline =~ s/^(.\s*)\{\s*/$1\t/; + if ($fixedline !~ /^\+\s*$/) { + fix_insert_line($fixlinenr, $fixedline); + } + } + } + +# missing space after union, struct or enum definition + if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { + if (WARN("SPACING", + "missing space after $1 definition\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ + s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; + } + } + +# Function pointer declarations +# check spacing between type, funcptr, and args +# canonical declaration is "type (*funcptr)(args...)" + if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { + my $declare = $1; + my $pre_pointer_space = $2; + my $post_pointer_space = $3; + my $funcname = $4; + my $post_funcname_space = $5; + my $pre_args_space = $6; + +# the $Declare variable will capture all spaces after the type +# so check it for a missing trailing missing space but pointer return types +# don't need a space so don't warn for those. + my $post_declare_space = ""; + if ($declare =~ /(\s+)$/) { + $post_declare_space = $1; + $declare = rtrim($declare); + } + if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { + WARN("SPACING", + "missing space after return type\n" . $herecurr); + $post_declare_space = " "; + } + +# unnecessary space "type (*funcptr)(args...)" +# This test is not currently implemented because these declarations are +# equivalent to +# int foo(int bar, ...) +# and this is form shouldn't/doesn't generate a checkpatch warning. +# +# elsif ($declare =~ /\s{2,}$/) { +# WARN("SPACING", +# "Multiple spaces after return type\n" . $herecurr); +# } + +# unnecessary space "type ( *funcptr)(args...)" + if (defined $pre_pointer_space && + $pre_pointer_space =~ /^\s/) { + WARN("SPACING", + "Unnecessary space after function pointer open parenthesis\n" . $herecurr); + } + +# unnecessary space "type (* funcptr)(args...)" + if (defined $post_pointer_space && + $post_pointer_space =~ /^\s/) { + WARN("SPACING", + "Unnecessary space before function pointer name\n" . $herecurr); + } + +# unnecessary space "type (*funcptr )(args...)" + if (defined $post_funcname_space && + $post_funcname_space =~ /^\s/) { + WARN("SPACING", + "Unnecessary space after function pointer name\n" . $herecurr); + } + +# unnecessary space "type (*funcptr) (args...)" + if (defined $pre_args_space && + $pre_args_space =~ /^\s/) { + WARN("SPACING", + "Unnecessary space before function pointer arguments\n" . $herecurr); + } + + if (show_type("SPACING") && $fix) { + $fixed[$fixlinenr] =~ + s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; + } + } + +# check for spacing round square brackets; allowed: +# 1. with a type on the left -- int [] a; +# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, +# 3. inside a curly brace -- = { [0...10] = 5 } + while ($line =~ /(.*?\s)\[/g) { + my ($where, $prefix) = ($-[1], $1); + if ($prefix !~ /$Type\s+$/ && + ($where != 0 || $prefix !~ /^.\s+$/) && + $prefix !~ /[{,:]\s+$/) { + if (ERROR("BRACKET_SPACE", + "space prohibited before open square bracket '['\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ + s/^(\+.*?)\s+\[/$1\[/; + } + } + } + +# check for spaces between functions and their parentheses. + while ($line =~ /($Ident)\s+\(/g) { + my $name = $1; + my $ctx_before = substr($line, 0, $-[1]); + my $ctx = "$ctx_before$name"; + + # Ignore those directives where spaces _are_ permitted. + if ($name =~ /^(?: + if|for|while|switch|return|case| + volatile|__volatile__| + __attribute__|format|__extension__| + asm|__asm__)$/x) + { + # cpp #define statements have non-optional spaces, ie + # if there is a space between the name and the open + # parenthesis it is simply not a parameter group. + } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { + + # cpp #elif statement condition may start with a ( + } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { + + # If this whole things ends with a type its most + # likely a typedef for a function. + } elsif ($ctx =~ /$Type$/) { + + } else { + if (WARN("SPACING", + "space prohibited between function name and open parenthesis '('\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ + s/\b$name\s+\(/$name\(/; + } + } + } + +# Check operator spacing. + if (!($line=~/\#\s*include/)) { + my $fixed_line = ""; + my $line_fixed = 0; + + my $ops = qr{ + <<=|>>=|<=|>=|==|!=| + \+=|-=|\*=|\/=|%=|\^=|\|=|&=| + =>|->|<<|>>|<|>|=|!|~| + &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| + \?:|\?|: + }x; + my @elements = split(/($ops|;)/, $opline); + +## print("element count: <" . $#elements . ">\n"); +## foreach my $el (@elements) { +## print("el: <$el>\n"); +## } + + my @fix_elements = (); + my $off = 0; + + foreach my $el (@elements) { + push(@fix_elements, substr($rawline, $off, length($el))); + $off += length($el); + } + + $off = 0; + + my $blank = copy_spacing($opline); + my $last_after = -1; + + for (my $n = 0; $n < $#elements; $n += 2) { + + my $good = $fix_elements[$n] . $fix_elements[$n + 1]; + +## print("n: <$n> good: <$good>\n"); + + $off += length($elements[$n]); + + # Pick up the preceding and succeeding characters. + my $ca = substr($opline, 0, $off); + my $cc = ''; + if (length($opline) >= ($off + length($elements[$n + 1]))) { + $cc = substr($opline, $off + length($elements[$n + 1])); + } + my $cb = "$ca$;$cc"; + + my $a = ''; + $a = 'V' if ($elements[$n] ne ''); + $a = 'W' if ($elements[$n] =~ /\s$/); + $a = 'C' if ($elements[$n] =~ /$;$/); + $a = 'B' if ($elements[$n] =~ /(\[|\()$/); + $a = 'O' if ($elements[$n] eq ''); + $a = 'E' if ($ca =~ /^\s*$/); + + my $op = $elements[$n + 1]; + + my $c = ''; + if (defined $elements[$n + 2]) { + $c = 'V' if ($elements[$n + 2] ne ''); + $c = 'W' if ($elements[$n + 2] =~ /^\s/); + $c = 'C' if ($elements[$n + 2] =~ /^$;/); + $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); + $c = 'O' if ($elements[$n + 2] eq ''); + $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); + } else { + $c = 'E'; + } + + my $ctx = "${a}x${c}"; + + my $at = "(ctx:$ctx)"; + + my $ptr = substr($blank, 0, $off) . "^"; + my $hereptr = "$hereline$ptr\n"; + + # Pull out the value of this operator. + my $op_type = substr($curr_values, $off + 1, 1); + + # Get the full operator variant. + my $opv = $op . substr($curr_vars, $off, 1); + + # Ignore operators passed as parameters. + if ($op_type ne 'V' && + $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { + +# # Ignore comments +# } elsif ($op =~ /^$;+$/) { + + # ; should have either the end of line or a space or \ after it + } elsif ($op eq ';') { + if ($ctx !~ /.x[WEBC]/ && + $cc !~ /^\\/ && $cc !~ /^;/) { + if (ERROR("SPACING", + "space required after that '$op' $at\n" . $hereptr)) { + $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; + $line_fixed = 1; + } + } + + # // is a comment + } elsif ($op eq '//') { + + # : when part of a bitfield + } elsif ($opv eq ':B') { + # skip the bitfield test for now + + # No spaces for: + # -> + } elsif ($op eq '->') { + if ($ctx =~ /Wx.|.xW/) { + if (ERROR("SPACING", + "spaces prohibited around that '$op' $at\n" . $hereptr)) { + $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); + if (defined $fix_elements[$n + 2]) { + $fix_elements[$n + 2] =~ s/^\s+//; + } + $line_fixed = 1; + } + } + + # , must not have a space before and must have a space on the right. + } elsif ($op eq ',') { + my $rtrim_before = 0; + my $space_after = 0; + if ($ctx =~ /Wx./) { + if (ERROR("SPACING", + "space prohibited before that '$op' $at\n" . $hereptr)) { + $line_fixed = 1; + $rtrim_before = 1; + } + } + if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { + if (ERROR("SPACING", + "space required after that '$op' $at\n" . $hereptr)) { + $line_fixed = 1; + $last_after = $n; + $space_after = 1; + } + } + if ($rtrim_before || $space_after) { + if ($rtrim_before) { + $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); + } else { + $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); + } + if ($space_after) { + $good .= " "; + } + } + + # '*' as part of a type definition -- reported already. + } elsif ($opv eq '*_') { + #warn "'*' is part of type\n"; + + # unary operators should have a space before and + # none after. May be left adjacent to another + # unary operator, or a cast + } elsif ($op eq '!' || $op eq '~' || + $opv eq '*U' || $opv eq '-U' || + $opv eq '&U' || $opv eq '&&U') { + if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { + if (ERROR("SPACING", + "space required before that '$op' $at\n" . $hereptr)) { + if ($n != $last_after + 2) { + $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); + $line_fixed = 1; + } + } + } + if ($op eq '*' && $cc =~/\s*$Modifier\b/) { + # A unary '*' may be const + + } elsif ($ctx =~ /.xW/) { + if (ERROR("SPACING", + "space prohibited after that '$op' $at\n" . $hereptr)) { + $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); + if (defined $fix_elements[$n + 2]) { + $fix_elements[$n + 2] =~ s/^\s+//; + } + $line_fixed = 1; + } + } + + # unary ++ and unary -- are allowed no space on one side. + } elsif ($op eq '++' or $op eq '--') { + if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { + if (ERROR("SPACING", + "space required one side of that '$op' $at\n" . $hereptr)) { + $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; + $line_fixed = 1; + } + } + if ($ctx =~ /Wx[BE]/ || + ($ctx =~ /Wx./ && $cc =~ /^;/)) { + if (ERROR("SPACING", + "space prohibited before that '$op' $at\n" . $hereptr)) { + $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); + $line_fixed = 1; + } + } + if ($ctx =~ /ExW/) { + if (ERROR("SPACING", + "space prohibited after that '$op' $at\n" . $hereptr)) { + $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); + if (defined $fix_elements[$n + 2]) { + $fix_elements[$n + 2] =~ s/^\s+//; + } + $line_fixed = 1; + } + } + + # << and >> may either have or not have spaces both sides + } elsif ($op eq '<<' or $op eq '>>' or + $op eq '&' or $op eq '^' or $op eq '|' or + $op eq '+' or $op eq '-' or + $op eq '*' or $op eq '/' or + $op eq '%') + { + if ($check) { + if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { + if (CHK("SPACING", + "spaces preferred around that '$op' $at\n" . $hereptr)) { + $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; + $fix_elements[$n + 2] =~ s/^\s+//; + $line_fixed = 1; + } + } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { + if (CHK("SPACING", + "space preferred before that '$op' $at\n" . $hereptr)) { + $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); + $line_fixed = 1; + } + } + } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { + if (ERROR("SPACING", + "need consistent spacing around '$op' $at\n" . $hereptr)) { + $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; + if (defined $fix_elements[$n + 2]) { + $fix_elements[$n + 2] =~ s/^\s+//; + } + $line_fixed = 1; + } + } + + # A colon needs no spaces before when it is + # terminating a case value or a label. + } elsif ($opv eq ':C' || $opv eq ':L') { + if ($ctx =~ /Wx./) { + if (ERROR("SPACING", + "space prohibited before that '$op' $at\n" . $hereptr)) { + $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); + $line_fixed = 1; + } + } + + # All the others need spaces both sides. + } elsif ($ctx !~ /[EWC]x[CWE]/) { + my $ok = 0; + + # Ignore email addresses <foo@bar> + if (($op eq '<' && + $cc =~ /^\S+\@\S+>/) || + ($op eq '>' && + $ca =~ /<\S+\@\S+$/)) + { + $ok = 1; + } + + # for asm volatile statements + # ignore a colon with another + # colon immediately before or after + if (($op eq ':') && + ($ca =~ /:$/ || $cc =~ /^:/)) { + $ok = 1; + } + + # messages are ERROR, but ?: are CHK + if ($ok == 0) { + my $msg_level = \&ERROR; + $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); + + if (&{$msg_level}("SPACING", + "spaces required around that '$op' $at\n" . $hereptr)) { + $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; + if (defined $fix_elements[$n + 2]) { + $fix_elements[$n + 2] =~ s/^\s+//; + } + $line_fixed = 1; + } + } + } + $off += length($elements[$n + 1]); + +## print("n: <$n> GOOD: <$good>\n"); + + $fixed_line = $fixed_line . $good; + } + + if (($#elements % 2) == 0) { + $fixed_line = $fixed_line . $fix_elements[$#elements]; + } + + if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { + $fixed[$fixlinenr] = $fixed_line; + } + + + } + +# check for whitespace before a non-naked semicolon + if ($line =~ /^\+.*\S\s+;\s*$/) { + if (WARN("SPACING", + "space prohibited before semicolon\n" . $herecurr) && + $fix) { + 1 while $fixed[$fixlinenr] =~ + s/^(\+.*\S)\s+;/$1;/; + } + } + +# check for multiple assignments + if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { + CHK("MULTIPLE_ASSIGNMENTS", + "multiple assignments should be avoided\n" . $herecurr); + } + +## # check for multiple declarations, allowing for a function declaration +## # continuation. +## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && +## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { +## +## # Remove any bracketed sections to ensure we do not +## # falsly report the parameters of functions. +## my $ln = $line; +## while ($ln =~ s/\([^\(\)]*\)//g) { +## } +## if ($ln =~ /,/) { +## WARN("MULTIPLE_DECLARATION", +## "declaring multiple variables together should be avoided\n" . $herecurr); +## } +## } + +#need space before brace following if, while, etc + if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || + $line =~ /\b(?:else|do)\{/) { + if (ERROR("SPACING", + "space required before the open brace '{'\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/; + } + } + +## # check for blank lines before declarations +## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && +## $prevrawline =~ /^.\s*$/) { +## WARN("SPACING", +## "No blank lines before declarations\n" . $hereprev); +## } +## + +# closing brace should have a space following it when it has anything +# on the line + if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { + if (ERROR("SPACING", + "space required after that close brace '}'\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ + s/}((?!(?:,|;|\)))\S)/} $1/; + } + } + +# check spacing on square brackets + if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { + if (ERROR("SPACING", + "space prohibited after that open square bracket '['\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ + s/\[\s+/\[/; + } + } + if ($line =~ /\s\]/) { + if (ERROR("SPACING", + "space prohibited before that close square bracket ']'\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ + s/\s+\]/\]/; + } + } + +# check spacing on parentheses + if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && + $line !~ /for\s*\(\s+;/) { + if (ERROR("SPACING", + "space prohibited after that open parenthesis '('\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ + s/\(\s+/\(/; + } + } + if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && + $line !~ /for\s*\(.*;\s+\)/ && + $line !~ /:\s+\)/) { + if (ERROR("SPACING", + "space prohibited before that close parenthesis ')'\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ + s/\s+\)/\)/; + } + } + +# check unnecessary parentheses around addressof/dereference single $Lvals +# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar + + while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { + my $var = $1; + if (CHK("UNNECESSARY_PARENTHESES", + "Unnecessary parentheses around $var\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; + } + } + +# check for unnecessary parentheses around function pointer uses +# ie: (foo->bar)(); should be foo->bar(); +# but not "if (foo->bar) (" to avoid some false positives + if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { + my $var = $2; + if (CHK("UNNECESSARY_PARENTHESES", + "Unnecessary parentheses around function pointer $var\n" . $herecurr) && + $fix) { + my $var2 = deparenthesize($var); + $var2 =~ s/\s//g; + $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; + } + } + +# check for unnecessary parentheses around comparisons in if uses +# when !drivers/staging or command-line uses --strict + if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) && + $perl_version_ok && defined($stat) && + $stat =~ /(^.\s*if\s*($balanced_parens))/) { + my $if_stat = $1; + my $test = substr($2, 1, -1); + my $herectx; + while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) { + my $match = $1; + # avoid parentheses around potential macro args + next if ($match =~ /^\s*\w+\s*$/); + if (!defined($herectx)) { + $herectx = $here . "\n"; + my $cnt = statement_rawlines($if_stat); + for (my $n = 0; $n < $cnt; $n++) { + my $rl = raw_line($linenr, $n); + $herectx .= $rl . "\n"; + last if $rl =~ /^[ \+].*\{/; + } + } + CHK("UNNECESSARY_PARENTHESES", + "Unnecessary parentheses around '$match'\n" . $herectx); + } + } + +#goto labels aren't indented, allow a single space however + if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and + !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { + if (WARN("INDENTED_LABEL", + "labels should not be indented\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ + s/^(.)\s+/$1/; + } + } + +# return is not a function + if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { + my $spacing = $1; + if ($perl_version_ok && + $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { + my $value = $1; + $value = deparenthesize($value); + if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { + ERROR("RETURN_PARENTHESES", + "return is not a function, parentheses are not required\n" . $herecurr); + } + } elsif ($spacing !~ /\s+/) { + ERROR("SPACING", + "space required before the open parenthesis '('\n" . $herecurr); + } + } + +# unnecessary return in a void function +# at end-of-function, with the previous line a single leading tab, then return; +# and the line before that not a goto label target like "out:" + if ($sline =~ /^[ \+]}\s*$/ && + $prevline =~ /^\+\treturn\s*;\s*$/ && + $linenr >= 3 && + $lines[$linenr - 3] =~ /^[ +]/ && + $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { + WARN("RETURN_VOID", + "void function return statements are not generally useful\n" . $hereprev); + } + +# if statements using unnecessary parentheses - ie: if ((foo == bar)) + if ($perl_version_ok && + $line =~ /\bif\s*((?:\(\s*){2,})/) { + my $openparens = $1; + my $count = $openparens =~ tr@\(@\(@; + my $msg = ""; + if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { + my $comp = $4; #Not $1 because of $LvalOrFunc + $msg = " - maybe == should be = ?" if ($comp eq "=="); + WARN("UNNECESSARY_PARENTHESES", + "Unnecessary parentheses$msg\n" . $herecurr); + } + } + +# comparisons with a constant or upper case identifier on the left +# avoid cases like "foo + BAR < baz" +# only fix matches surrounded by parentheses to avoid incorrect +# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" + if ($perl_version_ok && + $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { + my $lead = $1; + my $const = $2; + my $comp = $3; + my $to = $4; + my $newcomp = $comp; + if ($lead !~ /(?:$Operators|\.)\s*$/ && + $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && + WARN("CONSTANT_COMPARISON", + "Comparisons should place the constant on the right side of the test\n" . $herecurr) && + $fix) { + if ($comp eq "<") { + $newcomp = ">"; + } elsif ($comp eq "<=") { + $newcomp = ">="; + } elsif ($comp eq ">") { + $newcomp = "<"; + } elsif ($comp eq ">=") { + $newcomp = "<="; + } + $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; + } + } + +# Return of what appears to be an errno should normally be negative + if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { + my $name = $1; + if ($name ne 'EOF' && $name ne 'ERROR') { + WARN("USE_NEGATIVE_ERRNO", + "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); + } + } + +# Need a space before open parenthesis after if, while etc + if ($line =~ /\b(if|while|for|switch)\(/) { + if (ERROR("SPACING", + "space required before the open parenthesis '('\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ + s/\b(if|while|for|switch)\(/$1 \(/; + } + } + +# Check for illegal assignment in if conditional -- and check for trailing +# statements after the conditional. + if ($line =~ /do\s*(?!{)/) { + ($stat, $cond, $line_nr_next, $remain_next, $off_next) = + ctx_statement_block($linenr, $realcnt, 0) + if (!defined $stat); + my ($stat_next) = ctx_statement_block($line_nr_next, + $remain_next, $off_next); + $stat_next =~ s/\n./\n /g; + ##print "stat<$stat> stat_next<$stat_next>\n"; + + if ($stat_next =~ /^\s*while\b/) { + # If the statement carries leading newlines, + # then count those as offsets. + my ($whitespace) = + ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); + my $offset = + statement_rawlines($whitespace) - 1; + + $suppress_whiletrailers{$line_nr_next + + $offset} = 1; + } + } + if (!defined $suppress_whiletrailers{$linenr} && + defined($stat) && defined($cond) && + $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { + my ($s, $c) = ($stat, $cond); + + if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { + ERROR("ASSIGN_IN_IF", + "do not use assignment in if condition\n" . $herecurr); + } + + # Find out what is on the end of the line after the + # conditional. + substr($s, 0, length($c), ''); + $s =~ s/\n.*//g; + $s =~ s/$;//g; # Remove any comments + if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && + $c !~ /}\s*while\s*/) + { + # Find out how long the conditional actually is. + my @newlines = ($c =~ /\n/gs); + my $cond_lines = 1 + $#newlines; + my $stat_real = ''; + + $stat_real = raw_line($linenr, $cond_lines) + . "\n" if ($cond_lines); + if (defined($stat_real) && $cond_lines > 1) { + $stat_real = "[...]\n$stat_real"; + } + + ERROR("TRAILING_STATEMENTS", + "trailing statements should be on next line\n" . $herecurr . $stat_real); + } + } + +# Check for bitwise tests written as boolean + if ($line =~ / + (?: + (?:\[|\(|\&\&|\|\|) + \s*0[xX][0-9]+\s* + (?:\&\&|\|\|) + | + (?:\&\&|\|\|) + \s*0[xX][0-9]+\s* + (?:\&\&|\|\||\)|\]) + )/x) + { + WARN("HEXADECIMAL_BOOLEAN_TEST", + "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); + } + +# if and else should not have general statements after it + if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { + my $s = $1; + $s =~ s/$;//g; # Remove any comments + if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { + ERROR("TRAILING_STATEMENTS", + "trailing statements should be on next line\n" . $herecurr); + } + } +# if should not continue a brace + if ($line =~ /}\s*if\b/) { + ERROR("TRAILING_STATEMENTS", + "trailing statements should be on next line (or did you mean 'else if'?)\n" . + $herecurr); + } +# case and default should not have general statements after them + if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && + $line !~ /\G(?: + (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| + \s*return\s+ + )/xg) + { + ERROR("TRAILING_STATEMENTS", + "trailing statements should be on next line\n" . $herecurr); + } + + # Check for }<nl>else {, these must be at the same + # indent level to be relevant to each other. + if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && + $previndent == $indent) { + if (ERROR("ELSE_AFTER_BRACE", + "else should follow close brace '}'\n" . $hereprev) && + $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { + fix_delete_line($fixlinenr - 1, $prevrawline); + fix_delete_line($fixlinenr, $rawline); + my $fixedline = $prevrawline; + $fixedline =~ s/}\s*$//; + if ($fixedline !~ /^\+\s*$/) { + fix_insert_line($fixlinenr, $fixedline); + } + $fixedline = $rawline; + $fixedline =~ s/^(.\s*)else/$1} else/; + fix_insert_line($fixlinenr, $fixedline); + } + } + + if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && + $previndent == $indent) { + my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); + + # Find out what is on the end of the line after the + # conditional. + substr($s, 0, length($c), ''); + $s =~ s/\n.*//g; + + if ($s =~ /^\s*;/) { + if (ERROR("WHILE_AFTER_BRACE", + "while should follow close brace '}'\n" . $hereprev) && + $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { + fix_delete_line($fixlinenr - 1, $prevrawline); + fix_delete_line($fixlinenr, $rawline); + my $fixedline = $prevrawline; + my $trailing = $rawline; + $trailing =~ s/^\+//; + $trailing = trim($trailing); + $fixedline =~ s/}\s*$/} $trailing/; + fix_insert_line($fixlinenr, $fixedline); + } + } + } + +#Specific variable tests + while ($line =~ m{($Constant|$Lval)}g) { + my $var = $1; + +#CamelCase + if ($var !~ /^$Constant$/ && + $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && +#Ignore Page<foo> variants + $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && +#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show) + $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ && +#Ignore some three character SI units explicitly, like MiB and KHz + $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { + while ($var =~ m{($Ident)}g) { + my $word = $1; + next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); + if ($check) { + seed_camelcase_includes(); + if (!$file && !$camelcase_file_seeded) { + seed_camelcase_file($realfile); + $camelcase_file_seeded = 1; + } + } + if (!defined $camelcase{$word}) { + $camelcase{$word} = 1; + CHK("CAMELCASE", + "Avoid CamelCase: <$word>\n" . $herecurr); + } + } + } + } + +#no spaces allowed after \ in define + if ($line =~ /\#\s*define.*\\\s+$/) { + if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", + "Whitespace after \\ makes next lines useless\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\s+$//; + } + } + +# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes +# itself <asm/foo.h> (uses RAW line) + if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { + my $file = "$1.h"; + my $checkfile = "include/linux/$file"; + if (-f "$root/$checkfile" && + $realfile ne $checkfile && + $1 !~ /$allowed_asm_includes/) + { + my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; + if ($asminclude > 0) { + if ($realfile =~ m{^arch/}) { + CHK("ARCH_INCLUDE_LINUX", + "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); + } else { + WARN("INCLUDE_LINUX", + "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); + } + } + } + } + +# multi-statement macros should be enclosed in a do while loop, grab the +# first statement and ensure its the whole macro if its not enclosed +# in a known good container + if ($realfile !~ m@/vmlinux.lds.h$@ && + $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { + my $ln = $linenr; + my $cnt = $realcnt; + my ($off, $dstat, $dcond, $rest); + my $ctx = ''; + my $has_flow_statement = 0; + my $has_arg_concat = 0; + ($dstat, $dcond, $ln, $cnt, $off) = + ctx_statement_block($linenr, $realcnt, 0); + $ctx = $dstat; + #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; + #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; + + $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); + $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); + + $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; + my $define_args = $1; + my $define_stmt = $dstat; + my @def_args = (); + + if (defined $define_args && $define_args ne "") { + $define_args = substr($define_args, 1, length($define_args) - 2); + $define_args =~ s/\s*//g; + $define_args =~ s/\\\+?//g; + @def_args = split(",", $define_args); + } + + $dstat =~ s/$;//g; + $dstat =~ s/\\\n.//g; + $dstat =~ s/^\s*//s; + $dstat =~ s/\s*$//s; + + # Flatten any parentheses and braces + while ($dstat =~ s/\([^\(\)]*\)/1/ || + $dstat =~ s/\{[^\{\}]*\}/1/ || + $dstat =~ s/.\[[^\[\]]*\]/1/) + { + } + + # Flatten any obvious string concatentation. + while ($dstat =~ s/($String)\s*$Ident/$1/ || + $dstat =~ s/$Ident\s*($String)/$1/) + { + } + + # Make asm volatile uses seem like a generic function + $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; + + my $exceptions = qr{ + $Declare| + module_param_named| + MODULE_PARM_DESC| + DECLARE_PER_CPU| + DEFINE_PER_CPU| + __typeof__\(| + union| + struct| + \.$Ident\s*=\s*| + ^\"|\"$| + ^\[ + }x; + #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; + + $ctx =~ s/\n*$//; + my $stmt_cnt = statement_rawlines($ctx); + my $herectx = get_stat_here($linenr, $stmt_cnt, $here); + + if ($dstat ne '' && + $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), + $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); + $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz + $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants + $dstat !~ /$exceptions/ && + $dstat !~ /^\.$Ident\s*=/ && # .foo = + $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo + $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) + $dstat !~ /^for\s*$Constant$/ && # for (...) + $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() + $dstat !~ /^do\s*{/ && # do {... + $dstat !~ /^\(\{/ && # ({... + $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) + { + if ($dstat =~ /^\s*if\b/) { + ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", + "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); + } elsif ($dstat =~ /;/) { + ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", + "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); + } else { + ERROR("COMPLEX_MACRO", + "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); + } + + } + + # Make $define_stmt single line, comment-free, etc + my @stmt_array = split('\n', $define_stmt); + my $first = 1; + $define_stmt = ""; + foreach my $l (@stmt_array) { + $l =~ s/\\$//; + if ($first) { + $define_stmt = $l; + $first = 0; + } elsif ($l =~ /^[\+ ]/) { + $define_stmt .= substr($l, 1); + } + } + $define_stmt =~ s/$;//g; + $define_stmt =~ s/\s+/ /g; + $define_stmt = trim($define_stmt); + +# check if any macro arguments are reused (ignore '...' and 'type') + foreach my $arg (@def_args) { + next if ($arg =~ /\.\.\./); + next if ($arg =~ /^type$/i); + my $tmp_stmt = $define_stmt; + $tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; + $tmp_stmt =~ s/\#+\s*$arg\b//g; + $tmp_stmt =~ s/\b$arg\s*\#\#//g; + my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; + if ($use_cnt > 1) { + CHK("MACRO_ARG_REUSE", + "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); + } +# check if any macro arguments may have other precedence issues + if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && + ((defined($1) && $1 ne ',') || + (defined($2) && $2 ne ','))) { + CHK("MACRO_ARG_PRECEDENCE", + "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); + } + } + +# check for macros with flow control, but without ## concatenation +# ## concatenation is commonly a macro that defines a function so ignore those + if ($has_flow_statement && !$has_arg_concat) { + my $cnt = statement_rawlines($ctx); + my $herectx = get_stat_here($linenr, $cnt, $here); + + WARN("MACRO_WITH_FLOW_CONTROL", + "Macros with flow control statements should be avoided\n" . "$herectx"); + } + +# check for line continuations outside of #defines, preprocessor #, and asm + + } else { + if ($prevline !~ /^..*\\$/ && + $line !~ /^\+\s*\#.*\\$/ && # preprocessor + $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm + $line =~ /^\+.*\\$/) { + WARN("LINE_CONTINUATIONS", + "Avoid unnecessary line continuations\n" . $herecurr); + } + } + +# do {} while (0) macro tests: +# single-statement macros do not need to be enclosed in do while (0) loop, +# macro should not end with a semicolon + if ($perl_version_ok && + $realfile !~ m@/vmlinux.lds.h$@ && + $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { + my $ln = $linenr; + my $cnt = $realcnt; + my ($off, $dstat, $dcond, $rest); + my $ctx = ''; + ($dstat, $dcond, $ln, $cnt, $off) = + ctx_statement_block($linenr, $realcnt, 0); + $ctx = $dstat; + + $dstat =~ s/\\\n.//g; + $dstat =~ s/$;/ /g; + + if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { + my $stmts = $2; + my $semis = $3; + + $ctx =~ s/\n*$//; + my $cnt = statement_rawlines($ctx); + my $herectx = get_stat_here($linenr, $cnt, $here); + + if (($stmts =~ tr/;/;/) == 1 && + $stmts !~ /^\s*(if|while|for|switch)\b/) { + WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", + "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); + } + if (defined $semis && $semis ne "") { + WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", + "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); + } + } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { + $ctx =~ s/\n*$//; + my $cnt = statement_rawlines($ctx); + my $herectx = get_stat_here($linenr, $cnt, $here); + + WARN("TRAILING_SEMICOLON", + "macros should not use a trailing semicolon\n" . "$herectx"); + } + } + +# check for redundant bracing round if etc + if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { + my ($level, $endln, @chunks) = + ctx_statement_full($linenr, $realcnt, 1); + #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; + #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; + if ($#chunks > 0 && $level == 0) { + my @allowed = (); + my $allow = 0; + my $seen = 0; + my $herectx = $here . "\n"; + my $ln = $linenr - 1; + for my $chunk (@chunks) { + my ($cond, $block) = @{$chunk}; + + # If the condition carries leading newlines, then count those as offsets. + my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); + my $offset = statement_rawlines($whitespace) - 1; + + $allowed[$allow] = 0; + #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; + + # We have looked at and allowed this specific line. + $suppress_ifbraces{$ln + $offset} = 1; + + $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; + $ln += statement_rawlines($block) - 1; + + substr($block, 0, length($cond), ''); + + $seen++ if ($block =~ /^\s*{/); + + #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; + if (statement_lines($cond) > 1) { + #print "APW: ALLOWED: cond<$cond>\n"; + $allowed[$allow] = 1; + } + if ($block =~/\b(?:if|for|while)\b/) { + #print "APW: ALLOWED: block<$block>\n"; + $allowed[$allow] = 1; + } + if (statement_block_size($block) > 1) { + #print "APW: ALLOWED: lines block<$block>\n"; + $allowed[$allow] = 1; + } + $allow++; + } + if ($seen) { + my $sum_allowed = 0; + foreach (@allowed) { + $sum_allowed += $_; + } + if ($sum_allowed == 0) { + WARN("BRACES", + "braces {} are not necessary for any arm of this statement\n" . $herectx); + } elsif ($sum_allowed != $allow && + $seen != $allow) { + CHK("BRACES", + "braces {} should be used on all arms of this statement\n" . $herectx); + } + } + } + } + if (!defined $suppress_ifbraces{$linenr - 1} && + $line =~ /\b(if|while|for|else)\b/) { + my $allowed = 0; + + # Check the pre-context. + if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { + #print "APW: ALLOWED: pre<$1>\n"; + $allowed = 1; + } + + my ($level, $endln, @chunks) = + ctx_statement_full($linenr, $realcnt, $-[0]); + + # Check the condition. + my ($cond, $block) = @{$chunks[0]}; + #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; + if (defined $cond) { + substr($block, 0, length($cond), ''); + } + if (statement_lines($cond) > 1) { + #print "APW: ALLOWED: cond<$cond>\n"; + $allowed = 1; + } + if ($block =~/\b(?:if|for|while)\b/) { + #print "APW: ALLOWED: block<$block>\n"; + $allowed = 1; + } + if (statement_block_size($block) > 1) { + #print "APW: ALLOWED: lines block<$block>\n"; + $allowed = 1; + } + # Check the post-context. + if (defined $chunks[1]) { + my ($cond, $block) = @{$chunks[1]}; + if (defined $cond) { + substr($block, 0, length($cond), ''); + } + if ($block =~ /^\s*\{/) { + #print "APW: ALLOWED: chunk-1 block<$block>\n"; + $allowed = 1; + } + } + if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { + my $cnt = statement_rawlines($block); + my $herectx = get_stat_here($linenr, $cnt, $here); + + WARN("BRACES", + "braces {} are not necessary for single statement blocks\n" . $herectx); + } + } + +# check for single line unbalanced braces + if ($sline =~ /^.\s*\}\s*else\s*$/ || + $sline =~ /^.\s*else\s*\{\s*$/) { + CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); + } + +# check for unnecessary blank lines around braces + if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { + if (CHK("BRACES", + "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && + $fix && $prevrawline =~ /^\+/) { + fix_delete_line($fixlinenr - 1, $prevrawline); + } + } + if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { + if (CHK("BRACES", + "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && + $fix) { + fix_delete_line($fixlinenr, $rawline); + } + } + +# no volatiles please + my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; + if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { + WARN("VOLATILE", + "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); + } + +# Check for user-visible strings broken across lines, which breaks the ability +# to grep for the string. Make exceptions when the previous string ends in a +# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' +# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value + if ($line =~ /^\+\s*$String/ && + $prevline =~ /"\s*$/ && + $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { + if (WARN("SPLIT_STRING", + "quoted string split across lines\n" . $hereprev) && + $fix && + $prevrawline =~ /^\+.*"\s*$/ && + $last_coalesced_string_linenr != $linenr - 1) { + my $extracted_string = get_quoted_string($line, $rawline); + my $comma_close = ""; + if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { + $comma_close = $1; + } + + fix_delete_line($fixlinenr - 1, $prevrawline); + fix_delete_line($fixlinenr, $rawline); + my $fixedline = $prevrawline; + $fixedline =~ s/"\s*$//; + $fixedline .= substr($extracted_string, 1) . trim($comma_close); + fix_insert_line($fixlinenr - 1, $fixedline); + $fixedline = $rawline; + $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; + if ($fixedline !~ /\+\s*$/) { + fix_insert_line($fixlinenr, $fixedline); + } + $last_coalesced_string_linenr = $linenr; + } + } + +# check for missing a space in a string concatenation + if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { + WARN('MISSING_SPACE', + "break quoted strings at a space character\n" . $hereprev); + } + +# check for an embedded function name in a string when the function is known +# This does not work very well for -f --file checking as it depends on patch +# context providing the function name or a single line form for in-file +# function declarations + if (!$SOF && + $line =~ /^\+.*$String/ && + defined($context_function) && + get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && + length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { + WARN("EMBEDDED_FUNCTION_NAME", + "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); + } + +# check for spaces before a quoted newline + if ($rawline =~ /^.*\".*\s\\n/) { + if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", + "unnecessary whitespace before a quoted newline\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; + } + + } + +# concatenated string without spaces between elements + if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) { + if (CHK("CONCATENATED_STRING", + "Concatenated strings should use spaces between elements\n" . $herecurr) && + $fix) { + while ($line =~ /($String)/g) { + my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); + $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/; + $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/; + } + } + } + +# uncoalesced string fragments + if ($line =~ /$String\s*"/) { + if (WARN("STRING_FRAGMENTS", + "Consecutive strings are generally better as a single string\n" . $herecurr) && + $fix) { + while ($line =~ /($String)(?=\s*")/g) { + my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); + $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e; + } + } + } + +# check for non-standard and hex prefixed decimal printf formats + my $show_L = 1; #don't show the same defect twice + my $show_Z = 1; + while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { + my $string = substr($rawline, $-[1], $+[1] - $-[1]); + $string =~ s/%%/__/g; + # check for %L + if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { + WARN("PRINTF_L", + "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); + $show_L = 0; + } + # check for %Z + if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { + WARN("PRINTF_Z", + "%Z$1 is non-standard C, use %z$1\n" . $herecurr); + $show_Z = 0; + } + # check for 0x<decimal> + if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { + ERROR("PRINTF_0XDECIMAL", + "Prefixing 0x with decimal output is defective\n" . $herecurr); + } + } + +# check for line continuations in quoted strings with odd counts of " + if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) { + WARN("LINE_CONTINUATIONS", + "Avoid line continuations in quoted strings\n" . $herecurr); + } + +# warn about #if 0 + if ($line =~ /^.\s*\#\s*if\s+0\b/) { + WARN("IF_0", + "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr); + } + +# warn about #if 1 + if ($line =~ /^.\s*\#\s*if\s+1\b/) { + WARN("IF_1", + "Consider removing the #if 1 and its #endif\n" . $herecurr); + } + +# check for needless "if (<foo>) fn(<foo>)" uses + if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { + my $tested = quotemeta($1); + my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; + if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { + my $func = $1; + if (WARN('NEEDLESS_IF', + "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && + $fix) { + my $do_fix = 1; + my $leading_tabs = ""; + my $new_leading_tabs = ""; + if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { + $leading_tabs = $1; + } else { + $do_fix = 0; + } + if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { + $new_leading_tabs = $1; + if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { + $do_fix = 0; + } + } else { + $do_fix = 0; + } + if ($do_fix) { + fix_delete_line($fixlinenr - 1, $prevrawline); + $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; + } + } + } + } + +# check for unnecessary "Out of Memory" messages + if ($line =~ /^\+.*\b$logFunctions\s*\(/ && + $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && + (defined $1 || defined $3) && + $linenr > 3) { + my $testval = $2; + my $testline = $lines[$linenr - 3]; + + my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); +# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); + + if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ && + $s !~ /\b__GFP_NOWARN\b/ ) { + WARN("OOM_MESSAGE", + "Possible unnecessary 'out of memory' message\n" . $hereprev); + } + } + +# check for logging functions with KERN_<LEVEL> + if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && + $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { + my $level = $1; + if (WARN("UNNECESSARY_KERN_LEVEL", + "Possible unnecessary $level\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\s*$level\s*//; + } + } + +# check for logging continuations + if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { + WARN("LOGGING_CONTINUATION", + "Avoid logging continuation uses where feasible\n" . $herecurr); + } + +# check for mask then right shift without a parentheses + if ($perl_version_ok && + $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && + $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so + WARN("MASK_THEN_SHIFT", + "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); + } + +# check for pointer comparisons to NULL + if ($perl_version_ok) { + while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { + my $val = $1; + my $equal = "!"; + $equal = "" if ($4 eq "!="); + if (CHK("COMPARISON_TO_NULL", + "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; + } + } + } + +# check for bad placement of section $InitAttribute (e.g.: __initdata) + if ($line =~ /(\b$InitAttribute\b)/) { + my $attr = $1; + if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { + my $ptr = $1; + my $var = $2; + if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && + ERROR("MISPLACED_INIT", + "$attr should be placed after $var\n" . $herecurr)) || + ($ptr !~ /\b(union|struct)\s+$attr\b/ && + WARN("MISPLACED_INIT", + "$attr should be placed after $var\n" . $herecurr))) && + $fix) { + $fixed[$fixlinenr] =~ s/(\bstatic\s+(?:const\s+)?)(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*([=;])\s*/"$1" . trim(string_find_replace($2, "\\s*$attr\\s*", " ")) . " " . trim(string_find_replace($3, "\\s*$attr\\s*", "")) . " $attr" . ("$4" eq ";" ? ";" : " = ")/e; + } + } + } + +# check for $InitAttributeData (ie: __initdata) with const + if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { + my $attr = $1; + $attr =~ /($InitAttributePrefix)(.*)/; + my $attr_prefix = $1; + my $attr_type = $2; + if (ERROR("INIT_ATTRIBUTE", + "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ + s/$InitAttributeData/${attr_prefix}initconst/; + } + } + +# check for $InitAttributeConst (ie: __initconst) without const + if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { + my $attr = $1; + if (ERROR("INIT_ATTRIBUTE", + "Use of $attr requires a separate use of const\n" . $herecurr) && + $fix) { + my $lead = $fixed[$fixlinenr] =~ + /(^\+\s*(?:static\s+))/; + $lead = rtrim($1); + $lead = "$lead " if ($lead !~ /^\+$/); + $lead = "${lead}const "; + $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; + } + } + +# check for __read_mostly with const non-pointer (should just be const) + if ($line =~ /\b__read_mostly\b/ && + $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { + if (ERROR("CONST_READ_MOSTLY", + "Invalid use of __read_mostly with const type\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; + } + } + +# don't use __constant_<foo> functions outside of include/uapi/ + if ($realfile !~ m@^include/uapi/@ && + $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { + my $constant_func = $1; + my $func = $constant_func; + $func =~ s/^__constant_//; + if (WARN("CONSTANT_CONVERSION", + "$constant_func should be $func\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; + } + } + +# prefer usleep_range over udelay + if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { + my $delay = $1; + # ignore udelay's < 10, however + if (! ($delay < 10) ) { + CHK("USLEEP_RANGE", + "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr); + } + if ($delay > 2000) { + WARN("LONG_UDELAY", + "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); + } + } + +# warn about unexpectedly long msleep's + if ($line =~ /\bmsleep\s*\((\d+)\);/) { + if ($1 < 20) { + WARN("MSLEEP", + "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr); + } + } + +# check for comparisons of jiffies + if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { + WARN("JIFFIES_COMPARISON", + "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); + } + +# check for comparisons of get_jiffies_64() + if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { + WARN("JIFFIES_COMPARISON", + "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); + } + +# warn about #ifdefs in C files +# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { +# print "#ifdef in C files should be avoided\n"; +# print "$herecurr"; +# $clean = 0; +# } + +# warn about spacing in #ifdefs + if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { + if (ERROR("SPACING", + "exactly one space required after that #$1\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ + s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; + } + + } + +# check for spinlock_t definitions without a comment. + if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || + $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { + my $which = $1; + if (!ctx_has_comment($first_line, $linenr)) { + CHK("UNCOMMENTED_DEFINITION", + "$1 definition without comment\n" . $herecurr); + } + } +# check for memory barriers without a comment. + + my $barriers = qr{ + mb| + rmb| + wmb| + read_barrier_depends + }x; + my $barrier_stems = qr{ + mb__before_atomic| + mb__after_atomic| + store_release| + load_acquire| + store_mb| + (?:$barriers) + }x; + my $all_barriers = qr{ + (?:$barriers)| + smp_(?:$barrier_stems)| + virt_(?:$barrier_stems) + }x; + + if ($line =~ /\b(?:$all_barriers)\s*\(/) { + if (!ctx_has_comment($first_line, $linenr)) { + WARN("MEMORY_BARRIER", + "memory barrier without comment\n" . $herecurr); + } + } + + my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; + + if ($realfile !~ m@^include/asm-generic/@ && + $realfile !~ m@/barrier\.h$@ && + $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && + $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { + WARN("MEMORY_BARRIER", + "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); + } + +# check for waitqueue_active without a comment. + if ($line =~ /\bwaitqueue_active\s*\(/) { + if (!ctx_has_comment($first_line, $linenr)) { + WARN("WAITQUEUE_ACTIVE", + "waitqueue_active without comment\n" . $herecurr); + } + } + +# check for smp_read_barrier_depends and read_barrier_depends + if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) { + WARN("READ_BARRIER_DEPENDS", + "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr); + } + +# check of hardware specific defines + if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { + CHK("ARCH_DEFINES", + "architecture specific defines should be avoided\n" . $herecurr); + } + +# check that the storage class is not after a type + if ($line =~ /\b($Type)\s+($Storage)\b/) { + WARN("STORAGE_CLASS", + "storage class '$2' should be located before type '$1'\n" . $herecurr); + } +# Check that the storage class is at the beginning of a declaration + if ($line =~ /\b$Storage\b/ && + $line !~ /^.\s*$Storage/ && + $line =~ /^.\s*(.+?)\$Storage\s/ && + $1 !~ /[\,\)]\s*$/) { + WARN("STORAGE_CLASS", + "storage class should be at the beginning of the declaration\n" . $herecurr); + } + +# check the location of the inline attribute, that it is between +# storage class and type. + if ($line =~ /\b$Type\s+$Inline\b/ || + $line =~ /\b$Inline\s+$Storage\b/) { + ERROR("INLINE_LOCATION", + "inline keyword should sit between storage class and type\n" . $herecurr); + } + +# Check for __inline__ and __inline, prefer inline + if ($realfile !~ m@\binclude/uapi/@ && + $line =~ /\b(__inline__|__inline)\b/) { + if (WARN("INLINE", + "plain inline is preferred over $1\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; + + } + } + +# Check for __attribute__ packed, prefer __packed + if ($realfile !~ m@\binclude/uapi/@ && + $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { + WARN("PREFER_PACKED", + "__packed is preferred over __attribute__((packed))\n" . $herecurr); + } + +# Check for __attribute__ aligned, prefer __aligned + if ($realfile !~ m@\binclude/uapi/@ && + $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { + WARN("PREFER_ALIGNED", + "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); + } + +# Check for __attribute__ section, prefer __section + if ($realfile !~ m@\binclude/uapi/@ && + $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) { + my $old = substr($rawline, $-[1], $+[1] - $-[1]); + my $new = substr($old, 1, -1); + if (WARN("PREFER_SECTION", + "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/; + } + } + +# Check for __attribute__ format(printf, prefer __printf + if ($realfile !~ m@\binclude/uapi/@ && + $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { + if (WARN("PREFER_PRINTF", + "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; + + } + } + +# Check for __attribute__ format(scanf, prefer __scanf + if ($realfile !~ m@\binclude/uapi/@ && + $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { + if (WARN("PREFER_SCANF", + "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; + } + } + +# Check for __attribute__ weak, or __weak declarations (may have link issues) + if ($perl_version_ok && + $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && + ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || + $line =~ /\b__weak\b/)) { + ERROR("WEAK_DECLARATION", + "Using weak declarations can have unintended link defects\n" . $herecurr); + } + +# check for c99 types like uint8_t used outside of uapi/ and tools/ + if (!$SOF && + $realfile !~ m@\binclude/uapi/@ && + $realfile !~ m@\btools/@ && + $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { + my $type = $1; + if ($type =~ /\b($typeC99Typedefs)\b/) { + $type = $1; + my $kernel_type = 'u'; + $kernel_type = 's' if ($type =~ /^_*[si]/); + $type =~ /(\d+)/; + $kernel_type .= $1; + if (CHK("PREFER_KERNEL_TYPES", + "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; + } + } + } + +# check for cast of C90 native int or longer types constants + if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { + my $cast = $1; + my $const = $2; + if (WARN("TYPECAST_INT_CONSTANT", + "Unnecessary typecast of c90 int constant\n" . $herecurr) && + $fix) { + my $suffix = ""; + my $newconst = $const; + $newconst =~ s/${Int_type}$//; + $suffix .= 'U' if ($cast =~ /\bunsigned\b/); + if ($cast =~ /\blong\s+long\b/) { + $suffix .= 'LL'; + } elsif ($cast =~ /\blong\b/) { + $suffix .= 'L'; + } + $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; + } + } + +# check for sizeof(&) + if ($line =~ /\bsizeof\s*\(\s*\&/) { + WARN("SIZEOF_ADDRESS", + "sizeof(& should be avoided\n" . $herecurr); + } + +# check for sizeof without parenthesis + if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { + if (WARN("SIZEOF_PARENTHESIS", + "sizeof $1 should be sizeof($1)\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; + } + } + +# check for struct spinlock declarations + if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { + WARN("USE_SPINLOCK_T", + "struct spinlock should be spinlock_t\n" . $herecurr); + } + +# check for seq_printf uses that could be seq_puts + if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { + my $fmt = get_quoted_string($line, $rawline); + $fmt =~ s/%%//g; + if ($fmt !~ /%/) { + if (WARN("PREFER_SEQ_PUTS", + "Prefer seq_puts to seq_printf\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; + } + } + } + +# check for memcpy uses that should be memcpy_s + if ($SOF && ($line =~ /memcpy\s*\(.*/)) { + my $fmt = get_quoted_string($line, $rawline); + $fmt =~ s/%%//g; + if ($fmt !~ /%/) { + if (WARN("PREFER_MEMCPY_S", + "Use safe version of memcpy - memcpy_s whenever possible\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/memcpy\b/memcpy_s/; + } + } + } + +# check for vsprintf extension %p<foo> misuses + if ($perl_version_ok && + defined $stat && + $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && + $1 !~ /^_*volatile_*$/) { + my $stat_real; + + my $lc = $stat =~ tr@\n@@; + $lc = $lc + $linenr; + for (my $count = $linenr; $count <= $lc; $count++) { + my $specifier; + my $extension; + my $bad_specifier = ""; + my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); + $fmt =~ s/%%//g; + + while ($fmt =~ /(\%[\*\d\.]*p(\w))/g) { + $specifier = $1; + $extension = $2; + if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOxt]/) { + $bad_specifier = $specifier; + last; + } + if ($extension eq "x" && !defined($stat_real)) { + if (!defined($stat_real)) { + $stat_real = get_stat_real($linenr, $lc); + } + WARN("VSPRINTF_SPECIFIER_PX", + "Using vsprintf specifier '\%px' potentially exposes the kernel memory layout, if you don't really need the address please consider using '\%p'.\n" . "$here\n$stat_real\n"); + } + } + if ($bad_specifier ne "") { + my $stat_real = get_stat_real($linenr, $lc); + my $ext_type = "Invalid"; + my $use = ""; + if ($bad_specifier =~ /p[Ff]/) { + $ext_type = "Deprecated"; + $use = " - use %pS instead"; + $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/); + } + + WARN("VSPRINTF_POINTER_EXTENSION", + "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); + } + } + } + +# Check for misused memsets + if ($perl_version_ok && + defined $stat && + $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { + + my $ms_addr = $2; + my $ms_val = $7; + my $ms_size = $12; + + if ($ms_size =~ /^(0x|)0$/i) { + ERROR("MEMSET", + "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); + } elsif ($ms_size =~ /^(0x|)1$/i) { + WARN("MEMSET", + "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); + } + } + +# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) +# if ($perl_version_ok && +# defined $stat && +# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { +# if (WARN("PREFER_ETHER_ADDR_COPY", +# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && +# $fix) { +# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; +# } +# } + +# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) +# if ($perl_version_ok && +# defined $stat && +# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { +# WARN("PREFER_ETHER_ADDR_EQUAL", +# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") +# } + +# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr +# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr +# if ($perl_version_ok && +# defined $stat && +# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { +# +# my $ms_val = $7; +# +# if ($ms_val =~ /^(?:0x|)0+$/i) { +# if (WARN("PREFER_ETH_ZERO_ADDR", +# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && +# $fix) { +# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; +# } +# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { +# if (WARN("PREFER_ETH_BROADCAST_ADDR", +# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && +# $fix) { +# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; +# } +# } +# } + +# typecasts on min/max could be min_t/max_t + if ($perl_version_ok && + defined $stat && + $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { + if (defined $2 || defined $7) { + my $call = $1; + my $cast1 = deparenthesize($2); + my $arg1 = $3; + my $cast2 = deparenthesize($7); + my $arg2 = $8; + my $cast; + + if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { + $cast = "$cast1 or $cast2"; + } elsif ($cast1 ne "") { + $cast = $cast1; + } else { + $cast = $cast2; + } + WARN("MINMAX", + "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); + } + } + +# check usleep_range arguments + if ($perl_version_ok && + defined $stat && + $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { + my $min = $1; + my $max = $7; + if ($min eq $max) { + WARN("USLEEP_RANGE", + "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); + } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && + $min > $max) { + WARN("USLEEP_RANGE", + "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); + } + } + +# check for naked sscanf + if ($perl_version_ok && + defined $stat && + $line =~ /\bsscanf\b/ && + ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && + $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && + $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { + my $lc = $stat =~ tr@\n@@; + $lc = $lc + $linenr; + my $stat_real = get_stat_real($linenr, $lc); + WARN("NAKED_SSCANF", + "unchecked sscanf return value\n" . "$here\n$stat_real\n"); + } + +# check for simple sscanf that should be kstrto<foo> + if ($perl_version_ok && + defined $stat && + $line =~ /\bsscanf\b/) { + my $lc = $stat =~ tr@\n@@; + $lc = $lc + $linenr; + my $stat_real = get_stat_real($linenr, $lc); + if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { + my $format = $6; + my $count = $format =~ tr@%@%@; + if ($count == 1 && + $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { + WARN("SSCANF_TO_KSTRTO", + "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); + } + } + } + +# check for new externs in .h files. + if ($realfile =~ /\.h$/ && + $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { + if (CHK("AVOID_EXTERNS", + "extern prototypes should be avoided in .h files\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; + } + } + +# check for new externs in .c files. + if ($realfile =~ /\.c$/ && defined $stat && + $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) + { + my $function_name = $1; + my $paren_space = $2; + + my $s = $stat; + if (defined $cond) { + substr($s, 0, length($cond), ''); + } + if ($s =~ /^\s*;/ && + $function_name ne 'uninitialized_var') + { + WARN("AVOID_EXTERNS", + "externs should be avoided in .c files\n" . $herecurr); + } + + if ($paren_space =~ /\n/) { + WARN("FUNCTION_ARGUMENTS", + "arguments for function declarations should follow identifier\n" . $herecurr); + } + + } elsif ($realfile =~ /\.c$/ && defined $stat && + $stat =~ /^.\s*extern\s+/) + { + WARN("AVOID_EXTERNS", + "externs should be avoided in .c files\n" . $herecurr); + } + +# check for function declarations that have arguments without identifier names + if (defined $stat && + $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && + $1 ne "void") { + my $args = trim($1); + while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { + my $arg = trim($1); + if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { + WARN("FUNCTION_ARGUMENTS", + "function definition argument '$arg' should also have an identifier name\n" . $herecurr); + } + } + } + +# check for function definitions + if ($perl_version_ok && + defined $stat && + $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { + $context_function = $1; + +# check for multiline function definition with misplaced open brace + my $ok = 0; + my $cnt = statement_rawlines($stat); + my $herectx = $here . "\n"; + for (my $n = 0; $n < $cnt; $n++) { + my $rl = raw_line($linenr, $n); + $herectx .= $rl . "\n"; + $ok = 1 if ($rl =~ /^[ \+]\{/); + $ok = 1 if ($rl =~ /\{/ && $n == 0); + last if $rl =~ /^[ \+].*\{/; + } + if (!$ok) { + ERROR("OPEN_BRACE", + "open brace '{' following function definitions go on the next line\n" . $herectx); + } + } + +# checks for new __setup's + if ($rawline =~ /\b__setup\("([^"]*)"/) { + my $name = $1; + + if (!grep(/$name/, @setup_docs)) { + CHK("UNDOCUMENTED_SETUP", + "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr); + } + } + +# check for pointless casting of alloc functions + if ($line =~ /\*\s*\)\s*$allocFunctions\b/) { + WARN("UNNECESSARY_CASTS", + "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); + } + +# alloc style +# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) + if ($perl_version_ok && + $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { + CHK("ALLOC_SIZEOF_STRUCT", + "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); + } + +# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc + if ($perl_version_ok && + defined $stat && + $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { + my $oldfunc = $3; + my $a1 = $4; + my $a2 = $10; + my $newfunc = "kmalloc_array"; + $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); + my $r1 = $a1; + my $r2 = $a2; + if ($a1 =~ /^sizeof\s*\S/) { + $r1 = $a2; + $r2 = $a1; + } + if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && + !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { + my $cnt = statement_rawlines($stat); + my $herectx = get_stat_here($linenr, $cnt, $here); + + if (WARN("ALLOC_WITH_MULTIPLY", + "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && + $cnt == 1 && + $fix) { + $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e; + } + } + } + +# check for krealloc arg reuse + if ($perl_version_ok && + $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ && + $1 eq $3) { + WARN("KREALLOC_ARG_REUSE", + "Reusing the krealloc arg is almost always a bug\n" . $herecurr); + } + +# check for alloc argument mismatch + if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { + WARN("ALLOC_ARRAY_ARGS", + "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); + } + +# check for multiple semicolons + if ($line =~ /;\s*;\s*$/) { + if (WARN("ONE_SEMICOLON", + "Statements terminations use 1 semicolon\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; + } + } + +# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi + if ($realfile !~ m@^include/uapi/@ && + $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { + my $ull = ""; + $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); + if (CHK("BIT_MACRO", + "Prefer using the BIT$ull macro\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; + } + } + +# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE + if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) { + my $config = $1; + if (WARN("PREFER_IS_ENABLED", + "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; + } + } + +# check for case / default statements not preceded by break/fallthrough/switch + if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { + my $has_break = 0; + my $has_statement = 0; + my $count = 0; + my $prevline = $linenr; + while ($prevline > 1 && ($file || $count < 3) && !$has_break) { + $prevline--; + my $rline = $rawlines[$prevline - 1]; + my $fline = $lines[$prevline - 1]; + last if ($fline =~ /^\@\@/); + next if ($fline =~ /^\-/); + next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); + $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); + next if ($fline =~ /^.[\s$;]*$/); + $has_statement = 1; + $count++; + $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/); + } + if (!$has_break && $has_statement) { + WARN("MISSING_BREAK", + "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr); + } + } + +# check for switch/default statements without a break; + if ($perl_version_ok && + defined $stat && + $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { + my $cnt = statement_rawlines($stat); + my $herectx = get_stat_here($linenr, $cnt, $here); + + WARN("DEFAULT_NO_BREAK", + "switch default: should use break\n" . $herectx); + } + +# check for gcc specific __FUNCTION__ + if ($line =~ /\b__FUNCTION__\b/) { + if (WARN("USE_FUNC", + "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; + } + } + +# check for uses of __DATE__, __TIME__, __TIMESTAMP__ + while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { + ERROR("DATE_TIME", + "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); + } + +# check for use of yield() + if ($line =~ /\byield\s*\(\s*\)/) { + WARN("YIELD", + "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); + } + +# check for comparisons against true and false + if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { + my $lead = $1; + my $arg = $2; + my $test = $3; + my $otype = $4; + my $trail = $5; + my $op = "!"; + + ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); + + my $type = lc($otype); + if ($type =~ /^(?:true|false)$/) { + if (("$test" eq "==" && "$type" eq "true") || + ("$test" eq "!=" && "$type" eq "false")) { + $op = ""; + } + + CHK("BOOL_COMPARISON", + "Using comparison to $otype is error prone\n" . $herecurr); + +## maybe suggesting a correct construct would better +## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); + + } + } + +# check for semaphores initialized locked + if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { + WARN("CONSIDER_COMPLETION", + "consider using a completion\n" . $herecurr); + } + +# recommend kstrto* over simple_strto* and strict_strto* + if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { + WARN("CONSIDER_KSTRTO", + "$1 is obsolete, use k$3 instead\n" . $herecurr); + } + +# check for __initcall(), use device_initcall() explicitly or more appropriate function please + if ($line =~ /^.\s*__initcall\s*\(/) { + WARN("USE_DEVICE_INITCALL", + "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); + } + +# check for spin_is_locked(), suggest lockdep instead + if ($line =~ /\bspin_is_locked\(/) { + WARN("USE_LOCKDEP", + "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr); + } + +# check for deprecated apis + if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) { + my $deprecated_api = $1; + my $new_api = $deprecated_apis{$deprecated_api}; + WARN("DEPRECATED_API", + "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr); + } + +# check for various structs that are normally const (ops, kgdb, device_tree) +# and avoid what seem like struct definitions 'struct foo {' + if ($line !~ /\bconst\b/ && + $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { + WARN("CONST_STRUCT", + "struct $1 should normally be const\n" . $herecurr); + } + +# use of NR_CPUS is usually wrong +# ignore definitions of NR_CPUS and usage to define arrays as likely right + if ($line =~ /\bNR_CPUS\b/ && + $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && + $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && + $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && + $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && + $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) + { + WARN("NR_CPUS", + "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); + } + +# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. + if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { + ERROR("DEFINE_ARCH_HAS", + "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); + } + +# likely/unlikely comparisons similar to "(likely(foo) > 0)" + if ($perl_version_ok && + $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { + WARN("LIKELY_MISUSE", + "Using $1 should generally have parentheses around the comparison\n" . $herecurr); + } + +# nested likely/unlikely calls + if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) { + WARN("LIKELY_MISUSE", + "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr); + } + +# whine mightly about in_atomic + if ($line =~ /\bin_atomic\s*\(/) { + if ($realfile =~ m@^drivers/@) { + ERROR("IN_ATOMIC", + "do not use in_atomic in drivers\n" . $herecurr); + } elsif ($realfile !~ m@^kernel/@) { + WARN("IN_ATOMIC", + "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); + } + } + +# check for mutex_trylock_recursive usage + if ($line =~ /mutex_trylock_recursive/) { + ERROR("LOCKING", + "recursive locking is bad, do not use this ever.\n" . $herecurr); + } + +# check for lockdep_set_novalidate_class + if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || + $line =~ /__lockdep_no_validate__\s*\)/ ) { + if ($realfile !~ m@^kernel/lockdep@ && + $realfile !~ m@^include/linux/lockdep@ && + $realfile !~ m@^drivers/base/core@) { + ERROR("LOCKDEP", + "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); + } + } + + if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || + $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { + WARN("EXPORTED_WORLD_WRITABLE", + "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); + } + +# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> +# and whether or not function naming is typical and if +# DEVICE_ATTR permissions uses are unusual too + if ($perl_version_ok && + defined $stat && + $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) { + my $var = $1; + my $perms = $2; + my $show = $3; + my $store = $4; + my $octal_perms = perms_to_octal($perms); + if ($show =~ /^${var}_show$/ && + $store =~ /^${var}_store$/ && + $octal_perms eq "0644") { + if (WARN("DEVICE_ATTR_RW", + "Use DEVICE_ATTR_RW\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/; + } + } elsif ($show =~ /^${var}_show$/ && + $store =~ /^NULL$/ && + $octal_perms eq "0444") { + if (WARN("DEVICE_ATTR_RO", + "Use DEVICE_ATTR_RO\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/; + } + } elsif ($show =~ /^NULL$/ && + $store =~ /^${var}_store$/ && + $octal_perms eq "0200") { + if (WARN("DEVICE_ATTR_WO", + "Use DEVICE_ATTR_WO\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/; + } + } elsif ($octal_perms eq "0644" || + $octal_perms eq "0444" || + $octal_perms eq "0200") { + my $newshow = "$show"; + $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show"); + my $newstore = $store; + $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store"); + my $rename = ""; + if ($show ne $newshow) { + $rename .= " '$show' to '$newshow'"; + } + if ($store ne $newstore) { + $rename .= " '$store' to '$newstore'"; + } + WARN("DEVICE_ATTR_FUNCTIONS", + "Consider renaming function(s)$rename\n" . $herecurr); + } else { + WARN("DEVICE_ATTR_PERMS", + "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr); + } + } + +# Mode permission misuses where it seems decimal should be octal +# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop +# o Ignore module_param*(...) uses with a decimal 0 permission as that has a +# specific definition of not visible in sysfs. +# o Ignore proc_create*(...) uses with a decimal 0 permission as that means +# use the default permissions + if ($perl_version_ok && + defined $stat && + $line =~ /$mode_perms_search/) { + foreach my $entry (@mode_permission_funcs) { + my $func = $entry->[0]; + my $arg_pos = $entry->[1]; + + my $lc = $stat =~ tr@\n@@; + $lc = $lc + $linenr; + my $stat_real = get_stat_real($linenr, $lc); + + my $skip_args = ""; + if ($arg_pos > 1) { + $arg_pos--; + $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; + } + my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; + if ($stat =~ /$test/) { + my $val = $1; + $val = $6 if ($skip_args ne ""); + if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") && + (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || + ($val =~ /^$Octal$/ && length($val) ne 4))) { + ERROR("NON_OCTAL_PERMISSIONS", + "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); + } + if ($val =~ /^$Octal$/ && (oct($val) & 02)) { + ERROR("EXPORTED_WORLD_WRITABLE", + "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); + } + } + } + } + +# check for uses of S_<PERMS> that could be octal for readability + while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) { + my $oval = $1; + my $octal = perms_to_octal($oval); + if (WARN("SYMBOLIC_PERMS", + "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/; + } + } + +# validate content of MODULE_LICENSE against list from include/linux/module.h + if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { + my $extracted_string = get_quoted_string($line, $rawline); + my $valid_licenses = qr{ + GPL| + GPL\ v2| + GPL\ and\ additional\ rights| + Dual\ BSD/GPL| + Dual\ MIT/GPL| + Dual\ MPL/GPL| + Proprietary + }x; + if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { + WARN("MODULE_LICENSE", + "unknown module license " . $extracted_string . "\n" . $herecurr); + } + } + +# check for sysctl duplicate constants + if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) { + WARN("DUPLICATED_SYSCTL_CONST", + "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr); + } + } + + # If we have no input at all, then there is nothing to report on + # so just keep quiet. + if ($#rawlines == -1) { + exit(0); + } + + # In mailback mode only produce a report in the negative, for + # things that appear to be patches. + if ($mailback && ($clean == 1 || !$is_patch)) { + exit(0); + } + + # This is not a patch, and we are are in 'no-patch' mode so + # just keep quiet. + if (!$chk_patch && !$is_patch) { + exit(0); + } + + if (!$is_patch && $filename !~ /cover-letter\.patch$/) { + ERROR("NOT_UNIFIED_DIFF", + "Does not appear to be a unified-diff format patch\n"); + } + if ($is_patch && $has_commit_log && $chk_signoff) { + if ($signoff == 0) { + ERROR("MISSING_SIGN_OFF", + "Missing Signed-off-by: line(s)\n"); + } elsif (!$authorsignoff) { + WARN("NO_AUTHOR_SIGN_OFF", + "Missing Signed-off-by: line by nominal patch author '$author'\n"); + } + } + + print report_dump(); + if ($summary && !($clean == 1 && $quiet == 1)) { + print "$filename " if ($summary_file); + print "total: $cnt_error errors, $cnt_warn warnings, " . + (($check)? "$cnt_chk checks, " : "") . + "$cnt_lines lines checked\n"; + } + + if ($quiet == 0) { + # If there were any defects found and not already fixing them + if (!$clean and !$fix) { + print << "EOM" + +NOTE: For some of the reported defects, checkpatch may be able to + mechanically convert to the typical style using --fix or --fix-inplace. +EOM + } + # If there were whitespace errors which cleanpatch can fix + # then suggest that. + if ($rpt_cleaners) { + $rpt_cleaners = 0; + print << "EOM" + +NOTE: Whitespace errors detected. + You may wish to use scripts/cleanpatch or scripts/cleanfile +EOM + } + } + + if ($clean == 0 && $fix && + ("@rawlines" ne "@fixed" || + $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { + my $newfile = $filename; + $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); + my $linecount = 0; + my $f; + + @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); + + open($f, '>', $newfile) + or die "$P: Can't open $newfile for write\n"; + foreach my $fixed_line (@fixed) { + $linecount++; + if ($file) { + if ($linecount > 3) { + $fixed_line =~ s/^\+//; + print $f $fixed_line . "\n"; + } + } else { + print $f $fixed_line . "\n"; + } + } + close($f); + + if (!$quiet) { + print << "EOM"; + +Wrote EXPERIMENTAL --fix correction(s) to '$newfile' + +Do _NOT_ trust the results written to this file. +Do _NOT_ submit these changes without inspecting them for correctness. + +This EXPERIMENTAL file is simply a convenience to help rewrite patches. +No warranties, expressed or implied... +EOM + } + } + + if ($quiet == 0) { + print "\n"; + if ($clean == 1) { + print "$vname has no obvious style problems and is ready for submission.\n"; + } else { + print "$vname has style problems, please review.\n"; + } + } + return $clean; +} diff --git a/tools/rimage/scripts/const_structs.checkpatch b/tools/rimage/scripts/const_structs.checkpatch new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tools/rimage/scripts/spelling.txt b/tools/rimage/scripts/spelling.txt new file mode 100644 index 000000000000..9a058cff49d4 --- /dev/null +++ b/tools/rimage/scripts/spelling.txt @@ -0,0 +1,1254 @@ +# Originally from Debian's Lintian tool. Various false positives have been +# removed, and various additions have been made as they've been discovered +# in the kernel source. +# +# License: GPLv2 +# +# The format of each line is: +# mistake||correction +# +abandonning||abandoning +abigious||ambiguous +abitrate||arbitrate +abov||above +abreviated||abbreviated +absense||absence +absolut||absolute +absoulte||absolute +acccess||access +acceess||access +acceleratoin||acceleration +accelleration||acceleration +accesing||accessing +accesnt||accent +accessable||accessible +accesss||access +accidentaly||accidentally +accidentually||accidentally +accoding||according +accomodate||accommodate +accomodates||accommodates +accordign||according +accoring||according +accout||account +accquire||acquire +accquired||acquired +accross||across +acessable||accessible +acess||access +achitecture||architecture +acient||ancient +acitions||actions +acitve||active +acknowldegement||acknowledgment +acknowledgement||acknowledgment +ackowledge||acknowledge +ackowledged||acknowledged +acording||according +activete||activate +actived||activated +actualy||actually +acumulating||accumulating +acumulator||accumulator +adapater||adapter +addional||additional +additionaly||additionally +additonal||additional +addres||address +adddress||address +addreses||addresses +addresss||address +aditional||additional +aditionally||additionally +aditionaly||additionally +adminstrative||administrative +adress||address +adresses||addresses +adviced||advised +afecting||affecting +againt||against +agaist||against +aggreataon||aggregation +aggreation||aggregation +albumns||albums +alegorical||allegorical +algined||aligned +algorith||algorithm +algorithmical||algorithmically +algoritm||algorithm +algoritms||algorithms +algorrithm||algorithm +algorritm||algorithm +aligment||alignment +alignement||alignment +allign||align +alligned||aligned +alllocate||allocate +alloated||allocated +allocatote||allocate +allocatrd||allocated +allocte||allocate +allpication||application +alocate||allocate +alogirhtms||algorithms +alogrithm||algorithm +alot||a lot +alow||allow +alows||allows +altough||although +alue||value +ambigious||ambiguous +amoung||among +amout||amount +an union||a union +an user||a user +an userspace||a userspace +an one||a one +analysator||analyzer +ang||and +anniversery||anniversary +annoucement||announcement +anomolies||anomalies +anomoly||anomaly +anway||anyway +aplication||application +appearence||appearance +applicaion||application +appliction||application +applictions||applications +applys||applies +appplications||applications +appropiate||appropriate +appropriatly||appropriately +approriate||appropriate +approriately||appropriately +apropriate||appropriate +aquainted||acquainted +aquired||acquired +aquisition||acquisition +arbitary||arbitrary +architechture||architecture +arguement||argument +arguements||arguments +aritmetic||arithmetic +arne't||aren't +arraival||arrival +artifical||artificial +artillary||artillery +asign||assign +asser||assert +assertation||assertion +assiged||assigned +assigment||assignment +assigments||assignments +assistent||assistant +assocation||association +associcated||associated +assotiated||associated +assum||assume +assumtpion||assumption +asuming||assuming +asycronous||asynchronous +asynchnous||asynchronous +atomatically||automatically +atomicly||atomically +atempt||attempt +attachement||attachment +attched||attached +attemps||attempts +attemping||attempting +attruibutes||attributes +authentification||authentication +automaticaly||automatically +automaticly||automatically +automatize||automate +automatized||automated +automatizes||automates +autonymous||autonomous +auxillary||auxiliary +auxilliary||auxiliary +avaiable||available +avaible||available +availabe||available +availabled||available +availablity||availability +availale||available +availavility||availability +availble||available +availiable||available +availible||available +avalable||available +avaliable||available +aysnc||async +backgroud||background +backword||backward +backwords||backwards +bahavior||behavior +bakup||backup +baloon||balloon +baloons||balloons +bandwith||bandwidth +banlance||balance +batery||battery +beacuse||because +becasue||because +becomming||becoming +becuase||because +beeing||being +befor||before +begining||beginning +beter||better +betweeen||between +bianries||binaries +bitmast||bitmask +boardcast||broadcast +borad||board +boundry||boundary +brievely||briefly +broadcat||broadcast +cacluated||calculated +caculation||calculation +calender||calendar +calescing||coalescing +calle||called +callibration||calibration +calucate||calculate +calulate||calculate +cancelation||cancellation +cancle||cancel +capabilites||capabilities +capabilty||capability +capabitilies||capabilities +capatibilities||capabilities +capapbilities||capabilities +carefuly||carefully +cariage||carriage +catagory||category +cehck||check +challange||challenge +challanges||challenges +chanell||channel +changable||changeable +chanined||chained +channle||channel +channnel||channel +charachter||character +charachters||characters +charactor||character +charater||character +charaters||characters +charcter||character +chcek||check +chck||check +checksuming||checksumming +childern||children +childs||children +chiled||child +chked||checked +chnage||change +chnages||changes +chnnel||channel +choosen||chosen +chouse||chose +circumvernt||circumvent +claread||cleared +clared||cleared +closeing||closing +clustred||clustered +coexistance||coexistence +collapsable||collapsible +colorfull||colorful +comand||command +comit||commit +commerical||commercial +comming||coming +comminucation||communication +commited||committed +commiting||committing +committ||commit +commoditiy||commodity +comsume||consume +comsumer||consumer +comsuming||consuming +compability||compatibility +compaibility||compatibility +compatability||compatibility +compatable||compatible +compatibiliy||compatibility +compatibilty||compatibility +compatiblity||compatibility +competion||completion +compilant||compliant +compleatly||completely +completition||completion +completly||completely +complient||compliant +componnents||components +compoment||component +compres||compress +compresion||compression +comression||compression +comunication||communication +conbination||combination +conditionaly||conditionally +conected||connected +connecetd||connected +configuartion||configuration +configuratoin||configuration +configuraton||configuration +configuretion||configuration +configutation||configuration +conider||consider +conjuction||conjunction +connectinos||connections +connnection||connection +connnections||connections +consistancy||consistency +consistant||consistent +containes||contains +containts||contains +contaisn||contains +contant||contact +contence||contents +continious||continuous +continous||continuous +continously||continuously +continueing||continuing +contraints||constraints +contol||control +contoller||controller +controled||controlled +controler||controller +controll||control +contruction||construction +contry||country +conuntry||country +convertion||conversion +convertor||converter +convienient||convenient +convinient||convenient +corected||corrected +correponding||corresponding +correponds||corresponds +correspoding||corresponding +cotrol||control +cound||could +couter||counter +coutner||counter +cryptocraphic||cryptographic +cunter||counter +curently||currently +cylic||cyclic +dafault||default +deafult||default +deamon||daemon +decompres||decompress +decription||description +dectected||detected +defailt||default +defferred||deferred +definate||definite +definately||definitely +defintion||definition +defintions||definitions +defualt||default +defult||default +deintializing||deinitializing +deintialize||deinitialize +deintialized||deinitialized +deivce||device +delared||declared +delare||declare +delares||declares +delaring||declaring +delemiter||delimiter +demodualtor||demodulator +demension||dimension +dependancies||dependencies +dependancy||dependency +dependant||dependent +depreacted||deprecated +depreacte||deprecate +desactivate||deactivate +desciptor||descriptor +desciptors||descriptors +descripton||description +descrition||description +descritptor||descriptor +desctiptor||descriptor +desriptor||descriptor +desriptors||descriptors +destionation||destination +destory||destroy +destoryed||destroyed +destorys||destroys +destroied||destroyed +detabase||database +deteced||detected +develope||develop +developement||development +developped||developed +developpement||development +developper||developer +developpment||development +deveolpment||development +devided||divided +deviece||device +diable||disable +dictionnary||dictionary +didnt||didn't +diferent||different +differrence||difference +diffrent||different +diffrentiate||differentiate +difinition||definition +dimesions||dimensions +diplay||display +direectly||directly +disassocation||disassociation +disapear||disappear +disapeared||disappeared +disappared||disappeared +disble||disable +disbled||disabled +disconnet||disconnect +discontinous||discontinuous +dispertion||dispersion +dissapears||disappears +distiction||distinction +docuentation||documentation +documantation||documentation +documentaion||documentation +documment||document +doesnt||doesn't +dorp||drop +dosen||doesn +downlad||download +downlads||downloads +druing||during +dynmaic||dynamic +easilly||easily +ecspecially||especially +edditable||editable +editting||editing +efective||effective +efficently||efficiently +ehther||ether +eigth||eight +elementry||elementary +eletronic||electronic +embeded||embedded +enabledi||enabled +enchanced||enhanced +encorporating||incorporating +encrupted||encrypted +encrypiton||encryption +encryptio||encryption +endianess||endianness +enhaced||enhanced +enlightnment||enlightenment +entrys||entries +enocded||encoded +enterily||entirely +enviroiment||environment +enviroment||environment +environement||environment +environent||environment +eqivalent||equivalent +equiped||equipped +equivelant||equivalent +equivilant||equivalent +eror||error +errorr||error +estbalishment||establishment +etsablishment||establishment +etsbalishment||establishment +excecutable||executable +exceded||exceeded +excellant||excellent +exeed||exceed +existance||existence +existant||existent +exixt||exist +exlcude||exclude +exlcusive||exclusive +exmaple||example +expecially||especially +explicite||explicit +explicitely||explicitly +explict||explicit +explictely||explicitly +explictly||explicitly +expresion||expression +exprimental||experimental +extened||extended +extensability||extensibility +extention||extension +extracter||extractor +falied||failed +faild||failed +faill||fail +failied||failed +faillure||failure +failue||failure +failuer||failure +failng||failing +faireness||fairness +falied||failed +faliure||failure +fallbck||fallback +familar||familiar +fatser||faster +feauture||feature +feautures||features +fetaure||feature +fetaures||features +fileystem||filesystem +fimware||firmware +firware||firmware +finanize||finalize +findn||find +finilizes||finalizes +finsih||finish +flusing||flushing +folloing||following +followign||following +followings||following +follwing||following +fonud||found +forseeable||foreseeable +forse||force +fortan||fortran +forwardig||forwarding +framming||framing +framwork||framework +frequncy||frequency +frome||from +fucntion||function +fuction||function +fuctions||functions +funcion||function +functionallity||functionality +functionaly||functionally +functionnality||functionality +functonality||functionality +funtion||function +funtions||functions +furthur||further +futhermore||furthermore +futrue||future +gaurenteed||guaranteed +generiously||generously +genereate||generate +genric||generic +globel||global +grabing||grabbing +grahical||graphical +grahpical||graphical +grapic||graphic +grranted||granted +guage||gauge +guarenteed||guaranteed +guarentee||guarantee +halfs||halves +hander||handler +handfull||handful +hanled||handled +happend||happened +harware||hardware +heirarchically||hierarchically +helpfull||helpful +hybernate||hibernate +hierachy||hierarchy +hierarchie||hierarchy +howver||however +hsould||should +hypervior||hypervisor +hypter||hyper +identidier||identifier +iligal||illegal +illigal||illegal +imblance||imbalance +immeadiately||immediately +immedaite||immediate +immediatelly||immediately +immediatly||immediately +immidiate||immediate +impelentation||implementation +impementated||implemented +implemantation||implementation +implemenation||implementation +implementaiton||implementation +implementated||implemented +implemention||implementation +implementd||implemented +implemetation||implementation +implemntation||implementation +implentation||implementation +implmentation||implementation +implmenting||implementing +incative||inactive +incomming||incoming +incompatabilities||incompatibilities +incompatable||incompatible +inconsistant||inconsistent +increas||increase +incremeted||incremented +incrment||increment +indendation||indentation +indended||intended +independant||independent +independantly||independently +independed||independent +indiate||indicate +indicat||indicate +inexpect||inexpected +infomation||information +informatiom||information +informations||information +informtion||information +infromation||information +ingore||ignore +inital||initial +initalized||initialized +initalised||initialized +initalise||initialize +initalize||initialize +initation||initiation +initators||initiators +initialiazation||initialization +initializiation||initialization +initialzed||initialized +initilization||initialization +initilize||initialize +inofficial||unofficial +insititute||institute +instal||install +instanciated||instantiated +inteface||interface +integreated||integrated +integrety||integrity +integrey||integrity +intendet||intended +intented||intended +interanl||internal +interchangable||interchangeable +interferring||interfering +interger||integer +intermittant||intermittent +internel||internal +interoprability||interoperability +interuupt||interrupt +interrface||interface +interrrupt||interrupt +interrup||interrupt +interrups||interrupts +interruptted||interrupted +interupted||interrupted +interupt||interrupt +intial||initial +intialisation||initialisation +intialised||initialised +intialise||initialise +intialization||initialization +intialized||initialized +intialize||initialize +intregral||integral +intrrupt||interrupt +intterrupt||interrupt +intuative||intuitive +invaid||invalid +invald||invalid +invalde||invalid +invalide||invalid +invalidiate||invalidate +invalud||invalid +invididual||individual +invokation||invocation +invokations||invocations +irrelevent||irrelevant +isnt||isn't +isssue||issue +iternations||iterations +itertation||iteration +itslef||itself +jave||java +jeffies||jiffies +juse||just +jus||just +kown||known +langage||language +langauage||language +langauge||language +langugage||language +lauch||launch +layed||laid +leightweight||lightweight +lengh||length +lenght||length +lenth||length +lesstiff||lesstif +libaries||libraries +libary||library +librairies||libraries +libraris||libraries +licenceing||licencing +loggging||logging +loggin||login +logile||logfile +loosing||losing +losted||lost +machinary||machinery +maintainance||maintenance +maintainence||maintenance +maintan||maintain +makeing||making +malplaced||misplaced +malplace||misplace +managable||manageable +managment||management +mangement||management +manoeuvering||maneuvering +mappping||mapping +mathimatical||mathematical +mathimatic||mathematic +mathimatics||mathematics +maxium||maximum +mechamism||mechanism +meetign||meeting +ment||meant +mergable||mergeable +mesage||message +messags||messages +messgaes||messages +messsage||message +messsages||messages +micropone||microphone +microprocesspr||microprocessor +milliseonds||milliseconds +minium||minimum +minimam||minimum +minumum||minimum +misalinged||misaligned +miscelleneous||miscellaneous +misformed||malformed +mispelled||misspelled +mispelt||misspelt +mising||missing +mismactch||mismatch +missmanaged||mismanaged +missmatch||mismatch +miximum||maximum +mmnemonic||mnemonic +mnay||many +modulues||modules +momery||memory +memomry||memory +monochorome||monochrome +monochromo||monochrome +monocrome||monochrome +mopdule||module +mroe||more +mulitplied||multiplied +multidimensionnal||multidimensional +multple||multiple +mumber||number +muticast||multicast +mutilcast||multicast +mutiple||multiple +mutli||multi +nams||names +navagating||navigating +nead||need +neccecary||necessary +neccesary||necessary +neccessary||necessary +necesary||necessary +neded||needed +negaive||negative +negoitation||negotiation +negotation||negotiation +nerver||never +nescessary||necessary +nessessary||necessary +noticable||noticeable +notications||notifications +notifed||notified +numebr||number +numner||number +obtaion||obtain +occassionally||occasionally +occationally||occasionally +occurance||occurrence +occurances||occurrences +occured||occurred +occurence||occurrence +occure||occurred +occured||occurred +occuring||occurring +offet||offset +omited||omitted +omiting||omitting +omitt||omit +ommiting||omitting +ommitted||omitted +onself||oneself +ony||only +operatione||operation +opertaions||operations +optionnal||optional +optmizations||optimizations +orientatied||orientated +orientied||oriented +orignal||original +otherise||otherwise +ouput||output +oustanding||outstanding +overaall||overall +overhread||overhead +overlaping||overlapping +overide||override +overrided||overridden +overriden||overridden +overun||overrun +overwritting||overwriting +overwriten||overwritten +pacakge||package +pachage||package +packacge||package +packege||package +packge||package +packtes||packets +pakage||package +pallette||palette +paln||plan +paramameters||parameters +paramaters||parameters +paramater||parameter +parametes||parameters +parametised||parametrised +paramter||parameter +paramters||parameters +particuarly||particularly +particularily||particularly +partiton||partition +pased||passed +passin||passing +pathes||paths +pecularities||peculiarities +peformance||performance +peice||piece +pendantic||pedantic +peprocessor||preprocessor +perfoming||performing +permissons||permissions +peroid||period +persistance||persistence +persistant||persistent +plalform||platform +platfrom||platform +plattform||platform +pleaes||please +ploting||plotting +plugable||pluggable +poinnter||pointer +pointeur||pointer +poiter||pointer +posible||possible +positon||position +possibilites||possibilities +powerfull||powerful +preample||preamble +preapre||prepare +preceeded||preceded +preceeding||preceding +preceed||precede +precendence||precedence +precission||precision +preemptable||preemptible +prefered||preferred +prefferably||preferably +premption||preemption +prepaired||prepared +pressre||pressure +primative||primitive +princliple||principle +priorty||priority +privilaged||privileged +privilage||privilege +priviledge||privilege +priviledges||privileges +probaly||probably +procceed||proceed +proccesors||processors +procesed||processed +proces||process +procesing||processing +processessing||processing +processess||processes +processpr||processor +processsed||processed +processsing||processing +procteted||protected +prodecure||procedure +progams||programs +progess||progress +programers||programmers +programm||program +programms||programs +progresss||progress +promiscous||promiscuous +promps||prompts +pronnounced||pronounced +prononciation||pronunciation +pronouce||pronounce +pronunce||pronounce +propery||property +propigate||propagate +propigation||propagation +propogate||propagate +prosess||process +protable||portable +protcol||protocol +protecion||protection +protocoll||protocol +promixity||proximity +psudo||pseudo +psuedo||pseudo +psychadelic||psychedelic +pwoer||power +quering||querying +randomally||randomly +raoming||roaming +reasearcher||researcher +reasearchers||researchers +reasearch||research +recepient||recipient +receving||receiving +recieved||received +recieve||receive +reciever||receiver +recieves||receives +recogniced||recognised +recognizeable||recognizable +recommanded||recommended +recyle||recycle +redircet||redirect +redirectrion||redirection +reename||rename +refcounf||refcount +refence||reference +refered||referred +referenace||reference +refering||referring +refernces||references +refernnce||reference +refrence||reference +registerd||registered +registeresd||registered +registerred||registered +registes||registers +registraration||registration +regsiter||register +regster||register +regualar||regular +reguator||regulator +regulamentations||regulations +reigstration||registration +releated||related +relevent||relevant +remoote||remote +remore||remote +removeable||removable +repectively||respectively +replacable||replaceable +replacments||replacements +replys||replies +reponse||response +representaion||representation +reqeust||request +requestied||requested +requiere||require +requirment||requirement +requred||required +requried||required +requst||request +reseting||resetting +resizeable||resizable +resouce||resource +resouces||resources +resoures||resources +responce||response +ressizes||resizes +ressource||resource +ressources||resources +retransmited||retransmitted +retreived||retrieved +retreive||retrieve +retrive||retrieve +retuned||returned +reudce||reduce +reuest||request +reuqest||request +reutnred||returned +revsion||revision +rmeoved||removed +rmeove||remove +rmeoves||removes +rountine||routine +routins||routines +rquest||request +runing||running +runned||ran +runnning||running +runtine||runtime +sacrifying||sacrificing +safly||safely +safty||safety +savable||saveable +scaned||scanned +scaning||scanning +scarch||search +seach||search +searchs||searches +secquence||sequence +secund||second +segement||segment +senarios||scenarios +sentivite||sensitive +separatly||separately +sepcify||specify +sepc||spec +seperated||separated +seperately||separately +seperate||separate +seperatly||separately +seperator||separator +sepperate||separate +sequece||sequence +sequencial||sequential +serveral||several +setts||sets +settting||setting +shotdown||shutdown +shoud||should +shouldnt||shouldn't +shoule||should +shrinked||shrunk +siginificantly||significantly +signabl||signal +similary||similarly +similiar||similar +simlar||similar +simliar||similar +simpified||simplified +singaled||signaled +singal||signal +singed||signed +sleeped||slept +softwares||software +speach||speech +specfic||specific +speciefied||specified +specifc||specific +specifed||specified +specificatin||specification +specificaton||specification +specifing||specifying +specifiying||specifying +speficied||specified +speicify||specify +speling||spelling +spinlcok||spinlock +spinock||spinlock +splitted||split +spreaded||spread +spurrious||spurious +sructure||structure +stablilization||stabilization +staically||statically +staion||station +standardss||standards +standartization||standardization +standart||standard +staticly||statically +stoped||stopped +stoppped||stopped +straming||streaming +struc||struct +structres||structures +stuct||struct +strucuture||structure +stucture||structure +sturcture||structure +subdirectoires||subdirectories +suble||subtle +substract||subtract +submition||submission +succesfully||successfully +succesful||successful +successed||succeeded +successfull||successful +successfuly||successfully +sucessfully||successfully +sucess||success +superflous||superfluous +superseeded||superseded +suplied||supplied +suported||supported +suport||support +supportet||supported +suppored||supported +supportin||supporting +suppoted||supported +suppported||supported +suppport||support +supress||suppress +surpressed||suppressed +surpresses||suppresses +susbsystem||subsystem +suspeneded||suspended +suspicously||suspiciously +swaping||swapping +switchs||switches +swith||switch +swithable||switchable +swithc||switch +swithced||switched +swithcing||switching +swithed||switched +swithing||switching +swtich||switch +symetric||symmetric +synax||syntax +synchonized||synchronized +syncronize||synchronize +syncronized||synchronized +syncronizing||synchronizing +syncronus||synchronous +syste||system +sytem||system +sythesis||synthesis +taht||that +targetted||targeted +targetting||targeting +teh||the +temorary||temporary +temproarily||temporarily +therfore||therefore +thier||their +threds||threads +threshhold||threshold +thresold||threshold +throught||through +troughput||throughput +thses||these +tiggered||triggered +tipically||typically +timout||timeout +tmis||this +torerable||tolerable +tramsmitted||transmitted +tramsmit||transmit +tranasction||transaction +tranfer||transfer +transciever||transceiver +transferd||transferred +transfered||transferred +transfering||transferring +transision||transition +transmittd||transmitted +transormed||transformed +trasfer||transfer +trasmission||transmission +treshold||threshold +trigerring||triggering +trun||turn +tunning||tuning +ture||true +tyep||type +udpate||update +uesd||used +uncommited||uncommitted +unconditionaly||unconditionally +underun||underrun +unecessary||unnecessary +unexecpted||unexpected +unexepected||unexpected +unexpcted||unexpected +unexpectd||unexpected +unexpeted||unexpected +unexpexted||unexpected +unfortunatelly||unfortunately +unifiy||unify +unintialized||uninitialized +unkmown||unknown +unknonw||unknown +unknow||unknown +unkown||unknown +unneded||unneeded +unneccecary||unnecessary +unneccesary||unnecessary +unneccessary||unnecessary +unnecesary||unnecessary +unneedingly||unnecessarily +unnsupported||unsupported +unmached||unmatched +unregester||unregister +unresgister||unregister +unrgesiter||unregister +unsinged||unsigned +unstabel||unstable +unsolicitied||unsolicited +unsuccessfull||unsuccessful +unsuported||unsupported +untill||until +unuseful||useless +upate||update +usefule||useful +usefull||useful +usege||usage +usera||users +usualy||usually +utilites||utilities +utillities||utilities +utilties||utilities +utiltity||utility +utitity||utility +utitlty||utility +vaid||valid +vaild||valid +valide||valid +variantions||variations +varible||variable +varient||variant +vaule||value +verbse||verbose +verisons||versions +verison||version +verson||version +vicefersa||vice-versa +virtal||virtual +virtaul||virtual +virtiual||virtual +visiters||visitors +vitual||virtual +wakeus||wakeups +wating||waiting +wiat||wait +wether||whether +whataver||whatever +whcih||which +whenver||whenever +wheter||whether +whe||when +wierd||weird +wiil||will +wirte||write +withing||within +wnat||want +workarould||workaround +writeing||writing +writting||writing +zombe||zombie +zomebie||zombie diff --git a/tools/rimage/src/adsp_config.c b/tools/rimage/src/adsp_config.c new file mode 100644 index 000000000000..9a9423cbada7 --- /dev/null +++ b/tools/rimage/src/adsp_config.c @@ -0,0 +1,2378 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2020 Intel Corporation. All rights reserved. + * + * Author: Karol Trzcinski <karolx.trzcinski@linux.intel.com> + */ + +#include "rimage/sof/user/manifest.h" +#include "rimage/sof/user/manifest.h" +#include "rimage/adsp_config.h" +#include "rimage/ext_manifest_gen.h" +#include "rimage/plat_auth.h" +#include "rimage/manifest.h" +#include "rimage/rimage.h" +#include "rimage/cse.h" +#include "rimage/css.h" +#include "rimage/toml_utils.h" +#include "rimage/file_utils.h" +#include "toml.h" +#include <stdbool.h> +#include <stdint.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include <ctype.h> + +/* map memory zone string name to enum value */ +static enum snd_sof_fw_blk_type zone_name_to_idx(const char *name) +{ + static const struct { + const char name[32]; + enum snd_sof_fw_blk_type type; + } mem_zone_name_dict[] = { + {"START", SOF_FW_BLK_TYPE_START}, + {"IRAM", SOF_FW_BLK_TYPE_IRAM}, + {"DRAM", SOF_FW_BLK_TYPE_DRAM}, + {"SRAM", SOF_FW_BLK_TYPE_SRAM}, + {"ROM", SOF_FW_BLK_TYPE_ROM}, + {"IMR", SOF_FW_BLK_TYPE_IMR}, + {"RSRVD0", SOF_FW_BLK_TYPE_RSRVD0}, + {"HP-SRAM", SOF_FW_BLK_TYPE_HPSRAM}, + {"LP-SRAM", SOF_FW_BLK_TYPE_LPSRAM}, + {"RSRVD8", SOF_FW_BLK_TYPE_RSRVD8}, + {"RSRVD9", SOF_FW_BLK_TYPE_RSRVD9}, + {"RSRVD10", SOF_FW_BLK_TYPE_RSRVD10}, + {"RSRVD11", SOF_FW_BLK_TYPE_RSRVD11}, + {"RSRVD12", SOF_FW_BLK_TYPE_RSRVD12}, + {"RSRVD13", SOF_FW_BLK_TYPE_RSRVD13}, + {"RSRVD14", SOF_FW_BLK_TYPE_RSRVD14}, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(mem_zone_name_dict); ++i) { + if (!strcmp(name, mem_zone_name_dict[i].name)) + return mem_zone_name_dict[i].type; + } + return SOF_FW_BLK_TYPE_INVALID; +} + +static void dump_adsp(const struct adsp *adsp) +{ + int i; + + DUMP("\nadsp"); + DUMP_KEY("name", "'%s'", adsp->name); + DUMP_KEY("image_size", "0x%x", adsp->image_size); + DUMP_KEY("exec_boot_ldr", "%d", adsp->exec_boot_ldr); + for (i = 0; i < ARRAY_SIZE(adsp->mem.zones); ++i) { + DUMP_KEY("mem_zone.idx", "%d", i); + DUMP_KEY("mem_zone.size", "0x%x", adsp->mem.zones[i].size); + DUMP_KEY("mem_zone.base", "0x%x", adsp->mem.zones[i].base); + DUMP_KEY("mem_zone.host_offset", "0x%x", adsp->mem.zones[i].host_offset); + } +} + +static int parse_adsp(const toml_table_t *toml, struct parse_ctx *pctx, struct adsp *out, + bool verbose) +{ + toml_array_t *mem_zone_array, *alias_array; + struct memory_zone *zone; + struct parse_ctx ctx; + toml_table_t *adsp; + toml_raw_t raw; + int zone_idx; + char a_kind; + int a_size; + bool alias_found; + int ret; + int i; + + /* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */ + adsp = toml_table_in(toml, "adsp"); + if (!adsp) + return err_key_not_found("adsp"); + ++pctx->table_cnt; + parse_ctx_init(&ctx); + + /* non-configurable fields */ + + /* configurable fields */ + raw = toml_raw_in(adsp, "name"); + if (!raw) + return err_key_not_found("name"); + ++ctx.key_cnt; + + /* free(out->name) is called in adsp_free() */ + ret = toml_rtos(raw, (char **)&out->name); + if (ret < 0) + return err_key_parse("name", NULL); + + out->image_size = parse_uint32_hex_key(adsp, &ctx, "image_size", 0, &ret); + if (ret < 0) + return ret; + + out->exec_boot_ldr = parse_uint32_key(adsp, &ctx, "exec_boot_ldr", 0, &ret); + if (ret < 0) + return ret; + + memset(&out->mem, 0, sizeof(out->mem)); + out->mem.alias.mask = parse_uint32_hex_key(adsp, &ctx, "alias_mask", -ENODATA, &ret); + alias_found = !ret; + + /* check everything parsed, 1 or 2 tables should be present */ + ctx.array_cnt += 1 + alias_found; + ret = assert_everything_parsed(adsp, &ctx); + if (ret < 0) + return ret; + + if (alias_found) { + alias_array = toml_array_in(adsp, "mem_alias"); + if (!alias_array) + return err_key_not_found("mem_alias"); + a_kind = toml_array_kind(alias_array); + a_size = toml_array_nelem(alias_array); + if (a_kind != 't' || a_size != 2) + return err_key_parse("mem_alias", "wrong array type %c or length %d", + a_kind, a_size); + + /* retrieve "cached" and "uncached" alias base addresses */ + for (i = 0; i < a_size; ++i) { + toml_table_t *alias = toml_table_at(alias_array, i); + char alias_name[16]; + uint32_t base; + + if (!alias) + return err_key_parse("mem_alias", NULL); + + parse_str_key(alias, &ctx, "type", alias_name, sizeof(alias_name), &ret); + if (ret < 0) + return err_key_parse("mem_alias", NULL); + + base = parse_uint32_hex_key(alias, &ctx, "base", -1, &ret); + + if (!strncmp("cached", alias_name, sizeof("cached"))) + out->mem.alias.cached = base & out->mem.alias.mask; + else if (!strncmp("uncached", alias_name, sizeof("uncached"))) + out->mem.alias.uncached = base & out->mem.alias.mask; + } + } else { + /* Make uncache_to_cache() an identity transform */ + out->mem.alias.uncached = 0; + out->mem.alias.cached = 0; + out->mem.alias.mask = 0; + } + + /* look for entry array */ + mem_zone_array = toml_array_in(adsp, "mem_zone"); + if (!mem_zone_array) + return err_key_not_found("mem_zone"); + a_kind = toml_array_kind(mem_zone_array); + a_size = toml_array_nelem(mem_zone_array); + if (a_kind != 't' || a_size > SOF_FW_BLK_TYPE_NUM) + return err_key_parse("mem_zone", "wrong array type %c or length %d", + a_kind, a_size); + + /* parse entry array elements */ + for (i = 0; i < a_size; ++i) { + toml_table_t *mem_zone = toml_table_at(mem_zone_array, i); + char zone_name[32]; + + if (!mem_zone) + return err_key_parse("mem_zone", NULL); + + /* initialize parse context for each array element */ + parse_ctx_init(&ctx); + + /* non-configurable fields */ + + /* configurable fields */ + parse_str_key(mem_zone, &ctx, "type", zone_name, sizeof(zone_name), &ret); + if (ret < 0) + return err_key_parse("mem_zone", NULL); + + zone_idx = zone_name_to_idx(zone_name); + if (zone_idx < 0) + return err_key_parse("mem_zone.name", "unknown zone '%s'", zone_name); + + zone = &out->mem.zones[zone_idx]; + zone->base = parse_uint32_hex_key(mem_zone, &ctx, "base", -1, &ret); + if (ret < 0) + return err_key_parse("mem_zone", NULL); + + zone->host_offset = parse_uint32_hex_key(mem_zone, &ctx, "host_offset", 0, + &ret); + if (ret < 0) + return err_key_parse("mem_zone", NULL); + + zone->size = parse_uint32_hex_key(mem_zone, &ctx, "size", -1, &ret); + if (ret < 0) + return err_key_parse("mem_zone", NULL); + + /* check everything parsed */ + ret = assert_everything_parsed(mem_zone, &ctx); + if (ret < 0) + return ret; + } + + if (verbose) + dump_adsp(out); + + /* + * values set in other places in code: + * - write_firmware + * - write_firmware_meu + * - man_vX_Y + */ + + return 0; +} + +static void dump_cse(const struct CsePartitionDirHeader *cse_header, + const struct CsePartitionDirEntry *cse_entry) +{ + int i; + + DUMP("\ncse"); + DUMP_PRINTABLE_BYTES("partition_name", cse_header->partition_name); + DUMP_KEY("header_version", "%d", cse_header->header_version); + DUMP_KEY("entry_version", "%d", cse_header->entry_version); + DUMP_KEY("nb_entries", "%d", cse_header->nb_entries); + for (i = 0; i < cse_header->nb_entries; ++i) { + DUMP_PRINTABLE_BYTES("entry.name", cse_entry[i].entry_name); + DUMP_KEY("entry.offset", "0x%x", cse_entry[i].offset); + DUMP_KEY("entry.length", "0x%x", cse_entry[i].length); + } +} + +static int parse_cse(const toml_table_t *toml, struct parse_ctx *pctx, + struct CsePartitionDirHeader *hdr, struct CsePartitionDirEntry *out, + int entry_capacity, bool verbose) +{ + toml_array_t *cse_entry_array; + toml_table_t *cse_entry; + struct parse_ctx ctx; + toml_table_t *cse; + int ret; + int i; + + /* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */ + cse = toml_table_in(toml, "cse"); + if (!cse) + return err_key_not_found("cse"); + ++pctx->table_cnt; + parse_ctx_init(&ctx); + + /* non-configurable fields */ + hdr->header_marker = CSE_HEADER_MAKER; + hdr->header_length = sizeof(struct CsePartitionDirHeader); + + /* configurable fields */ + hdr->header_version = parse_uint32_key(cse, &ctx, "header_version", 1, &ret); + if (ret < 0) + return ret; + + hdr->entry_version = parse_uint32_key(cse, &ctx, "entry_version", 1, &ret); + if (ret < 0) + return ret; + + parse_printable_key(cse, &ctx, "partition_name", hdr->partition_name, + sizeof(hdr->partition_name), &ret); + if (ret < 0) + return ret; + + /* check everything parsed, expect 1 table */ + ctx.array_cnt += 1; + ret = assert_everything_parsed(cse, &ctx); + if (ret < 0) + return ret; + + /* entry array */ + cse_entry_array = toml_array_in(cse, "entry"); + if (!cse_entry_array) + return err_key_not_found("entry"); + if (toml_array_kind(cse_entry_array) != 't' || + toml_array_nelem(cse_entry_array) != entry_capacity) + return err_key_parse("entry", "wrong array type or length != %d", entry_capacity); + + /* parse entry array elements */ + for (i = 0; i < toml_array_nelem(cse_entry_array); ++i) { + cse_entry = toml_table_at(cse_entry_array, i); + if (!cse_entry) + return err_key_parse("entry", NULL); + + /* initialize parse context for each array element */ + parse_ctx_init(&ctx); + + /* non-configurable fields */ + + /* configurable fields */ + parse_printable_key(cse_entry, &ctx, "name", out[i].entry_name, + sizeof(out[i].entry_name), &ret); + if (ret < 0) + return err_key_parse("entry", NULL); + + out[i].offset = parse_uint32_hex_key(cse_entry, &ctx, "offset", -1, &ret); + if (ret < 0) + return err_key_parse("entry", NULL); + + out[i].length = parse_uint32_hex_key(cse_entry, &ctx, "length", -1, &ret); + if (ret < 0) + return err_key_parse("entry", NULL); + + /* check everything parsed */ + ret = assert_everything_parsed(cse_entry, &ctx); + if (ret < 0) + return ret; + } + + hdr->nb_entries = toml_array_nelem(cse_entry_array); + + if (verbose) + dump_cse(hdr, out); + + /* + * values set in other places in code: + * - checksum + */ + + return 0; +} + +static void dump_cse_v2_5(const struct CsePartitionDirHeader_v2_5 *cse_header, + const struct CsePartitionDirEntry *cse_entry) +{ + int i; + + DUMP("\ncse"); + DUMP_PRINTABLE_BYTES("partition_name", cse_header->partition_name); + DUMP_KEY("header_version", "%d", cse_header->header_version); + DUMP_KEY("entry_version", "%d", cse_header->entry_version); + DUMP_KEY("nb_entries", "%d", cse_header->nb_entries); + for (i = 0; i < cse_header->nb_entries; ++i) { + DUMP_PRINTABLE_BYTES("entry.name", cse_entry[i].entry_name); + DUMP_KEY("entry.offset", "0x%x", cse_entry[i].offset); + DUMP_KEY("entry.length", "0x%x", cse_entry[i].length); + } +} + +/* TODO: fix up constants in headers for v2.5 */ +static int parse_cse_v2_5(const toml_table_t *toml, struct parse_ctx *pctx, + struct CsePartitionDirHeader_v2_5 *hdr, struct CsePartitionDirEntry *out, + int entry_capacity, bool verbose) +{ + toml_array_t *cse_entry_array; + toml_table_t *cse_entry; + struct parse_ctx ctx; + toml_table_t *cse; + int ret; + int i; + + /* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */ + cse = toml_table_in(toml, "cse"); + if (!cse) + return err_key_not_found("cse"); + ++pctx->table_cnt; + parse_ctx_init(&ctx); + + /* non-configurable fields */ + hdr->header_marker = CSE_HEADER_MAKER; + hdr->header_length = sizeof(struct CsePartitionDirHeader_v2_5); + + /* configurable fields */ + hdr->header_version = parse_uint32_key(cse, &ctx, "header_version", 2, &ret); + if (ret < 0) + return ret; + + hdr->entry_version = parse_uint32_key(cse, &ctx, "entry_version", 1, &ret); + if (ret < 0) + return ret; + + parse_printable_key(cse, &ctx, "partition_name", hdr->partition_name, + sizeof(hdr->partition_name), &ret); + if (ret < 0) + return ret; + + /* check everything parsed, expect 1 table */ + ctx.array_cnt += 1; + ret = assert_everything_parsed(cse, &ctx); + if (ret < 0) + return ret; + + /* entry array */ + cse_entry_array = toml_array_in(cse, "entry"); + if (!cse_entry_array) + return err_key_not_found("entry"); + if (toml_array_kind(cse_entry_array) != 't' || + toml_array_nelem(cse_entry_array) != entry_capacity) + return err_key_parse("entry", "wrong array type or length != %d", entry_capacity); + + /* parse entry array elements */ + for (i = 0; i < toml_array_nelem(cse_entry_array); ++i) { + cse_entry = toml_table_at(cse_entry_array, i); + if (!cse_entry) + return err_key_parse("entry", NULL); + + /* initialize parse context for each array element */ + parse_ctx_init(&ctx); + + /* non-configurable fields */ + + /* configurable fields */ + parse_printable_key(cse_entry, &ctx, "name", out[i].entry_name, + sizeof(out[i].entry_name), &ret); + if (ret < 0) + return err_key_parse("entry", NULL); + + out[i].offset = parse_uint32_hex_key(cse_entry, &ctx, "offset", -1, &ret); + if (ret < 0) + return err_key_parse("offset", NULL); + + out[i].length = parse_uint32_hex_key(cse_entry, &ctx, "length", -1, &ret); + if (ret < 0) + return err_key_parse("length", NULL); + + /* check everything parsed */ + ret = assert_everything_parsed(cse_entry, &ctx); + if (ret < 0) + return ret; + } + + hdr->nb_entries = toml_array_nelem(cse_entry_array); + + if (verbose) + dump_cse_v2_5(hdr, out); + + /* + * values set in other places in code: + * - checksum + */ + + return 0; +} + +static void dump_css_v1_5(const struct css_header_v1_5 *css) +{ + DUMP("\ncss 1.5"); + DUMP_KEY("module_type", "%d", css->module_type); + DUMP_KEY("header_len", "%d", css->header_len); + DUMP_KEY("header_version", "0x%x", css->header_version); + DUMP_KEY("module_vendor", "0x%x", css->module_vendor); + DUMP_KEY("size", "%d", css->size); + DUMP_KEY("key_size", "%d", css->key_size); + DUMP_KEY("modulus_size", "%d", css->modulus_size); + DUMP_KEY("exponent_size", "%d", css->exponent_size); +} + +static int parse_css_v1_5(const toml_table_t *toml, struct parse_ctx *pctx, + struct css_header_v1_5 *out, bool verbose) +{ + struct parse_ctx ctx; + toml_table_t *css; + int ret; + + /* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */ + css = toml_table_in(toml, "css"); + if (!css) + return err_key_not_found("css"); + ++pctx->table_cnt; + parse_ctx_init(&ctx); + + /* non-configurable fields */ + + /* configurable fields */ + out->module_type = parse_uint32_key(css, &ctx, "module_type", MAN_CSS_LT_MODULE_TYPE, &ret); + if (ret < 0) + return ret; + + out->header_len = parse_uint32_key(css, &ctx, "header_len", MAN_CSS_HDR_SIZE, &ret); + if (ret < 0) + return ret; + + out->header_version = parse_uint32_hex_key(css, &ctx, "header_version", MAN_CSS_HDR_VERSION, + &ret); + if (ret < 0) + return ret; + out->module_vendor = parse_uint32_hex_key(css, &ctx, "module_vendor", MAN_CSS_MOD_VENDOR, + &ret); + if (ret < 0) + return ret; + + out->size = parse_uint32_key(css, &ctx, "size", 0x800, &ret); + if (ret < 0) + return ret; + + out->key_size = parse_uint32_key(css, &ctx, "key_size", MAN_CSS_KEY_SIZE, &ret); + if (ret < 0) + return ret; + + out->modulus_size = parse_uint32_key(css, &ctx, "modulus_size", MAN_CSS_MOD_SIZE, &ret); + if (ret < 0) + return ret; + + out->exponent_size = parse_uint32_key(css, &ctx, "exponent_size", MAN_CSS_EXP_SIZE, &ret); + if (ret < 0) + return ret; + + /* check everything parsed */ + ret = assert_everything_parsed(css, &ctx); + if (ret < 0) + return ret; + + if (verbose) + dump_css_v1_5(out); + + /* + * values set in other places in code: + * - date + * - version + * - modulus + * - exponent + * - signature + */ + + return 0; +} + +static void dump_css_v1_8(const struct css_header_v1_8 *css) +{ + DUMP("\ncss 1.8"); + DUMP_KEY("header_type", "%d", css->header_type); + DUMP_KEY("header_len", "%d", css->header_len); + DUMP_KEY("header_version", "0x%x", css->header_version); + DUMP_KEY("module_vendor", "0x%x", css->module_vendor); + DUMP_KEY("size", "%d", css->size); + DUMP_KEY("svn", "%d", css->svn); + DUMP_KEY("modulus_size", "%d", css->modulus_size); + DUMP_KEY("exponent_size", "%d", css->exponent_size); +} + +static int parse_css_v1_8(const toml_table_t *toml, struct parse_ctx *pctx, + struct css_header_v1_8 *out, bool verbose) +{ + static const uint8_t hdr_id[4] = MAN_CSS_HDR_ID; + struct parse_ctx ctx; + toml_table_t *css; + int ret; + + /* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */ + css = toml_table_in(toml, "css"); + if (!css) + return err_key_not_found("css"); + ++pctx->table_cnt; + parse_ctx_init(&ctx); + + /* non-configurable fields */ + memcpy(out->header_id, hdr_id, sizeof(out->header_id)); + + /* configurable fields */ + out->header_type = parse_uint32_key(css, &ctx, "header_type", MAN_CSS_MOD_TYPE, &ret); + if (ret < 0) + return ret; + + out->header_len = parse_uint32_key(css, &ctx, "header_len", MAN_CSS_HDR_SIZE, &ret); + if (ret < 0) + return ret; + + out->header_version = parse_uint32_hex_key(css, &ctx, "header_version", MAN_CSS_HDR_VERSION, + &ret); + if (ret < 0) + return ret; + out->module_vendor = parse_uint32_hex_key(css, &ctx, "module_vendor", MAN_CSS_MOD_VENDOR, + &ret); + if (ret < 0) + return ret; + + out->size = parse_uint32_key(css, &ctx, "size", 222, &ret); + if (ret < 0) + return ret; + + out->svn = parse_uint32_key(css, &ctx, "svn", 0, &ret); + if (ret < 0) + return ret; + + out->modulus_size = parse_uint32_key(css, &ctx, "modulus_size", MAN_CSS_MOD_SIZE, &ret); + if (ret < 0) + return ret; + + out->exponent_size = parse_uint32_key(css, &ctx, "exponent_size", MAN_CSS_EXP_SIZE, &ret); + if (ret < 0) + return ret; + + /* check everything parsed */ + ret = assert_everything_parsed(css, &ctx); + if (ret < 0) + return ret; + + if (verbose) + dump_css_v1_8(out); + + /* + * values set in other places in code: + * - date + * - version + * - modulus + * - exponent + * - signature + */ + + return 0; +} + +static void dump_css_v2_5(const struct css_header_v2_5 *css) +{ + DUMP("\ncss 2.5"); + DUMP_KEY("header_type", "%d", css->header_type); + DUMP_KEY("header_len", "%d", css->header_len); + DUMP_KEY("header_version", "0x%x", css->header_version); + DUMP_KEY("module_vendor", "0x%x", css->module_vendor); + DUMP_KEY("size", "%d", css->size); + DUMP_KEY("svn", "%d", css->svn); + DUMP_KEY("modulus_size", "%d", css->modulus_size); + DUMP_KEY("exponent_size", "%d", css->exponent_size); +} + +static int parse_css_v2_5(const toml_table_t *toml, struct parse_ctx *pctx, + struct css_header_v2_5 *out, bool verbose) +{ + static const uint8_t hdr_id[4] = MAN_CSS_HDR_ID; + struct parse_ctx ctx; + toml_table_t *css; + int ret; + + /* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */ + css = toml_table_in(toml, "css"); + if (!css) + return err_key_not_found("css"); + ++pctx->table_cnt; + parse_ctx_init(&ctx); + + /* non-configurable fields */ + memcpy(out->header_id, hdr_id, sizeof(out->header_id)); + + /* configurable fields */ + out->header_type = parse_uint32_key(css, &ctx, "header_type", MAN_CSS_MOD_TYPE, &ret); + if (ret < 0) + return ret; + + out->header_len = parse_uint32_key(css, &ctx, "header_len", MAN_CSS_HDR_SIZE_2_5, &ret); + if (ret < 0) + return ret; + + out->header_version = parse_uint32_hex_key(css, &ctx, "header_version", MAN_CSS_HDR_VERSION_2_5, + &ret); + if (ret < 0) + return ret; + out->module_vendor = parse_uint32_hex_key(css, &ctx, "module_vendor", MAN_CSS_MOD_VENDOR, + &ret); + if (ret < 0) + return ret; + + out->size = parse_uint32_key(css, &ctx, "size", 281, &ret); + if (ret < 0) + return ret; + + out->svn = parse_uint32_key(css, &ctx, "svn", 0, &ret); + if (ret < 0) + return ret; + + out->modulus_size = parse_uint32_key(css, &ctx, "modulus_size", MAN_CSS_MOD_SIZE_2_5, &ret); + if (ret < 0) + return ret; + + out->exponent_size = parse_uint32_key(css, &ctx, "exponent_size", MAN_CSS_EXP_SIZE, &ret); + if (ret < 0) + return ret; + + /* hardcoded to align with meu */ + out->reserved1[0] = 0xf; + out->reserved1[1] = 0x048e0000; // TODO: what is this ? + + /* check everything parsed */ + ret = assert_everything_parsed(css, &ctx); + if (ret < 0) + return ret; + + if (verbose) + dump_css_v2_5(out); + + /* + * values set in other places in code: + * - date + * - version + * - modulus + * - exponent + * - signature + */ + + return 0; +} + +static void dump_signed_pkg(const struct signed_pkg_info_ext *signed_pkg) +{ + int i; + + DUMP("\nsigned_pkg"); + DUMP_PRINTABLE_BYTES("name", signed_pkg->name); + DUMP_KEY("vcn", "%d", signed_pkg->vcn); + DUMP_KEY("svn", "%d", signed_pkg->svn); + DUMP_KEY("fw_type", "%d", signed_pkg->fw_type); + DUMP_KEY("fw_sub_type", "%d", signed_pkg->fw_sub_type); + for (i = 0; i < ARRAY_SIZE(signed_pkg->bitmap); ++i) + DUMP_KEY("bitmap", "%d", signed_pkg->bitmap[i]); + for (i = 0; i < ARRAY_SIZE(signed_pkg->module); ++i) { + DUMP_PRINTABLE_BYTES("meta.name", signed_pkg->module[i].name); + DUMP_KEY("meta.type", "0x%x", signed_pkg->module[i].type); + DUMP_KEY("meta.hash_algo", "0x%x", signed_pkg->module[i].hash_algo); + DUMP_KEY("meta.hash_size", "0x%x", signed_pkg->module[i].hash_size); + DUMP_KEY("meta.meta_size", "%d", signed_pkg->module[i].meta_size); + } +} + +static int parse_signed_pkg(const toml_table_t *toml, struct parse_ctx *pctx, + struct image *image, bool verbose) +{ + struct adsp *adsp = image->adsp; + struct signed_pkg_info_ext *out = &adsp->man_v1_8->signed_pkg; + struct signed_pkg_info_module *mod; + toml_array_t *bitmap_array; + toml_array_t *module_array; + toml_table_t *signed_pkg; + struct parse_ctx ctx; + toml_table_t *module; + toml_raw_t raw; + int64_t temp_i; + int ret; + int i; + + /* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */ + signed_pkg = toml_table_in(toml, "signed_pkg"); + if (!signed_pkg) + return err_key_not_found("signed_pkg"); + ++pctx->table_cnt; + parse_ctx_init(&ctx); + + /* non-configurable fields */ + out->ext_type = SIGN_PKG_EXT_TYPE; + out->ext_len = sizeof(struct signed_pkg_info_ext); + + /* configurable fields */ + parse_printable_key(signed_pkg, &ctx, "name", out->name, sizeof(out->name), &ret); + if (ret < 0) + return ret; + + out->vcn = parse_uint32_key(signed_pkg, &ctx, "vcn", 0, &ret); + if (ret < 0) + return ret; + + out->svn = parse_uint32_key(signed_pkg, &ctx, "svn", 0, &ret); + if (ret < 0) + return ret; + + out->fw_type = parse_uint32_hex_key(signed_pkg, &ctx, "fw_type", 0, &ret); + if (ret < 0) + return ret; + + out->fw_sub_type = parse_uint32_hex_key(signed_pkg, &ctx, "fw_sub_type", 0, &ret); + if (ret < 0) + return ret; + + /* bitmap array */ + bitmap_array = toml_array_in(signed_pkg, "bitmap"); + if (!bitmap_array) { + /* default value, depending on the IMR type */ + out->bitmap[4] = image->imr_type == 4 ? 0x10 : 0x8; + } else { + ++ctx.array_cnt; + if (toml_array_kind(bitmap_array) != 'v' || toml_array_type(bitmap_array) != 'i' || + toml_array_nelem(bitmap_array) > ARRAY_SIZE(out->bitmap)) + return err_key_parse("bitmap", "wrong array type or length > %d", + ARRAY_SIZE(out->bitmap)); + + for (i = 0; i < toml_array_nelem(bitmap_array); ++i) { + raw = toml_raw_at(bitmap_array, i); + if (!raw) + return err_key_parse("bitmap", NULL); + + ret = toml_rtoi(raw, &temp_i); + if (ret < 0 || temp_i < 0) + return err_key_parse("bitmap", "values can't be negative"); + out->bitmap[i] = temp_i; + } + } + + /* check everything parsed, expect 1 more array */ + ctx.array_cnt += 1; + ret = assert_everything_parsed(signed_pkg, &ctx); + if (ret < 0) + return ret; + + /* modules array */ + module_array = toml_array_in(signed_pkg, "module"); + if (!module_array) + return err_key_not_found("module"); + if (toml_array_kind(module_array) != 't' || + toml_array_nelem(module_array) != ARRAY_SIZE(out->module)) + return err_key_parse("module", "wrong array type or length != %d", + ARRAY_SIZE(out->module)); + + /* parse modules array elements */ + for (i = 0; i < toml_array_nelem(module_array); ++i) { + module = toml_table_at(module_array, i); + if (!module) + return err_key_parse("module", NULL); + mod = &out->module[i]; + + /* initialize parse context for each array element */ + parse_ctx_init(&ctx); + + /* non-configurable fields */ + + /* configurable fields */ + parse_printable_key(module, &ctx, "name", mod->name, sizeof(mod->name), &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + mod->type = parse_uint32_hex_key(module, &ctx, "type", 0x03, &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + mod->hash_algo = parse_uint32_hex_key(module, &ctx, "hash_algo", 0x02, &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + mod->hash_size = parse_uint32_hex_key(module, &ctx, "hash_size", 0x20, &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + mod->meta_size = parse_uint32_key(module, &ctx, "meta_size", 96, &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + /* check everything parsed */ + ret = assert_everything_parsed(module, &ctx); + if (ret < 0) + return ret; + } + + if (verbose) + dump_signed_pkg(out); + + /* + * values set in other places in code: + * - module.hash + */ + + return 0; +} + +static void dump_signed_pkg_v2_5(const struct signed_pkg_info_ext_v2_5 *signed_pkg) +{ + int i; + + DUMP("\nsigned_pkg"); + DUMP_PRINTABLE_BYTES("name", signed_pkg->name); + DUMP_KEY("vcn", "%d", signed_pkg->vcn); + DUMP_KEY("svn", "%d", signed_pkg->svn); + DUMP_KEY("fw_type", "%d", signed_pkg->fw_type); + DUMP_KEY("fw_sub_type", "%d", signed_pkg->fw_sub_type); + for (i = 0; i < ARRAY_SIZE(signed_pkg->bitmap); ++i) + DUMP_KEY("bitmap", "%d", signed_pkg->bitmap[i]); + for (i = 0; i < ARRAY_SIZE(signed_pkg->module); ++i) { + DUMP_PRINTABLE_BYTES("meta.name", signed_pkg->module[i].name); + DUMP_KEY("meta.type", "0x%x", signed_pkg->module[i].type); + DUMP_KEY("meta.hash_algo", "0x%x", signed_pkg->module[i].hash_algo); + DUMP_KEY("meta.hash_size", "0x%x", signed_pkg->module[i].hash_size); + DUMP_KEY("meta.meta_size", "%d", signed_pkg->module[i].meta_size); + } +} + +static int parse_signed_pkg_v2_5(const toml_table_t *toml, struct parse_ctx *pctx, + struct image *image, bool verbose) +{ + struct adsp *adsp = image->adsp; + struct signed_pkg_info_ext_v2_5 *out = &adsp->man_v2_5->signed_pkg; + struct signed_pkg_info_module_v2_5 *mod; + toml_array_t *bitmap_array; + toml_array_t *module_array; + toml_table_t *signed_pkg; + struct parse_ctx ctx; + toml_table_t *module; + toml_raw_t raw; + int64_t temp_i; + int ret; + int i; + + /* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */ + signed_pkg = toml_table_in(toml, "signed_pkg"); + if (!signed_pkg) + return err_key_not_found("signed_pkg"); + ++pctx->table_cnt; + parse_ctx_init(&ctx); + + /* non-configurable fields */ + out->ext_type = SIGN_PKG_EXT_TYPE; + out->ext_len = sizeof(struct signed_pkg_info_ext_v2_5); + + /* configurable fields */ + parse_printable_key(signed_pkg, &ctx, "name", out->name, sizeof(out->name), &ret); + if (ret < 0) + return ret; + + out->vcn = parse_uint32_key(signed_pkg, &ctx, "vcn", 0, &ret); + if (ret < 0) + return ret; + + out->svn = parse_uint32_key(signed_pkg, &ctx, "svn", 0, &ret); + if (ret < 0) + return ret; + + out->fw_type = parse_uint32_hex_key(signed_pkg, &ctx, "fw_type", 0, &ret); + if (ret < 0) + return ret; + + out->fw_sub_type = parse_uint32_hex_key(signed_pkg, &ctx, "fw_sub_type", 0, &ret); + if (ret < 0) + return ret; + + /* bitmap array */ + bitmap_array = toml_array_in(signed_pkg, "bitmap"); + if (!bitmap_array) { + /* default value, depending on the IMR type */ + out->bitmap[4] = image->imr_type == 4 ? 0x10 : 0x8; + } else { + ++ctx.array_cnt; + if (toml_array_kind(bitmap_array) != 'v' || toml_array_type(bitmap_array) != 'i' || + toml_array_nelem(bitmap_array) > ARRAY_SIZE(out->bitmap)) + return err_key_parse("bitmap", "wrong array type or length > %d", + ARRAY_SIZE(out->bitmap)); + + for (i = 0; i < toml_array_nelem(bitmap_array); ++i) { + raw = toml_raw_at(bitmap_array, i); + if (!raw) + return err_key_parse("bitmap", NULL); + + ret = toml_rtoi(raw, &temp_i); + if (ret < 0 || temp_i < 0) + return err_key_parse("bitmap", "values can't be negative"); + out->bitmap[i] = temp_i; + } + } + + /* check everything parsed, expect 1 more array */ + ctx.array_cnt += 1; + ret = assert_everything_parsed(signed_pkg, &ctx); + if (ret < 0) + return ret; + + /* modules array */ + module_array = toml_array_in(signed_pkg, "module"); + if (!module_array) + return err_key_not_found("module"); + if (toml_array_kind(module_array) != 't' || + toml_array_nelem(module_array) != ARRAY_SIZE(out->module)) + return err_key_parse("module", "wrong array type or length != %d", + ARRAY_SIZE(out->module)); + + /* parse modules array elements */ + for (i = 0; i < toml_array_nelem(module_array); ++i) { + module = toml_table_at(module_array, i); + if (!module) + return err_key_parse("module", NULL); + mod = &out->module[i]; + + /* initialize parse context for each array element */ + parse_ctx_init(&ctx); + + /* non-configurable fields */ + + /* configurable fields */ + parse_printable_key(module, &ctx, "name", mod->name, sizeof(mod->name), &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + mod->type = parse_uint32_hex_key(module, &ctx, "type", 0x03, &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + mod->hash_algo = parse_uint32_hex_key(module, &ctx, "hash_algo", 0x00, &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + mod->hash_size = parse_uint32_hex_key(module, &ctx, "hash_size", 0x30, &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + mod->meta_size = parse_uint32_key(module, &ctx, "meta_size", 112, &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + /* check everything parsed */ + ret = assert_everything_parsed(module, &ctx); + if (ret < 0) + return ret; + } + + if (verbose) + dump_signed_pkg_v2_5(out); + + /* + * values set in other places in code: + * - module.hash + */ + + return 0; +} + +static void dump_signed_pkg_ace_v1_5(const struct signed_pkg_info_ext_ace_v1_5 *signed_pkg) +{ + int i; + + DUMP("\nsigned_pkg"); + DUMP_KEY("name", "'%s'", signed_pkg->name); + DUMP_KEY("vcn", "%d", signed_pkg->vcn); + DUMP_KEY("svn", "%d", signed_pkg->svn); + DUMP_KEY("fw_type", "%d", signed_pkg->fw_type); + DUMP_KEY("fw_sub_type", "%d", signed_pkg->fw_sub_type); + for (i = 0; i < ARRAY_SIZE(signed_pkg->module); ++i) { + DUMP_KEY("meta.name", "'%s'", signed_pkg->module[i].name); + DUMP_KEY("meta.type", "0x%x", signed_pkg->module[i].type); + } +} + +static int parse_signed_pkg_ace_v1_5(const toml_table_t *toml, struct parse_ctx *pctx, + struct image *image, bool verbose) +{ + struct adsp *adsp = image->adsp; + struct signed_pkg_info_ext_ace_v1_5 *out = &adsp->man_ace_v1_5->signed_pkg; + struct signed_pkg_info_module_ace_v1_5 *mod; + toml_array_t *module_array; + toml_table_t *signed_pkg; + struct parse_ctx ctx; + toml_table_t *module; + int ret; + int i; + + /* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */ + signed_pkg = toml_table_in(toml, "signed_pkg"); + if (!signed_pkg) + return err_key_not_found("signed_pkg"); + ++pctx->table_cnt; + parse_ctx_init(&ctx); + + /* non-configurable fields */ + out->ext_type = SIGN_PKG_EXT_TYPE_ACE_V1_5; + out->ext_len = sizeof(struct signed_pkg_info_ext_ace_v1_5); + + /* configurable fields */ + parse_printable_key(signed_pkg, &ctx, "name", out->name, sizeof(out->name), &ret); + if (ret < 0) + return ret; + + out->vcn = parse_uint32_key(signed_pkg, &ctx, "vcn", 0, &ret); + if (ret < 0) + return ret; + + out->svn = parse_uint32_key(signed_pkg, &ctx, "svn", 0, &ret); + if (ret < 0) + return ret; + + out->fw_type = parse_uint32_hex_key(signed_pkg, &ctx, "fw_type", 0, &ret); + if (ret < 0) + return ret; + + out->fw_sub_type = parse_uint32_hex_key(signed_pkg, &ctx, "fw_sub_type", 0, &ret); + if (ret < 0) + return ret; + + out->partition_usage = 0x20 + image->imr_type; + + /* check everything parsed, expect 1 more array */ + ctx.array_cnt += 1; + ret = assert_everything_parsed(signed_pkg, &ctx); + if (ret < 0) + return ret; + + /* modules array */ + module_array = toml_array_in(signed_pkg, "module"); + if (!module_array) + return err_key_not_found("module"); + if (toml_array_kind(module_array) != 't' || + toml_array_nelem(module_array) != ARRAY_SIZE(out->module)) + return err_key_parse("module", "wrong array type or length != %d", + ARRAY_SIZE(out->module)); + + /* parse modules array elements */ + for (i = 0; i < toml_array_nelem(module_array); ++i) { + module = toml_table_at(module_array, i); + if (!module) + return err_key_parse("module", NULL); + mod = &out->module[i]; + + /* initialize parse context for each array element */ + parse_ctx_init(&ctx); + + /* non-configurable fields */ + + /* configurable fields */ + parse_printable_key(module, &ctx, "name", mod->name, sizeof(mod->name), &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + mod->type = parse_uint32_hex_key(module, &ctx, "type", 0x03, &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + mod->hash_algo = parse_uint32_hex_key(module, &ctx, "hash_algo", 0x00, &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + mod->meta_size = parse_uint32_key(module, &ctx, "meta_size", 112, &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + /* check everything parsed */ + ret = assert_everything_parsed(module, &ctx); + if (ret < 0) + return ret; + } + + if (verbose) + dump_signed_pkg_ace_v1_5(out); + + /* + * values set in other places in code: + * - module.hash + */ + + return 0; +} + +static void dump_partition_info_ext(const struct partition_info_ext *part_info) +{ + int i; + + DUMP("\npartition_info"); + DUMP_PRINTABLE_BYTES("name", part_info->name); + DUMP_KEY("part_version", "0x%x", part_info->part_version); + DUMP_KEY("instance_id", "%d", part_info->instance_id); + for (i = 0; i < ARRAY_SIZE(part_info->module); ++i) { + DUMP_PRINTABLE_BYTES("module.name", part_info->module[i].name); + DUMP_KEY("module.meta_size", "0x%x", part_info->module[i].meta_size); + DUMP_KEY("module.type", "0x%x", part_info->module[i].type); + } +} + +static int parse_partition_info_ext(const toml_table_t *toml, struct parse_ctx *pctx, + struct partition_info_ext *out, bool verbose) +{ + static const uint8_t module_reserved[3] = {0x00, 0xff, 0xff}; + struct partition_info_module *mod; + toml_table_t *partition_info; + toml_array_t *module_array; + toml_table_t *module; + struct parse_ctx ctx; + int ret; + int i; + + /* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */ + partition_info = toml_table_in(toml, "partition_info"); + if (!partition_info) + return err_key_not_found("partition_info"); + ++pctx->table_cnt; + parse_ctx_init(&ctx); + + /* non-configurable fields */ + out->ext_type = PART_INFO_EXT_TYPE; + out->ext_len = sizeof(struct partition_info_ext); + memset(out->reserved, 0xff, sizeof(out->reserved)); + + /* configurable fields */ + parse_printable_key(partition_info, &ctx, "name", out->name, sizeof(out->name), &ret); + if (ret < 0) + return ret; + + out->vcn = parse_uint32_key(partition_info, &ctx, "vcn", 0, &ret); + if (ret < 0) + return ret; + + out->part_version = + parse_uint32_hex_key(partition_info, &ctx, "part_version", 0x10000000, &ret); + if (ret < 0) + return ret; + + out->vcn = parse_uint32_hex_key(partition_info, &ctx, "part_version", 0x10000000, &ret); + if (ret < 0) + return ret; + + out->vcn = parse_uint32_hex_key(partition_info, &ctx, "fmt_version", 0, &ret); + if (ret < 0) + return ret; + + out->instance_id = parse_uint32_key(partition_info, &ctx, "instance_id", 1, &ret); + if (ret < 0) + return ret; + + out->part_flags = parse_uint32_key(partition_info, &ctx, "part_flags", 0, &ret); + if (ret < 0) + return ret; + + /* check everything parsed, expect 1 array */ + ctx.array_cnt += 1; + ret = assert_everything_parsed(partition_info, &ctx); + if (ret < 0) + return ret; + + /* look for module array */ + module_array = toml_array_in(partition_info, "module"); + if (!module_array) + return err_key_not_found("module"); + if (toml_array_kind(module_array) != 't' || + toml_array_nelem(module_array) > ARRAY_SIZE(out->module)) + return err_key_parse("module", "wrong array type or length > %d", + ARRAY_SIZE(out->module)); + + /* parse module array elements */ + for (i = 0; i < toml_array_nelem(module_array); ++i) { + module = toml_table_at(module_array, i); + if (!module) + return err_key_parse("module", NULL); + mod = &out->module[i]; + + /* initialize parse context for each array element */ + parse_ctx_init(&ctx); + + /* non-configurable fields */ + memcpy(mod->reserved, module_reserved, sizeof(mod->reserved)); + + /* configurable fields */ + parse_printable_key(module, &ctx, "name", mod->name, sizeof(mod->name), &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + mod->meta_size = parse_uint32_key(module, &ctx, "meta_size", 96, &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + mod->type = parse_uint32_hex_key(module, &ctx, "type", 0x03, &ret); + if (ret < 0) + return err_key_parse("module", NULL); + + /* check everything parsed */ + ret = assert_everything_parsed(module, &ctx); + if (ret < 0) + return ret; + } + + if (verbose) + dump_partition_info_ext(out); + + /* + * values set in other places in code: + * - length + * - hash + * - module.hash + */ + + return 0; +} + +static int parse_info_ext_0x16(const toml_table_t *toml, struct parse_ctx *pctx, + struct info_ext_0x16 *out, bool verbose) +{ + /* known */ + out->ext_type = 0x16; + out->ext_len = sizeof(*out); + out->name[0] = 'A'; + out->name[1] = 'D'; + out->name[2] = 'S'; + out->name[3] = 'P'; + + /* copied from meu - unknown */ + out->data[0] = 0x10000000; + out->data[2] = 0x1; + out->data[3] = 0x0; + out->data[4] = 0x3003; + + return 0; +} + +static void dump_adsp_file_ext_v1_8(const struct sof_man_adsp_meta_file_ext_v1_8 *adsp_file) +{ + int i; + int j; + + DUMP("\nadsp_file_ext 1.8"); + DUMP_KEY("imr_type", "0x%x", adsp_file->imr_type); + for (i = 0; i < ARRAY_SIZE(adsp_file->comp_desc); ++i) { + DUMP_KEY("comp.version", "0x%x", adsp_file->comp_desc[i].version); + DUMP_KEY("comp.base_offset", "0x%x", adsp_file->comp_desc[i].base_offset); + for (j = 0; j < ARRAY_SIZE(adsp_file->comp_desc->attributes); ++j) + DUMP_KEY("comp.atributes[]", "%d", adsp_file->comp_desc[i].attributes[j]); + } +} + +static int parse_adsp_file_ext_v1_8(const toml_table_t *toml, struct parse_ctx *pctx, + struct sof_man_adsp_meta_file_ext_v1_8 *out, bool verbose) +{ + struct sof_man_component_desc_v1_8 *desc; + toml_array_t *attributes_array; + toml_table_t *adsp_file_ext; + toml_array_t *comp_array; + struct parse_ctx ctx; + toml_raw_t attribute; + toml_table_t *comp; + int64_t temp_i; + int ret; + int i; + int j; + + /* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */ + adsp_file_ext = toml_table_in(toml, "adsp_file"); + if (!adsp_file_ext) + return err_key_not_found("adsp_file"); + ++pctx->table_cnt; + parse_ctx_init(&ctx); + + /* non configurable flieds */ + out->ext_type = 17; /* always 17 for ADSP extension */ + out->ext_len = sizeof(struct sof_man_adsp_meta_file_ext_v1_8); + + /* configurable fields */ + out->imr_type = parse_uint32_hex_key(adsp_file_ext, &ctx, "imr_type", + MAN_DEFAULT_IMR_TYPE, &ret); + if (ret < 0) + return ret; + + /* check everything parsed, expect 1 array */ + ctx.array_cnt += 1; + ret = assert_everything_parsed(adsp_file_ext, &ctx); + if (ret < 0) + return ret; + + /* parse comp array */ + comp_array = toml_array_in(adsp_file_ext, "comp"); + if (!comp_array) + return err_key_not_found("comp"); + if (toml_array_nelem(comp_array) != 1 || toml_array_kind(comp_array) != 't') + return err_key_parse("comp", "wrong array type or length != 1"); + + /* parse comp array elements */ + for (i = 0; i < toml_array_nelem(comp_array); ++i) { + comp = toml_table_at(comp_array, i); + if (!comp) + return err_key_parse("comp", NULL); + desc = &out->comp_desc[i]; + + /* initialize parse context for each array element */ + parse_ctx_init(&ctx); + + /* non-configurable fields */ + + /* configurable fields */ + desc->version = parse_uint32_key(comp, &ctx, "version", 0, &ret); + if (ret < 0) + return err_key_parse("comp", NULL); + + desc->base_offset = parse_uint32_hex_key(comp, &ctx, "base_offset", + MAN_DESC_OFFSET_V1_8, &ret); + if (ret < 0) + return err_key_parse("comp", NULL); + + /* parse attributes array */ + attributes_array = toml_array_in(comp, "attributes"); + if (attributes_array) { + ++ctx.array_cnt; + if (toml_array_nelem(attributes_array) > ARRAY_SIZE(desc->attributes) || + toml_array_kind(attributes_array) != 'v' || + toml_array_type(attributes_array) != 'i') + return err_key_parse("comp.attributes", + "wrong array type or length > %d", + ARRAY_SIZE(desc->attributes)); + for (j = 0; j < toml_array_nelem(attributes_array); ++j) { + attribute = toml_raw_at(attributes_array, j); + if (!attribute) + err_key_parse("comp.attributes", NULL); + ret = toml_rtoi(attribute, &temp_i); + if (ret < 0 || temp_i < 0 || temp_i > UINT32_MAX) + err_key_parse("comp.attributes", NULL); + desc->attributes[j] = (uint32_t)temp_i; + } + } + + /* check everything parsed */ + ret = assert_everything_parsed(comp, &ctx); + if (ret < 0) + return ret; + } + + if (verbose) + dump_adsp_file_ext_v1_8(out); + + /* + * values set in other places in code: + * - imr_type + * - comp.limit_offset + */ + + return 0; +} + +static void dump_adsp_file_ext_v2_5(const struct sof_man_adsp_meta_file_ext_v2_5 *adsp_file) +{ + int i; + int j; + + DUMP("\nadsp_file 2.5"); + DUMP_KEY("imr_type", "0x%x", adsp_file->imr_type); + for (i = 0; i < ARRAY_SIZE(adsp_file->comp_desc); ++i) { + DUMP_KEY("comp.version", "0x%x", adsp_file->comp_desc[i].version); + DUMP_KEY("comp.base_offset", "0x%x", adsp_file->comp_desc[i].base_offset); + for (j = 0; j < ARRAY_SIZE(adsp_file->comp_desc->attributes); ++j) + DUMP_KEY("comp.atributes[]", "%d", adsp_file->comp_desc[i].attributes[j]); + } +} + +static int parse_adsp_file_ext_v2_5(const toml_table_t *toml, struct parse_ctx *pctx, + struct sof_man_adsp_meta_file_ext_v2_5 *out, bool verbose) +{ + struct sof_man_component_desc_v2_5 *desc; + toml_array_t *attributes_array; + toml_table_t *adsp_file_ext; + toml_array_t *comp_array; + struct parse_ctx ctx; + toml_raw_t attribute; + toml_table_t *comp; + int64_t temp_i; + int ret; + int i; + int j; + + /* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */ + adsp_file_ext = toml_table_in(toml, "adsp_file"); + if (!adsp_file_ext) + return err_key_not_found("adsp_file"); + ++pctx->table_cnt; + parse_ctx_init(&ctx); + + /* non configurable flieds */ + out->ext_type = 17; /* always 17 for ADSP extension */ + out->ext_len = sizeof(struct sof_man_adsp_meta_file_ext_v2_5); + + /* configurable fields */ + out->imr_type = parse_uint32_hex_key(adsp_file_ext, &ctx, "imr_type", + MAN_DEFAULT_IMR_TYPE, &ret); + if (ret < 0) + return ret; + + /* check everything parsed, expect 1 array */ + ctx.array_cnt += 1; + ret = assert_everything_parsed(adsp_file_ext, &ctx); + if (ret < 0) + return ret; + + /* parse comp array */ + comp_array = toml_array_in(adsp_file_ext, "comp"); + if (!comp_array) + return err_key_not_found("comp"); + if (toml_array_nelem(comp_array) != 1 || toml_array_kind(comp_array) != 't') + return err_key_parse("comp", "wrong array type or length != 1"); + + /* parse comp array elements */ + for (i = 0; i < toml_array_nelem(comp_array); ++i) { + comp = toml_table_at(comp_array, i); + if (!comp) + return err_key_parse("comp", NULL); + desc = &out->comp_desc[i]; + + /* initialize parse context for each array element */ + parse_ctx_init(&ctx); + + /* non configurable flieds */ + + /* configurable fields */ + desc->version = parse_uint32_key(comp, &ctx, "version", 0, &ret); + if (ret < 0) + return err_key_parse("comp", NULL); + + desc->base_offset = parse_uint32_hex_key(comp, &ctx, "base_offset", 0x2000, &ret); + if (ret < 0) + return err_key_parse("comp", NULL); + + /* parse attributes array */ + attributes_array = toml_array_in(comp, "attributes"); + if (attributes_array) { + ++ctx.array_cnt; + if (toml_array_nelem(attributes_array) > ARRAY_SIZE(desc->attributes) || + toml_array_kind(attributes_array) != 'v' || + toml_array_type(attributes_array) != 'i') + return err_key_parse("comp.attributes", + "wrong array type or length > %d", + ARRAY_SIZE(desc->attributes)); + for (j = 0; j < toml_array_nelem(attributes_array); ++j) { + attribute = toml_raw_at(attributes_array, j); + if (!attribute) + err_key_parse("comp.attributes", NULL); + ret = toml_rtoi(attribute, &temp_i); + if (ret < 0 || temp_i < 0 || temp_i > UINT32_MAX) + err_key_parse("comp.attributes", NULL); + desc->attributes[j] = (uint32_t)temp_i; + } + } + + /* check everything parsed */ + ret = assert_everything_parsed(comp, &ctx); + if (ret < 0) + return ret; + } + + if (verbose) + dump_adsp_file_ext_v2_5(out); + + /* + * values set in other places in code: + * - imr_type + * - comp.limit_offset + */ + + return 0; +} + +static void dump_fw_desc(const struct sof_man_fw_desc *fw_desc) +{ + DUMP("\nfw_desc.header"); + DUMP_KEY("header_id", "'%c%c%c%c'", fw_desc->header.header_id[0], + fw_desc->header.header_id[1], fw_desc->header.header_id[2], + fw_desc->header.header_id[3]); + DUMP_PRINTABLE_BYTES("name", fw_desc->header.name); + DUMP_KEY("preload_page_count", "%d", fw_desc->header.preload_page_count); + DUMP_KEY("fw_image_flags", "0x%x", fw_desc->header.fw_image_flags); + DUMP_KEY("feature_mask", "0x%x", fw_desc->header.feature_mask); + DUMP_KEY("hw_buf_base_addr", "0x%x", fw_desc->header.fw_compat); + DUMP_KEY("hw_buf_length", "0x%x", fw_desc->header.hw_buf_length); + DUMP_KEY("load_offset", "0x%x", fw_desc->header.load_offset); +} + +static int parse_fw_desc(const toml_table_t *toml, struct parse_ctx *pctx, + struct sof_man_fw_desc *out, bool verbose) +{ + static const uint8_t header_id[4] = SOF_MAN_FW_HDR_ID; + struct parse_ctx ctx; + toml_table_t *header; + toml_table_t *desc; + int ret; + + /* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */ + desc = toml_table_in(toml, "fw_desc"); + if (!desc) + return err_key_not_found("fw_desc"); + ++pctx->table_cnt; + parse_ctx_init(&ctx); + + header = toml_table_in(desc, "header"); + if (!header) + return err_key_not_found("header"); + ++ctx.table_cnt; + + /* check everything parsed */ + ret = assert_everything_parsed(desc, &ctx); + if (ret < 0) + return ret; + + /* initialize parser context for header subtable */ + parse_ctx_init(&ctx); + + /* non configurable flieds */ + memcpy(&out->header.header_id, header_id, sizeof(header_id)); + out->header.header_len = sizeof(struct sof_man_fw_header); + + /* configurable fields */ + parse_printable_key(header, &ctx, "name", out->header.name, sizeof(out->header.name), + &ret); + if (ret < 0) + return err_key_parse("header", NULL); + + out->header.preload_page_count = + parse_uint32_key(header, &ctx, "preload_page_count", 0, &ret); + if (ret < 0) + return err_key_parse("header", NULL); + + out->header.fw_image_flags = + parse_uint32_hex_key(header, &ctx, "fw_image_flags", SOF_MAN_FW_HDR_FLAGS, &ret); + if (ret < 0) + return err_key_parse("header", NULL); + + out->header.feature_mask = + parse_uint32_hex_key(header, &ctx, "feature_mask", SOF_MAN_FW_HDR_FEATURES, &ret); + if (ret < 0) + return err_key_parse("header", NULL); + + out->header.fw_compat = + parse_uint32_hex_key(header, &ctx, "hw_buf_base_addr", 0, &ret); + if (ret < 0) + return err_key_parse("header", NULL); + + out->header.hw_buf_length = parse_uint32_hex_key(header, &ctx, "hw_buf_length", 0, &ret); + if (ret < 0) + return err_key_parse("header", NULL); + + out->header.load_offset = parse_uint32_hex_key(header, &ctx, "load_offset", -1, &ret); + if (ret < 0) + return err_key_parse("header", NULL); + + /* check everything parsed */ + ret = assert_everything_parsed(header, &ctx); + if (ret < 0) + return ret; + + if (verbose) + dump_fw_desc(out); + + /* + * values set in other places in code: + * - major_version + * - minor_version + * - build_version + * - num_module_entries + */ + + return 0; +} + +static int parse_scheduling(const toml_table_t *mod_entry, struct parse_ctx *ctx, + struct fw_image_ext_mod_config *ext_mod_config, int *ext_length) +{ + toml_array_t *arr; + toml_raw_t raw; + int64_t val; + int ret; + + /* check "sched_caps" key */ + arr = toml_array_in(mod_entry, "sched_caps"); + if (!arr) { + ext_mod_config->header.num_scheduling_capabilities = 0; + *ext_length = 0; + return 0; + } + + if (toml_array_type(arr) != 'i' || toml_array_nelem(arr) != 2 || + toml_array_kind(arr) != 'v') + return err_key_parse("sched_caps", "wrong array type or length != 2"); + + ctx->array_cnt++; + + raw = toml_raw_at(arr, 0); + if (raw == 0) + return err_key_parse("frame_length", NULL); + ret = toml_rtoi(raw, &val); + if (ret < 0) + return err_key_parse("frame_length", "can't convert element to integer"); + ext_mod_config->sched_caps.frame_length = val; + + raw = toml_raw_at(arr, 1); + if (raw == 0) + return err_key_parse("multiples_supported", NULL); + ret = toml_rtoi(raw, &val); + if (ret < 0) + return err_key_parse("multiples_supported", "can't convert element to integer"); + ext_mod_config->sched_caps.multiples_supported.ul = val; + + ext_mod_config->header.num_scheduling_capabilities = 1; + *ext_length = sizeof(const struct mod_scheduling_caps); + + return 0; +} + +static int parse_pin(const toml_table_t *mod_entry, struct parse_ctx *ctx, + struct fw_image_ext_mod_config *ext_mod_config, int *ext_length) +{ + toml_array_t *arr; + toml_raw_t raw; + int64_t val; + int ret; + int i, j; + + /* check "pin" key */ + arr = toml_array_in(mod_entry, "pin"); + if (!arr) { + ext_mod_config->header.num_pin_entries = 0; + *ext_length = 0; + return 0; + } + + if (toml_array_type(arr) != 'i' || toml_array_kind(arr) != 'v') + return err_key_parse("pin", "wrong array type"); + + ctx->array_cnt++; + + ext_mod_config->header.num_pin_entries = toml_array_nelem(arr) / 6; + ext_mod_config->pin_desc = calloc(sizeof(const struct fw_pin_description), + toml_array_nelem(arr) / 6); + + if(!ext_mod_config->pin_desc) + return err_malloc("pin"); + + j = 0; + for (i = 0; ; i += 6, j++) { + raw = toml_raw_at(arr, i); + if (raw == 0) + break; + + ret = toml_rtoi(raw, &val); + if (ret < 0) + return err_key_parse("pin", "can't convert element to integer"); + ext_mod_config->pin_desc[j].caps.ul = (uint16_t)val; + + raw = toml_raw_at(arr, i + 1); + ret = toml_rtoi(raw, &val); + if (ret < 0) + return err_key_parse("pin", "can't convert element to integer"); + ext_mod_config->pin_desc[j].format_type = (enum mod_stream_type)val; + + raw = toml_raw_at(arr, i + 2); + ret = toml_rtoi(raw, &val); + if (ret < 0) + return err_key_parse("pin", "can't convert element to integer"); + ext_mod_config->pin_desc[j].sample_rate.ul = (uint32_t)val; + + raw = toml_raw_at(arr, i + 3); + ret = toml_rtoi(raw, &val); + if (ret < 0) + return err_key_parse("pin", "can't convert element to integer"); + ext_mod_config->pin_desc[j].sample_size.ul = (uint16_t)val; + + raw = toml_raw_at(arr, i + 4); + ret = toml_rtoi(raw, &val); + if (ret < 0) + return err_key_parse("pin", "can't convert element to integer"); + ext_mod_config->pin_desc[j].sample_container.ul = (uint32_t)val; + + raw = toml_raw_at(arr, i + 5); + ret = toml_rtoi(raw, &val); + if (ret < 0) + return err_key_parse("pin", "can't convert element to integer"); + ext_mod_config->pin_desc[j].ch_cfg.ul = (uint32_t)val; + } + + *ext_length = ext_mod_config->header.num_pin_entries * + sizeof(const struct fw_pin_description); + + return 0; +} + +static int parse_mod_config(const toml_table_t *mod_entry, struct parse_ctx *ctx, + struct fw_image_manifest_module *modules, + struct sof_man_module *mod_man) +{ + toml_array_t *arr; + toml_raw_t raw; + int *pin_data; + int64_t val; + int ret; + int i; + + /* check "pin" key */ + arr = toml_array_in(mod_entry, "mod_cfg"); + if (!arr) { + mod_man->cfg_count = 0; + return 0; + } + + if (toml_array_type(arr) != 'i' || toml_array_kind(arr) != 'v') + return err_key_parse("mod_cfg", "wrong array type"); + + ctx->array_cnt++; + + pin_data = (int *)(modules->mod_cfg + modules->mod_cfg_count); + mod_man->cfg_offset = modules->mod_cfg_count; + modules->mod_cfg_count += toml_array_nelem(arr) / 11; + mod_man->cfg_count = toml_array_nelem(arr) / 11; + + /* parse "pin" array elements */ + for (i = 0; ; ++i) { + raw = toml_raw_at(arr, i); + if (raw == 0) + break; + + ret = toml_rtoi(raw, &val); + if (ret < 0) + return err_key_parse("mod_cfg", "can't convert element to integer"); + pin_data[i] = val; + } + + return 0; +} + +static void dump_module(struct fw_image_manifest_module *man_cavs) +{ + int i; + + DUMP("\nmodule"); + DUMP_KEY("moudle count", "%d", man_cavs->mod_man_count); + DUMP_KEY("module config count", "%d", man_cavs->mod_cfg_count); + + for (i = 0; i < man_cavs->mod_man_count; i++) { + DUMP_PRINTABLE_BYTES("module name", man_cavs->mod_man[i].name); + DUMP_KEY("load type", "%d", man_cavs->mod_man[i].type.load_type); + DUMP_KEY("init config", "%d", man_cavs->mod_man[i].type.init_config); + DUMP_KEY("domain ll", "%d", man_cavs->mod_man[i].type.domain_ll); + DUMP_KEY("domain dp", "%d", man_cavs->mod_man[i].type.domain_dp); + DUMP_KEY("config count", "%d", man_cavs->mod_man[i].cfg_count); + DUMP_KEY("config offset", "%d", man_cavs->mod_man[i].cfg_offset); + } +} + +static int parse_module(const toml_table_t *toml, struct parse_ctx *pctx, + struct adsp *out, bool verbose) +{ + struct fw_image_manifest_module *modules; + toml_array_t *mod_entry_array; + toml_table_t *module; + toml_table_t *mod_entry; + struct parse_ctx ctx; + int entry_count; + int type, ext_length; + int tmp_cfg_count; + int ret, i; + + /* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */ + module = toml_table_in(toml, "module"); + if (!module) + return 0; + + out->write_firmware_ext_man = ext_man_write_cavs_25; + + modules = calloc(sizeof(struct fw_image_manifest_module), 1); + if (!modules) + return err_malloc("man_cavs"); + out->modules = modules; + + ++pctx->table_cnt; + parse_ctx_init(&ctx); + + entry_count = parse_uint32_key(module, &ctx, "count", 2, &ret); + if (ret < 0) + return ret; + + ctx.array_cnt += 1; + + mod_entry_array = toml_array_in(module, "entry"); + if (!mod_entry_array) + return err_key_not_found("entry"); + if (toml_array_kind(mod_entry_array) != 't' || + toml_array_nelem(mod_entry_array) != entry_count) + return err_key_parse("entry", "wrong array type or length != %d", entry_count); + + modules->mod_ext.mod_conf_count = entry_count; + modules->mod_man = calloc(sizeof(const struct sof_man_module), entry_count); + if (!modules->mod_man) + return -ENOMEM; + + modules->mod_man_count = toml_array_nelem(mod_entry_array); + + tmp_cfg_count = entry_count * 32; + modules->mod_cfg = calloc(sizeof(const struct sof_man_mod_config), tmp_cfg_count); + + /* parse entry array elements */ + for (i = 0; i < toml_array_nelem(mod_entry_array); ++i) { + struct fw_ext_mod_config_header *header; + struct sof_man_module *mod_man; + struct parse_ctx ctx_entry; + char buf[48]; + + mod_entry = toml_table_at(mod_entry_array, i); + if (!mod_entry) + return err_key_parse("entry", NULL); + + /* initialize parse context for each array element */ + parse_ctx_init(&ctx_entry); + + mod_man = &modules->mod_man[i]; + + memcpy(mod_man->struct_id, "$AME", 4); + + /* configurable fields */ + parse_printable_key(mod_entry, &ctx_entry, "name", mod_man->name, + sizeof(mod_man->name), &ret); + if (ret < 0) + return err_key_parse("name", NULL); + + parse_str_key(mod_entry, &ctx_entry, "uuid", buf, sizeof(buf), + &ret); + if (ret < 0) + return err_key_parse("uuid", NULL); + + parse_uuid(buf, mod_man->uuid); + + mod_man->affinity_mask = parse_uint32_hex_key(mod_entry, &ctx_entry, + "affinity_mask", 1, &ret); + if (ret < 0) + return err_key_parse("affinity_mask", NULL); + + mod_man->instance_max_count = parse_uint32_hex_key(mod_entry, &ctx_entry, + "instance_count", 1, &ret); + if (ret < 0) + return err_key_parse("instance_count", NULL); + + type = parse_uint32_hex_key(mod_entry, &ctx_entry, "domain_types", 0, &ret); + if (ret < 0) + return err_key_parse("domain_types", NULL); + if (!type) + mod_man->type.domain_ll = 1; + else + mod_man->type.domain_dp = 1; + + mod_man->type.load_type = parse_uint32_hex_key(mod_entry, &ctx_entry, + "load_type", 1, &ret); + if (ret < 0) + return err_key_parse("load_type", NULL); + + mod_man->type.init_config = parse_uint32_hex_key(mod_entry, &ctx_entry, + "init_config", 0, &ret); + if (ret < 0) + return err_key_parse("init_config", NULL); + + mod_man->type.auto_start = parse_uint32_hex_key(mod_entry, &ctx_entry, + "auto_start", 1, &ret); + if (ret < 0) + return err_key_parse("auto_start", NULL); + + header = &modules->mod_ext.ext_mod_config_array[i].header; + header->version_major = 2; + header->version_minor = 5; + header->ext_module_config_length = sizeof(struct fw_ext_mod_config_header); + memcpy(header->guid, mod_man->uuid, sizeof(mod_man->uuid)); + + type = parse_uint32_hex_key(mod_entry, &ctx_entry, "module_type", 1, &ret); + if (ret < 0) + return err_key_parse("module_type", NULL); + + header->module_type = type; + + ret = parse_scheduling(mod_entry, &ctx_entry, + modules->mod_ext.ext_mod_config_array + i, &ext_length); + if (ret < 0) + return err_key_parse("schd_caps", NULL); + header->ext_module_config_length += ext_length; + + ret = parse_pin(mod_entry, &ctx_entry, modules->mod_ext.ext_mod_config_array + i, + &ext_length); + if (ret < 0) + return err_key_parse("pin", NULL); + header->ext_module_config_length += ext_length; + + ret = parse_mod_config(mod_entry, &ctx_entry, modules, mod_man); + if (ret < 0) + return err_key_parse("mod_cfg", NULL); + + if (modules->mod_cfg_count > tmp_cfg_count) + return -ENOMEM; + + /* check everything parsed */ + ret = assert_everything_parsed(mod_entry, &ctx_entry); + if (ret < 0) + return ret; + } + + /* check everything parsed */ + ret = assert_everything_parsed(module, &ctx); + if (ret < 0) + return ret; + + if (verbose) + dump_module(modules); + + return 0; +} + +static int parse_adsp_config_v1_0(const toml_table_t *toml, struct image *image) +{ + struct adsp *out = image->adsp; + bool verbose = image->verbose; + struct parse_ctx ctx; + int ret; + + /* version array has already been parsed, so increment ctx.array_cnt */ + parse_ctx_init(&ctx); + ++ctx.array_cnt; + + /* parse each adsp subtable, sue platform has different manifest definition */ + ret = parse_adsp(toml, &ctx, out, verbose); + if (ret < 0) + return err_key_parse("adsp", NULL); + + /* assign correct write functions */ + out->write_firmware = simple_write_firmware; + out->write_firmware_meu = NULL; + + /* check everything parsed */ + ret = assert_everything_parsed(toml, &ctx); + if (ret < 0) + return ret; + + return 0; +} + +static int parse_adsp_config_v1_5(const toml_table_t *toml, struct image *image) +{ + struct adsp *out = image->adsp; + bool verbose = image->verbose; + struct parse_ctx ctx; + int ret; + + /* version array has already been parsed, so increment ctx.array_cnt */ + parse_ctx_init(&ctx); + ++ctx.array_cnt; + + /* parse each adsp subtable, sue platform has different manifest definition */ + ret = parse_adsp(toml, &ctx, out, verbose); + if (ret < 0) + return err_key_parse("adsp", NULL); + + /* suecreek has dedicated manifest file */ + if (!strcmp(out->name, "sue")) { + /* out free is done in client code */ + out->man_v1_5_sue = malloc(sizeof(struct fw_image_manifest_v1_5_sue)); + if (!out->man_v1_5_sue) + return err_malloc("man_v1_5_sue"); + + /* clear memory */ + memset(out->man_v1_5_sue, 0, sizeof(*out->man_v1_5_sue)); + + /* assign correct write functions */ + out->write_firmware = man_write_fw_v1_5_sue; + out->write_firmware_meu = man_write_fw_meu_v1_5; + out->verify_firmware = ri_manifest_verify_v1_5; + + /* parse others sibtables */ + ret = parse_fw_desc(toml, &ctx, &out->man_v1_5_sue->desc, verbose); + if (ret < 0) + return err_key_parse("fw_desc", NULL); + } else { + /* out free is done in client code */ + out->man_v1_5 = malloc(sizeof(struct fw_image_manifest_v1_5)); + if (!out->man_v1_5) + return err_malloc("man_v1_5"); + + /* clear memory */ + memset(out->man_v1_5, 0, sizeof(*out->man_v1_5)); + + /* assign correct write functions */ + out->write_firmware = man_write_fw_v1_5; + out->write_firmware_meu = man_write_fw_meu_v1_5; + out->verify_firmware = ri_manifest_verify_v1_5; + + /* parse others sibtables */ + ret = parse_css_v1_5(toml, &ctx, &out->man_v1_5->css_header, verbose); + if (ret < 0) + return err_key_parse("css", NULL); + + ret = parse_fw_desc(toml, &ctx, &out->man_v1_5->desc, verbose); + if (ret < 0) + return err_key_parse("fw_desc", NULL); + } + + /* check everything parsed */ + ret = assert_everything_parsed(toml, &ctx); + if (ret < 0) + return ret; + + return 0; +} + +static int parse_adsp_config_v1_8(const toml_table_t *toml, struct image *image) +{ + struct adsp *out = image->adsp; + bool verbose = image->verbose; + struct parse_ctx ctx; + int ret; + + /* out free is done in client code */ + out->man_v1_8 = malloc(sizeof(struct fw_image_manifest_v1_8)); + if (!out->man_v1_8) + return err_malloc("man_v1_8"); + + /* clear memory */ + memset(out->man_v1_8, 0, sizeof(*out->man_v1_8)); + + /* assign correct write functions */ + out->write_firmware = man_write_fw_v1_8; + out->write_firmware_meu = man_write_fw_meu_v1_8; + out->verify_firmware = ri_manifest_verify_v1_8; + + /* version array has already been parsed, so increment ctx.array_cnt */ + parse_ctx_init(&ctx); + ++ctx.array_cnt; + + /* parse each toml subtable */ + ret = parse_adsp(toml, &ctx, out, verbose); + if (ret < 0) + return err_key_parse("adsp", NULL); + + ret = parse_cse(toml, &ctx, &out->man_v1_8->cse_partition_dir_header, + out->man_v1_8->cse_partition_dir_entry, MAN_CSE_PARTS, verbose); + if (ret < 0) + return err_key_parse("cse", NULL); + + ret = parse_css_v1_8(toml, &ctx, &out->man_v1_8->css, verbose); + if (ret < 0) + return err_key_parse("css", NULL); + + ret = parse_signed_pkg(toml, &ctx, image, verbose); + if (ret < 0) + return err_key_parse("signed_pkg", NULL); + + ret = parse_partition_info_ext(toml, &ctx, &out->man_v1_8->partition_info, verbose); + if (ret < 0) + return err_key_parse("partition_info", NULL); + + ret = parse_adsp_file_ext_v1_8(toml, &ctx, &out->man_v1_8->adsp_file_ext, verbose); + if (ret < 0) + return err_key_parse("adsp_file", NULL); + + ret = parse_fw_desc(toml, &ctx, &out->man_v1_8->desc, verbose); + if (ret < 0) + return err_key_parse("fw_desc", NULL); + + /* check everything parsed */ + ret = assert_everything_parsed(toml, &ctx); + if (ret < 0) + return ret; + + return 0; +} + +static int parse_adsp_config_v2_5(const toml_table_t *toml, struct image *image) +{ + struct adsp *out = image->adsp; + bool verbose = image->verbose; + struct parse_ctx ctx; + int ret; + + /* out free is done in client code */ + out->man_v2_5 = malloc(sizeof(struct fw_image_manifest_v2_5)); + if (!out->man_v2_5) + return err_malloc("man_v2_5"); + + /* clear memory */ + memset(out->man_v2_5, 0, sizeof(*out->man_v2_5)); + + /* assign correct write functions */ + out->write_firmware = man_write_fw_v2_5; + out->write_firmware_meu = man_write_fw_meu_v2_5; + out->verify_firmware = ri_manifest_verify_v2_5; + + /* version array has already been parsed, so increment ctx.array_cnt */ + parse_ctx_init(&ctx); + ++ctx.array_cnt; + + /* parse each toml subtable */ + ret = parse_adsp(toml, &ctx, out, verbose); + if (ret < 0) + return err_key_parse("adsp", NULL); + + ret = parse_cse_v2_5(toml, &ctx, &out->man_v2_5->cse_partition_dir_header, + out->man_v2_5->cse_partition_dir_entry, MAN_CSE_PARTS, verbose); + if (ret < 0) + return err_key_parse("cse", NULL); + + ret = parse_css_v2_5(toml, &ctx, &out->man_v2_5->css, verbose); + if (ret < 0) + return err_key_parse("css", NULL); + + ret = parse_signed_pkg_v2_5(toml, &ctx, image, verbose); + if (ret < 0) + return err_key_parse("signed_pkg", NULL); + + ret = parse_info_ext_0x16(toml, &ctx, &out->man_v2_5->info_0x16, verbose); + if (ret < 0) + return err_key_parse("partition_info", NULL); + + ret = parse_adsp_file_ext_v2_5(toml, &ctx, &out->man_v2_5->adsp_file_ext, verbose); + if (ret < 0) + return err_key_parse("adsp_file", NULL); + + ret = parse_fw_desc(toml, &ctx, &out->man_v2_5->desc, verbose); + if (ret < 0) + return err_key_parse("fw_desc", NULL); + + ret = parse_module(toml, &ctx, out, verbose); + if (ret < 0) + return err_key_parse("module", NULL); + + /* check everything parsed */ + ret = assert_everything_parsed(toml, &ctx); + if (ret < 0) + return ret; + + return 0; +} + +static int parse_adsp_config_ace_v1_5(const toml_table_t *toml, struct image *image) +{ + struct adsp *out = image->adsp; + bool verbose = image->verbose; + struct parse_ctx ctx; + int ret; + + out->man_ace_v1_5 = malloc(sizeof(struct fw_image_manifest_ace_v1_5)); + if (!out->man_ace_v1_5) + return err_malloc("man_ace_v1_5"); + + /* clear memory */ + memset(out->man_ace_v1_5, 0, sizeof(*out->man_ace_v1_5)); + + /* assign correct write functions */ + out->write_firmware = man_write_fw_ace_v1_5; + out->write_firmware_meu = man_write_fw_meu_v2_5; + out->verify_firmware = ri_manifest_verify_v2_5; + + /* version array has already been parsed, so increment ctx.array_cnt */ + parse_ctx_init(&ctx); + ++ctx.array_cnt; + + /* parse each toml subtable */ + ret = parse_adsp(toml, &ctx, out, verbose); + if (ret < 0) + return err_key_parse("adsp", NULL); + + ret = parse_cse_v2_5(toml, &ctx, &out->man_ace_v1_5->cse_partition_dir_header, + out->man_ace_v1_5->cse_partition_dir_entry, 3, verbose); + if (ret < 0) + return err_key_parse("cse", NULL); + + ret = parse_css_v2_5(toml, &ctx, &out->man_ace_v1_5->css, verbose); + if (ret < 0) + return err_key_parse("css", NULL); + + ret = parse_signed_pkg_ace_v1_5(toml, &ctx, image, verbose); + if (ret < 0) + return err_key_parse("signed_pkg", NULL); + + ret = parse_info_ext_0x16(toml, &ctx, &out->man_ace_v1_5->info_0x16, verbose); + if (ret < 0) + return err_key_parse("partition_info", NULL); + + ret = parse_adsp_file_ext_v2_5(toml, &ctx, &out->man_ace_v1_5->adsp_file_ext, verbose); + if (ret < 0) + return err_key_parse("adsp_file", NULL); + + ret = parse_fw_desc(toml, &ctx, &out->man_ace_v1_5->desc, verbose); + if (ret < 0) + return err_key_parse("fw_desc", NULL); + + ret = parse_module(toml, &ctx, out, verbose); + if (ret < 0) + return err_key_parse("module", NULL); + + /* check everything parsed */ + ret = assert_everything_parsed(toml, &ctx); + if (ret < 0) + return ret; + + return 0; +} + +struct config_parser { + int major; + int minor; + int (*parse)(const toml_table_t *toml, struct image *image); +}; + +static const struct config_parser *find_config_parser(int64_t version[2]) +{ + /* list of supported configuration version with handler to parser */ + static const struct config_parser parsers[] = { + {1, 0, parse_adsp_config_v1_0}, + {1, 5, parse_adsp_config_v1_5}, + {1, 8, parse_adsp_config_v1_8}, + {2, 5, parse_adsp_config_v2_5}, + {3, 0, parse_adsp_config_ace_v1_5}, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(parsers); ++i) { + if (parsers[i].major == version[0] && + parsers[i].minor == version[1]) { + return &parsers[i]; + } + } + return NULL; +} + +static int adsp_parse_config_fd(FILE *fd, struct image *image) +{ + const struct config_parser *parser; + int64_t manifest_version[2]; + toml_table_t *toml; + char errbuf[256]; + int ret; + + /* whole toml file is parsed to global toml table at once */ + toml = toml_parse_file(fd, errbuf, ARRAY_SIZE(errbuf)); + if (!toml) + return log_err(-EINVAL, "error: toml file parsing, %s\n", errbuf); + + /* manifest version is in toml root */ + ret = parse_version(toml, manifest_version); + if (ret < 0) + goto error; + + /* find parser compatible with manifest version */ + parser = find_config_parser(manifest_version); + if (!parser) { + ret = log_err(-EINVAL, "error: Unsupported config version %d.%d\n", + manifest_version[0], manifest_version[1]); + goto error; + } + + /* run dedicated toml configuration parser */ + ret = parser->parse(toml, image); +error: + toml_free(toml); + return ret; +} + +/* public function, fully handle parsing process */ +int adsp_parse_config(const char *file, struct image *image) +{ + FILE *fd; + int ret; + + fd = fopen(file, "r"); + if (!fd) + return file_error("unable to open file for reading", file); + + ret = adsp_parse_config_fd(fd, image); + fclose(fd); + return ret; +} + +/* free given pointer and internally allocated memory */ +void adsp_free(struct adsp *adsp) +{ + if (!adsp) + return; + + if (adsp->man_v1_5) + free(adsp->man_v1_5); + + if (adsp->man_v1_5_sue) + free(adsp->man_v1_5_sue); + + if (adsp->man_v1_8) + free(adsp->man_v1_8); + + if (adsp->man_v2_5) + free(adsp->man_v2_5); + + if (adsp->modules) + free(adsp->modules); + + if (adsp->name) + free((char *)adsp->name); + + free(adsp); +} diff --git a/tools/rimage/src/cse.c b/tools/rimage/src/cse.c new file mode 100644 index 000000000000..3c5e9c561856 --- /dev/null +++ b/tools/rimage/src/cse.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2017 Intel Corporation. All rights reserved. +// +// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> +// Keyon Jie <yang.jie@linux.intel.com> + +#include <stdio.h> +#include <stdbool.h> +#include <rimage/rimage.h> +#include <rimage/cse.h> +#include <rimage/manifest.h> + +void ri_cse_create(struct image *image) +{ + struct CsePartitionDirHeader *cse_hdr = image->fw_image; + struct sof_man_adsp_meta_file_ext_v1_8 *meta = image->fw_image + + MAN_META_EXT_OFFSET_V1_8; + struct CsePartitionDirEntry *cse_entry = + image->fw_image + sizeof(*cse_hdr); + uint8_t csum = 0, *val = image->fw_image; + int i, size; + + fprintf(stdout, " cse: completing CSE V1.8 manifest\n"); + + cse_entry[2].length = meta->comp_desc[0].limit_offset - + MAN_DESC_OFFSET_V1_8; + + /* calculate checksum using BSD algo */ + size = sizeof(*cse_hdr) + sizeof(*cse_entry) * MAN_CSE_PARTS; + for (i = 0; i < size; i++) { + if (i == 11) + continue; + csum += val[i]; + } + cse_hdr->checksum = 0x100 - csum; +} + +static uint32_t crc32(uint8_t *input, int size, uint32_t poly, uint32_t init, + bool rev_in, bool rev_out, uint32_t xor_out) +{ + uint32_t crc = init; + uint32_t t32; + uint8_t val; + uint8_t t8; + int i; + int j; + + for (i = 0; i < size; i++) { + val = input[i]; + if (rev_in) { + t8 = 0; + for (j = 0; j < 8; j++) { + if (val & (1 << j)) + t8 |= (uint8_t)(1 << (7 - j)); + } + val = t8; + } + crc ^= (uint32_t)(val << 24); + for (j = 0; j < 8; j++) { + if (crc & 0x80000000) + crc = (uint32_t)((crc << 1) ^ poly); + else + crc <<= 1; + } + } + + if (rev_out) { + t32 = 0; + for (i = 0; i < 32; i++) { + if (crc & (1U << i)) + t32 |= (uint32_t)(1 << (31 - i)); + } + crc = t32; + } + + return crc ^ xor_out; +} + +void ri_cse_create_v2_5(struct image *image) +{ + struct CsePartitionDirHeader_v2_5 *cse_hdr = image->fw_image; + struct sof_man_adsp_meta_file_ext_v2_5 *meta = image->fw_image + + MAN_META_EXT_OFFSET_V2_5; + struct CsePartitionDirEntry *cse_entry = + image->fw_image + sizeof(*cse_hdr); + uint8_t *val = image->fw_image; + int size; + + fprintf(stdout, " cse: completing CSE V2.5 manifest\n"); + + cse_entry[2].length = meta->comp_desc[0].limit_offset - + MAN_DESC_OFFSET_V1_8; + + /* + * calculate checksum using crc-32/iso-hdlc + * + * polynomial: 0x04c11db7 + * initial value: 0xffffffff + * reverse input: true + * reverse output: true + * xor output: 0xffffffff + */ + size = (sizeof(*cse_hdr) + (sizeof(*cse_entry) * MAN_CSE_PARTS)); + cse_hdr->checksum = crc32(val, size, 0x04c11db7, 0xffffffff, true, true, 0xffffffff); + + fprintf(stdout, " cse: cse checksum %x\n", cse_hdr->checksum); +} + +void ri_cse_create_ace_v1_5(struct image *image) +{ + struct CsePartitionDirHeader_v2_5 *cse_hdr = image->fw_image; + struct sof_man_adsp_meta_file_ext_v2_5 *meta = image->fw_image + + MAN_META_EXT_OFFSET_ACE_V1_5; + struct CsePartitionDirEntry *cse_entry = + image->fw_image + sizeof(*cse_hdr); + uint8_t *val = image->fw_image; + int size; + + fprintf(stdout, " cse: completing CSE V2.5 manifest\n"); + + cse_entry[2].length = meta->comp_desc[0].limit_offset - + MAN_DESC_OFFSET_V1_8; + + /* + * calculate checksum using crc-32/iso-hdlc + * + * polynomial: 0x04c11db7 + * initial value: 0xffffffff + * reverse input: true + * reverse output: true + * xor output: 0xffffffff + */ + size = (sizeof(*cse_hdr) + (sizeof(*cse_entry) * MAN_CSE_PARTS)); + cse_hdr->checksum = crc32(val, size, 0x04c11db7, 0xffffffff, true, true, 0xffffffff); + + fprintf(stdout, " cse: cse checksum %x\n", cse_hdr->checksum); +} diff --git a/tools/rimage/src/css.c b/tools/rimage/src/css.c new file mode 100644 index 000000000000..a69d5c80f76b --- /dev/null +++ b/tools/rimage/src/css.c @@ -0,0 +1,185 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2017 Intel Corporation. All rights reserved. +// +// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> +// Keyon Jie <yang.jie@linux.intel.com> + +#include <stdio.h> +#include <errno.h> +#include <time.h> +#include <sys/time.h> +#include <rimage/rimage.h> +#include <rimage/css.h> +#include <rimage/manifest.h> + +void ri_css_v2_5_hdr_create(struct image *image) +{ + struct css_header_v2_5 *css = image->fw_image + MAN_CSS_HDR_OFFSET_2_5; + struct tm *date; + struct timeval tv; + time_t seconds; + int val; + + fprintf(stdout, " cse: %s completing CSS manifest\n", __func__); + + /* get local time and date */ + gettimeofday(&tv, NULL); + seconds = tv.tv_sec; + date = localtime(&seconds); + + if (!date) { + fprintf(stderr, "error: cant get localtime %d\n", -errno); + return; + } + + date->tm_year += 1900; + fprintf(stdout, " css: set build date to %d:%2.2d:%2.2d\n", + date->tm_year, date->tm_mon, date->tm_mday); + + /* year yYyy */ + val = date->tm_year / 1000; + css->date |= val << 28; + date->tm_year -= val * 1000; + /* year yyYy */ + val = date->tm_year / 100; + css->date |= val << 24; + date->tm_year -= val * 100; + /* year yyyY */ + val = date->tm_year / 10; + css->date |= val << 20; + date->tm_year -= val * 10; + /* year Yyyy */ + val = date->tm_year; + css->date |= val << 16; + + /* month Mm - for some reason month starts at 0 */ + val = ++date->tm_mon / 10; + css->date |= val << 12; + date->tm_mon -= (val * 10); + /* month mM */ + val = date->tm_mon; + css->date |= val << 8; + + /* Day Dd */ + val = date->tm_mday / 10; + css->date |= val << 4; + date->tm_mday -= (val * 10); + /* Day dD */ + val = date->tm_mday; + css->date |= val << 0; +} + +void ri_css_v1_8_hdr_create(struct image *image) +{ + struct css_header_v1_8 *css = image->fw_image + MAN_CSS_HDR_OFFSET; + struct tm *date; + struct timeval tv; + time_t seconds; + int val; + + fprintf(stdout, " cse: %s completing CSS manifest\n", __func__); + + /* get local time and date */ + gettimeofday(&tv, NULL); + seconds = tv.tv_sec; + date = localtime(&seconds); + + if (!date) { + fprintf(stderr, "error: cant get localtime %d\n", -errno); + return; + } + + date->tm_year += 1900; + fprintf(stdout, " css: set build date to %d:%2.2d:%2.2d\n", + date->tm_year, date->tm_mon, date->tm_mday); + + /* year yYyy */ + val = date->tm_year / 1000; + css->date |= val << 28; + date->tm_year -= val * 1000; + /* year yyYy */ + val = date->tm_year / 100; + css->date |= val << 24; + date->tm_year -= val * 100; + /* year yyyY */ + val = date->tm_year / 10; + css->date |= val << 20; + date->tm_year -= val * 10; + /* year Yyyy */ + val = date->tm_year; + css->date |= val << 16; + + /* month Mm - for some reason month starts at 0 */ + val = ++date->tm_mon / 10; + css->date |= val << 12; + date->tm_mon -= (val * 10); + /* month mM */ + val = date->tm_mon; + css->date |= val << 8; + + /* Day Dd */ + val = date->tm_mday / 10; + css->date |= val << 4; + date->tm_mday -= (val * 10); + /* Day dD */ + val = date->tm_mday; + css->date |= val << 0; +} + +void ri_css_v1_5_hdr_create(struct image *image) +{ + struct css_header_v1_5 *css = image->fw_image; + struct tm *date; + struct timeval tv; + time_t seconds; + int val; + + fprintf(stdout, " cse: %s completing CSS manifest\n", __func__); + + /* get local time and date */ + gettimeofday(&tv, NULL); + seconds = tv.tv_sec; + date = localtime(&seconds); + + if (!date) { + fprintf(stderr, "error: cant get localtime %d\n", -errno); + return; + } + + date->tm_year += 1900; + fprintf(stdout, " css: set build date to %d:%2.2d:%2.2d\n", + date->tm_year, date->tm_mon, date->tm_mday); + + /* year yYyy */ + val = date->tm_year / 1000; + css->date |= val << 28; + date->tm_year -= val * 1000; + /* year yyYy */ + val = date->tm_year / 100; + css->date |= val << 24; + date->tm_year -= val * 100; + /* year yyyY */ + val = date->tm_year / 10; + css->date |= val << 20; + date->tm_year -= val * 10; + /* year Yyyy */ + val = date->tm_year; + css->date |= val << 16; + + /* month Mm - for some reason month starts at 0 */ + val = ++date->tm_mon / 10; + css->date |= val << 12; + date->tm_mon -= (val * 10); + /* month mM */ + val = date->tm_mon; + css->date |= val << 8; + + /* Day Dd */ + val = date->tm_mday / 10; + css->date |= val << 4; + date->tm_mday -= (val * 10); + /* Day dD */ + val = date->tm_mday; + css->date |= val << 0; +} diff --git a/tools/rimage/src/elf_file.c b/tools/rimage/src/elf_file.c new file mode 100644 index 000000000000..efb9cc912b4e --- /dev/null +++ b/tools/rimage/src/elf_file.c @@ -0,0 +1,571 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + * Author: Adrian Warecki <adrian.warecki@intel.com> + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include <rimage/elf_file.h> +#include <rimage/file_utils.h> +#include <rimage/misc_utils.h> + + /* Values for e_type. */ +static struct name_val e_type[] = { + NAME_VAL_ENTRY(ET_NONE), /* Unknown type. */ + NAME_VAL_ENTRY(ET_REL), /* Relocatable. */ + NAME_VAL_ENTRY(ET_EXEC), /* Executable. */ + NAME_VAL_ENTRY(ET_DYN), /* Shared object. */ + NAME_VAL_ENTRY(ET_CORE), /* Core file. */ + NAME_VAL_END +}; + +static struct name_val sh_types[] = { + NAME_VAL_ENTRY(SHT_NULL), /* inactive */ + NAME_VAL_ENTRY(SHT_PROGBITS), /* program defined information */ + NAME_VAL_ENTRY(SHT_SYMTAB), /* symbol table section */ + NAME_VAL_ENTRY(SHT_STRTAB), /* string table section */ + NAME_VAL_ENTRY(SHT_RELA), /* relocation section with addends */ + NAME_VAL_ENTRY(SHT_HASH), /* symbol hash table section */ + NAME_VAL_ENTRY(SHT_DYNAMIC), /* dynamic section */ + NAME_VAL_ENTRY(SHT_NOTE), /* note section */ + NAME_VAL_ENTRY(SHT_NOBITS), /* no space section */ + NAME_VAL_ENTRY(SHT_REL), /* relocation section - no addends */ + NAME_VAL_ENTRY(SHT_SHLIB), /* reserved - purpose unknown */ + NAME_VAL_ENTRY(SHT_DYNSYM), /* dynamic symbol table section */ + NAME_VAL_ENTRY(SHT_INIT_ARRAY), /* Initialization function pointers. */ + NAME_VAL_ENTRY(SHT_FINI_ARRAY), /* Termination function pointers. */ + NAME_VAL_ENTRY(SHT_PREINIT_ARRAY), /* Pre-initialization function ptrs. */ + NAME_VAL_ENTRY(SHT_GROUP), /* Section group. */ + NAME_VAL_ENTRY(SHT_SYMTAB_SHNDX), /* Section indexes (see SHN_XINDEX). */ + NAME_VAL_ENTRY(SHT_LOOS), /* First of OS specific semantics */ + NAME_VAL_ENTRY(SHT_HIOS), /* Last of OS specific semantics */ + NAME_VAL_ENTRY(SHT_GNU_VERDEF), + NAME_VAL_ENTRY(SHT_GNU_VERNEED), + NAME_VAL_ENTRY(SHT_GNU_VERSYM), + NAME_VAL_ENTRY(SHT_LOPROC), /* reserved range for processor */ + NAME_VAL_ENTRY(SHT_HIPROC), /* specific section header types */ + NAME_VAL_ENTRY(SHT_LOUSER), /* reserved range for application */ + NAME_VAL_ENTRY(SHT_HIUSER), /* specific indexes */ + NAME_VAL_END +}; + +/* Flags for sh_flags. */ +static struct name_val sh_flags[] = { + NAME_VAL_ENTRY(SHF_WRITE), /* Section contains writable data. */ + NAME_VAL_ENTRY(SHF_ALLOC), /* Section occupies memory. */ + NAME_VAL_ENTRY(SHF_EXECINSTR), /* Section contains instructions. */ + NAME_VAL_ENTRY(SHF_MERGE), /* Section may be merged. */ + NAME_VAL_ENTRY(SHF_STRINGS), /* Section contains strings. */ + NAME_VAL_ENTRY(SHF_INFO_LINK), /* sh_info holds section index. */ + NAME_VAL_ENTRY(SHF_LINK_ORDER), /* Special ordering requirements. */ + NAME_VAL_ENTRY(SHF_OS_NONCONFORMING), /* OS-specific processing required. */ + NAME_VAL_ENTRY(SHF_GROUP), /* Member of section group. */ + NAME_VAL_ENTRY(SHF_TLS), /* Section contains TLS data. */ + NAME_VAL_END +}; + +/* Values for p_type. */ +static struct name_val p_type[] = { + NAME_VAL_ENTRY(PT_NULL), /* Unused entry. */ + NAME_VAL_ENTRY(PT_LOAD), /* Loadable segment. */ + NAME_VAL_ENTRY(PT_DYNAMIC), /* Dynamic linking information segment. */ + NAME_VAL_ENTRY(PT_INTERP), /* Pathname of interpreter. */ + NAME_VAL_ENTRY(PT_NOTE), /* Auxiliary information. */ + NAME_VAL_ENTRY(PT_SHLIB), /* Reserved (not used). */ + NAME_VAL_ENTRY(PT_PHDR), /* Location of program header itself. */ + NAME_VAL_ENTRY(PT_TLS), /* Thread local storage segment */ + NAME_VAL_END +}; + +/* Values for p_flags. */ +static struct name_val p_flags[] = { + NAME_VAL_ENTRY(PF_X), /* Executable. */ + NAME_VAL_ENTRY(PF_W), /* Writable. */ + NAME_VAL_ENTRY(PF_R), /* Readable. */ + NAME_VAL_END +}; + +/** + * Print elf related error message + * + * @param elf elf file structure + * @param msg error message + * @param error error code to return + * @return error code + */ +static int elf_error(const struct elf_file *elf, const char *msg, int error) +{ + fprintf(stderr, "Error: %s: %s\n", elf->filename, msg); + return -error; +} + +/** + * Read elf header + * + * @param elf elf file structure + * @return error code, 0 when success + */ +static int elf_header_read(struct elf_file *elf) +{ + size_t count; + + /* read in elf header */ + count = fread(&elf->header, sizeof(elf->header), 1, elf->file); + if (count != 1) { + if (count < 0) + return file_error("failed to read elf header", elf->filename); + else + return elf_error(elf, "Corrupted file.", ENODATA); + } + + if (strncmp((char *)elf->header.ident, "\177ELF\001\001", 5)) + return elf_error(elf, "Not a 32 bits ELF-LE file", EILSEQ); + + if (elf->header.version != EV_CURRENT) + return elf_error(elf, "Unsupported file version.", EINVAL); + + if (elf->header.ehsize < sizeof(Elf32_Ehdr)) + return elf_error(elf, "Invalid file header size.", EINVAL); + + if (elf->header.phoff >= elf->file_size) + return elf_error(elf, "Invalid program header file offset.", EINVAL); + + if (elf->header.phentsize < sizeof(Elf32_Phdr)) + return elf_error(elf, "Invalid program header size.", EINVAL); + + if (elf->header.phoff + elf->header.phnum * sizeof(Elf32_Phdr) > elf->file_size) + return elf_error(elf, "Invalid number of program header entries.", EINVAL); + + if (elf->header.shoff >= elf->file_size) + return elf_error(elf, "Invalid section header file offset.", EINVAL); + + if (elf->header.shentsize < sizeof(Elf32_Shdr)) + return elf_error(elf, "Invalid section header size.", EINVAL); + + if (elf->header.shoff + elf->header.shnum * sizeof(Elf32_Shdr) > elf->file_size) + return elf_error(elf, "Invalid number of section header entries.", EINVAL); + + if (elf->header.shstrndx >= elf->header.shnum) + return elf_error(elf, "Invalid section name strings section index.", EINVAL); + + return 0; +} + +void elf_header_print(const struct elf_file *elf) +{ + fprintf(stdout, "\tfile type\t 0x%8.8x ", elf->header.type); + print_enum(elf->header.type, e_type); + fprintf(stdout, "\tarchitecture\t 0x%8.8x\n", elf->header.machine); + fprintf(stdout, "\tformat version\t 0x%8.8x\n", elf->header.version); + fprintf(stdout, "\tarch flags\t 0x%8.8x\n", elf->header.flags); + fprintf(stdout, "\theader size\t 0x%8.8x\n", elf->header.ehsize); + fprintf(stdout, "\tentry point\t 0x%8.8x\n", elf->header.entry); + fprintf(stdout, "\tprogram offset\t 0x%8.8x\n", elf->header.phoff); + fprintf(stdout, "\tsection offset\t 0x%8.8x\n", elf->header.shoff); + fprintf(stdout, "\tprogram size\t 0x%8.8x\n", elf->header.phentsize); + fprintf(stdout, "\tprogram count\t 0x%8.8x\n", elf->header.phnum); + fprintf(stdout, "\tsection size\t 0x%8.8x\n", elf->header.shentsize); + fprintf(stdout, "\tsection count\t 0x%8.8x\n", elf->header.shnum); + fprintf(stdout, "\tstring index\t 0x%8.8x\n\n", elf->header.shstrndx); +} + +/** + * Read sections headers from elf file + * + * @param elf elf file structure + * @return error code, 0 when success + */ +static int elf_section_headers_read(struct elf_file *elf) +{ + int i, ret; + size_t offset, count; + + elf->sections = calloc(elf->header.shnum, sizeof(struct elf_section_header)); + if (!elf->sections) + return elf_error(elf, "Cannot allocate section array.", ENOMEM); + + /* In case of error, sections memory are released in elf_open function. */ + + offset = elf->header.shoff; + for (i = 0; i < elf->header.shnum; i++, offset += elf->header.shentsize) { + ret = fseek(elf->file, offset, SEEK_SET); + if (ret) + return file_error("unable to seek to section header", elf->filename); + + count = fread(&elf->sections[i].data, sizeof(Elf32_Shdr), 1, elf->file); + if (count != 1) { + if (count < 0) + return file_error("failed to read section header", elf->filename); + else + return elf_error(elf, "Corrupted file.", ENODATA); + } + } + + elf->sections_count = elf->header.shnum; + return 0; +} + +/** + * Update name of a section in the section headers + * + * @param elf elf file structure + * @return error code, 0 when success + */ +static int elf_set_sections_names(struct elf_file *elf, const struct elf_strings *strings) +{ + int ret, i; + + for (i = 0; i < elf->sections_count; i++) { + ret = elf_strings_get(strings, elf->sections[i].data.name, &elf->sections[i].name); + if (ret) + return ret; + } + + return 0; +} + +void elf_print_sections(const struct elf_file *elf) +{ + int i; + + for (i = 0; i < elf->sections_count; i++) { + fprintf(stdout, "Section %d:\n", i); + elf_section_header_print(&elf->sections[i]); + } +} + +/** + * Read program headers from elf file + * + * @param elf elf file structure + * @return error code, 0 when success + */ +static int elf_program_headers_read(struct elf_file *elf) +{ + int i, ret; + size_t offset, count; + + elf->programs = calloc(elf->header.phnum, sizeof(Elf32_Phdr)); + if (!elf->programs) + return elf_error(elf, "Cannot allocate program array.", ENOMEM); + + /* In case of error, programs memory are released in elf_open function. */ + + offset = elf->header.phoff; + for (i = 0; i < elf->header.phnum; i++, offset += elf->header.phentsize) { + ret = fseek(elf->file, offset, SEEK_SET); + if (ret) + return file_error("unable to seek to program header", elf->filename); + + count = fread(&elf->programs[i], sizeof(Elf32_Phdr), 1, elf->file); + if (count != 1) { + if (count < 0) + return file_error("failed to read program header", elf->filename); + else + return elf_error(elf, "Corrupted file.", ENODATA); + } + } + + elf->programs_count = elf->header.phnum; + return 0; +} + +void elf_print_programs(const struct elf_file *elf) +{ + int i; + + for (i = 0; i < elf->programs_count; i++) { + fprintf(stdout, "\nProgram %d:\n", i); + elf_program_header_print(&elf->programs[i]); + } +} + +/** + * Copy elf_header structure. Allocates a new copy of the name string. + * + * @param [in]src Source section header structure + * @param [out]dst Destination section header structure + * @return error code, 0 when success + */ +static int elf_section_header_copy(const struct elf_section_header *src, + struct elf_section_header *dst) +{ + if (src->name) { + dst->name = strdup(src->name); + if (!dst->name) + return -ENOMEM; + } else { + dst->name = NULL; + } + + memcpy(&dst->data, &src->data, sizeof(dst->data)); + return 0; +} + +int elf_section_header_get_by_index(const struct elf_file *elf, int index, + const struct elf_section_header **header) +{ + if (index >= elf->sections_count) + return elf_error(elf, "Invalid section index.", EINVAL); + + *header = &elf->sections[index]; + + return 0; +} + +int elf_section_header_get_by_name(const struct elf_file *elf, const char* name, + const struct elf_section_header **header) +{ + int i; + + *header = NULL; + + for (i = 0; i < elf->sections_count; i++) + if (strcmp(elf->sections[i].name, name) == 0) { + *header = &elf->sections[i]; + return 0; + } + + return -ENOENT; +} + +void elf_section_header_print(const struct elf_section_header *header) +{ + fprintf(stdout, "\tname\t\t0x%8.8x\n", header->data.name); + fprintf(stdout, "\tname\t\t%s\n", header->name); + fprintf(stdout, "\ttype\t\t0x%8.8x ", header->data.type); + print_enum(header->data.type, sh_types); + fprintf(stdout, "\tflags\t\t0x%8.8x ", header->data.flags); + print_flags(header->data.flags, sh_flags); + fprintf(stdout, "\taddr\t\t0x%8.8x\n", header->data.vaddr); + fprintf(stdout, "\toffset\t\t0x%8.8x\n", header->data.off); + fprintf(stdout, "\tsize\t\t0x%8.8x\n", header->data.size); + fprintf(stdout, "\tlink\t\t0x%8.8x\n", header->data.link); + fprintf(stdout, "\tinfo\t\t0x%8.8x\n", header->data.info); + fprintf(stdout, "\taddralign\t0x%8.8x\n", header->data.addralign); + fprintf(stdout, "\tentsize\t\t0x%8.8x\n\n", header->data.entsize); +} + +/** + * Release section header structure + * + * @param sec_hdr Section header structure + */ +static void elf_section_header_free(struct elf_section_header *sec_hdr) +{ + free(sec_hdr->name); + sec_hdr->name = NULL; +} + + +int elf_open(struct elf_file *elf, const char *filename) +{ + struct elf_strings names; + int ret = -ENOMEM; + + memset(elf, 0, sizeof(*elf)); + elf->filename = strdup(filename); + if (!elf->filename) { + ret = -ENOMEM; + goto err; + } + + elf->file = fopen(filename, "rb"); + if (!elf->file) { + ret = file_error("Unable to open elf file", elf->filename); + goto err; + } + + ret = get_file_size(elf->file, elf->filename, &elf->file_size); + if (ret) + goto err; + + ret = elf_header_read(elf); + if (ret) + goto err; + + ret = elf_program_headers_read(elf); + if (ret) + goto err; + + ret = elf_section_headers_read(elf); + if (ret) + goto err; + + ret = elf_strings_read_by_index(elf, elf->header.shstrndx, &names); + if (ret) + goto err; + + ret = elf_set_sections_names(elf, &names); + if (ret) { + elf_strings_free(&names); + goto err; + } + elf_strings_free(&names); + + return 0; + +err: + free(elf->filename); + free(elf->programs); + + if (elf->file) + fclose(elf->file); + + if (elf->sections) { + for (int i = 0; i < elf->sections_count; i++) + elf_section_header_free(&elf->sections[i]); + + free(elf->sections); + } + + return ret; +} + +/** +* Close elf file and release resources +* @param elf elf file structure +*/ +void elf_free(struct elf_file *elf) +{ + int i; + + free(elf->filename); + fclose(elf->file); + + for (i = 0; i < elf->sections_count; i++) + elf_section_header_free(&elf->sections[i]); + + free(elf->sections); + free(elf->programs); +} + +int elf_section_read_content(const struct elf_file *elf, const struct elf_section_header *header, + void *buffer, const size_t size) +{ + int ret; + size_t count; + + if ((header->data.type == SHT_NOBITS) || (header->data.type == SHT_NULL) || + !header->data.size) + return elf_error(elf, "Can't read section without data.", ENODATA); + + if (!header->data.off || (header->data.off + header->data.size) > elf->file_size) + return elf_error(elf, "Invalid section position in file.", ENFILE); + + if (header->data.size > size) + return elf_error(elf, "Output buffer too small.", ENOSPC); + + ret = fseek(elf->file, header->data.off, SEEK_SET); + if (ret) + return file_error("unable to seek to section data", elf->filename); + + count = fread(buffer, header->data.size, 1, elf->file); + if (count != 1) { + if (count < 0) + return file_error("failed to read section data", elf->filename); + else + return elf_error(elf, "Corrupted file.", ENODATA); + } + + return 0; +} + +int elf_section_read(const struct elf_file *elf, const struct elf_section_header *header, + struct elf_section *section) +{ + int ret; + + section->data = malloc(header->data.size); + if (!section->data) + return elf_error(elf, "No memory for section buffer.", ENOMEM); + + ret = elf_section_header_copy(header, §ion->header); + if (ret) + goto err; + + ret = elf_section_read_content(elf, header, section->data, header->data.size); + if (ret) + goto err; + + return 0; + +err: + elf_section_header_free(§ion->header); + free(section->data); + return ret; +} + +int elf_section_read_by_name(const struct elf_file *elf, const char *name, + struct elf_section *section) +{ + const struct elf_section_header *header; + int ret; + + ret = elf_section_header_get_by_name(elf, name, &header); + + if (ret) + return ret; + + return elf_section_read(elf, header, section); +} + +void elf_section_free(struct elf_section *section) +{ + free(section->data); +} + +int elf_strings_read_by_index(const struct elf_file *elf, int index, struct elf_strings *strings) +{ + const struct elf_section_header *header; + int ret; + + ret = elf_section_header_get_by_index(elf, index, &header); + if (ret) + return ret; + + if (header->data.type != SHT_STRTAB) + return elf_error(elf, "Invalid section type.", EINVAL); + + ret = elf_section_read(elf, header, &strings->section); + if (ret) + return elf_error(elf, "Unable to read section names section.", ret); + + return 0; +} + +int elf_strings_get(const struct elf_strings *strings, int index, char **str) +{ + if (index >= strings->section.header.data.size) + return -EINVAL; + + *str = strdup((const char *)strings->section.data + index); + if (!*str) + return -ENOMEM; + + return 0; +} + +void elf_strings_free(struct elf_strings *strings) +{ + elf_section_free(&strings->section); +} + +void elf_program_header_print(const Elf32_Phdr *header) +{ + fprintf(stdout, "\ttype\t 0x%8.8x ", header->type); + print_enum(header->type, p_type); + fprintf(stdout, "\tflags\t 0x%8.8x ", header->flags); + print_flags(header->flags, p_flags); + fprintf(stdout, "\toffset\t 0x%8.8x\n", header->off); + fprintf(stdout, "\tvaddr\t 0x%8.8x\n", header->vaddr); + fprintf(stdout, "\tpaddr\t 0x%8.8x\n", header->paddr); + fprintf(stdout, "\tfilesz\t 0x%8.8x\n", header->filesz); + fprintf(stdout, "\tmemsz\t 0x%8.8x\n", header->memsz); + fprintf(stdout, "\talign\t 0x%8.8x\n\n", header->align); +} diff --git a/tools/rimage/src/ext_manifest.c b/tools/rimage/src/ext_manifest.c new file mode 100644 index 000000000000..c6d3c02e887e --- /dev/null +++ b/tools/rimage/src/ext_manifest.c @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2020 Intel Corporation. All rights reserved. +// +// Author: Karol Trzcinski <karolx.trzcinski@linux.intel.com> + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> + +#include <rimage/ext_manifest_gen.h> +#include <rimage/sof/kernel/ext_manifest.h> +#include <rimage/rimage.h> +#include <rimage/cavs/cavs_ext_manifest.h> +#include <rimage/manifest.h> +#include <rimage/file_utils.h> + +const struct ext_man_header ext_man_template = { + .magic = EXT_MAN_MAGIC_NUMBER, + .header_version = EXT_MAN_VERSION, + .header_size = sizeof(struct ext_man_header), + .full_size = 0, /* runtime variable */ +}; + +static int ext_man_open_file(struct image *image) +{ + int ret; + + ret = create_file_name(image->out_ext_man_file, sizeof(image->out_ext_man_file), + image->out_file, "xman"); + if (ret) + return ret; + + /* open extended manifest outfile for writing */ + image->out_ext_man_fd = fopen(image->out_ext_man_file, "wb"); + if (!image->out_ext_man_fd) + return file_error("unable to open file for writing", image->out_ext_man_file); + + return 0; +} + +static const struct elf_file *ext_man_find_module(const struct image *image, + const struct elf_section_header **section) +{ + const struct manifest_module *module; + int i; + + for (i = 0; i < image->num_modules; i++) { + module = &image->module[i]; + + if (module->is_bootloader) + continue; + + if (!elf_section_header_get_by_name(&module->file.elf, EXT_MAN_DATA_SECTION, + section)) + return &module->file.elf; + } + + return NULL; +} + +static int ext_man_validate(uint32_t section_size, const void *section_data) +{ + uint8_t *sbuf = (uint8_t *)section_data; + struct ext_man_elem_header head; + uint32_t offset = 0; + + /* copy each head to local struct to omit memory align issues */ + while (offset < section_size) { + memcpy(&head, &sbuf[offset], sizeof(head)); + fprintf(stdout, "Extended manifest found module, type: 0x%04X size: 0x%04X (%4d) offset: 0x%04X\n", + head.type, head.elem_size, head.elem_size, offset); + if (head.elem_size == 0 || head.elem_size % EXT_MAN_ALIGN) { + fprintf(stderr, + "error: invalid extended manifest element size\n"); + return -EINVAL; + } + offset += head.elem_size; + } + + /* sum of packets size != section size */ + if (offset != section_size) { + fprintf(stderr, + "error: fw_metadata section is inconsistent, section size: 0x%04X != 0x%04X sum of packets size\n", + section_size, offset); + return -EINVAL; + } else { + return 0; + } +} + +static int ext_man_build(const struct elf_file *file, const struct elf_section_header *section, + struct ext_man_header **dst_buff) +{ + struct ext_man_header *ext_man; + size_t size; + int ret; + + size = ext_man_template.header_size + section->data.size; + if (size % 4) { + fprintf(stderr, "error: extended manifest size must be aligned to 4\n"); + return -EINVAL; + } + + ext_man = calloc(1, size); + if (!ext_man) + return -ENOMEM; + + /* fill ext_man struct, size aligned to 4 to avoid unaligned accesses */ + memcpy(ext_man, &ext_man_template, ext_man_template.header_size); + ext_man->full_size = size; + + ret = elf_section_read_content(file, section, ext_man + 1, + size - ext_man_template.header_size); + if (ret < 0) { + fprintf(stderr, "error: failed to read %s section content, code %d\n", + EXT_MAN_DATA_SECTION, ret); + free(ext_man); + return ret; + } + + *dst_buff = ext_man; + return 0; +} + +int ext_man_write(struct image *image) +{ + const struct elf_file *file; + struct ext_man_header *ext_man = NULL; + const struct elf_section_header *section; + int count; + int ret; + + ret = ext_man_open_file(image); + if (ret) + goto out; + + file = ext_man_find_module(image, §ion); + if (!file) { + ret = -ECANCELED; + goto out; + } + + ret = ext_man_build(file, section, &ext_man); + if (ret) + goto out; + + /* validate metadata section */ + ret = ext_man_validate(ext_man->full_size - ext_man->header_size, + (char *)ext_man + ext_man->header_size); + if (ret) { + ret = -errno; + goto out; + } + + /* write extended metadata to file */ + count = fwrite(ext_man, 1, ext_man->full_size, image->out_ext_man_fd); + + if (count != ext_man->full_size) { + ret = file_error("can't write extended manifest", image->out_ext_man_file); + goto out; + } + + fprintf(stdout, "Extended manifest saved to file %s size 0x%04X (%d) bytes\n\n", + image->out_ext_man_file, ext_man->full_size, + ext_man->full_size); + +out: + if (ext_man) + free(ext_man); + if (image->out_ext_man_fd) + fclose(image->out_ext_man_fd); + return ret; +} + +int ext_man_write_cavs_25(struct image *image) +{ + struct fw_image_ext_module *mod_ext; + struct fw_ext_man_cavs_header header; + int pin_count; + int count, i; + int ret; + size_t write_ret; + + ret = ext_man_open_file(image); + if (ret) + goto out; + + mod_ext = &image->adsp->modules->mod_ext; + count = mod_ext->mod_conf_count; + header.version_major = EXTENDED_MANIFEST_VERSION_MAJOR; + header.version_minor = EXTENDED_MANIFEST_VERSION_MINOR; + header.num_module_entries = count; + header.id = EXTENDED_MANIFEST_MAGIC_HEADER_ID; + header.len = sizeof(const struct fw_ext_man_cavs_header); + + for (i = 0; i < count; i++) + header.len += mod_ext->ext_mod_config_array[i].header.ext_module_config_length; + fwrite(&header, 1, sizeof(header), image->out_ext_man_fd); + + for (i = 0; i < count; i++) { + write_ret = fwrite(&mod_ext->ext_mod_config_array[i].header, + sizeof(struct fw_ext_mod_config_header), 1, + image->out_ext_man_fd); + if (write_ret != 1) { + ret = file_error("can't write fw_ext_mod_config_header", + image->out_ext_man_file); + goto out; + } + + if (mod_ext->ext_mod_config_array[i].header.num_scheduling_capabilities) { + write_ret = fwrite(&mod_ext->ext_mod_config_array[i].sched_caps, + sizeof(struct mod_scheduling_caps), 1, + image->out_ext_man_fd); + if (write_ret != 1) { + ret = file_error("can't write mod_scheduling_caps", + image->out_ext_man_file); + goto out; + } + } + + pin_count = mod_ext->ext_mod_config_array[i].header.num_pin_entries; + if (pin_count) { + write_ret = fwrite(mod_ext->ext_mod_config_array[i].pin_desc, + sizeof(struct fw_pin_description), pin_count, + image->out_ext_man_fd); + + if (write_ret != pin_count) { + ret = file_error("can't write fw_pin_description", + image->out_ext_man_file); + goto out; + } + } + } + +out: + if (image->out_ext_man_fd) + fclose(image->out_ext_man_fd); + return ret; +} diff --git a/tools/rimage/src/file_simple.c b/tools/rimage/src/file_simple.c new file mode 100644 index 000000000000..e87689f44133 --- /dev/null +++ b/tools/rimage/src/file_simple.c @@ -0,0 +1,298 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2015 Intel Corporation. All rights reserved. + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> + +#include <rimage/rimage.h> +#include <rimage/manifest.h> +#include <rimage/file_utils.h> + +static int get_mem_zone_type(const struct memory_config *memory, + const struct module_section *section) +{ + uint32_t start, end, base, size; + int i; + + start = section->load_address; + end = start + section->size; + + for (i = SOF_FW_BLK_TYPE_START; i < SOF_FW_BLK_TYPE_NUM; i++) { + base = memory->zones[i].base; + size = memory->zones[i].size; + + if (start < base) + continue; + if (start >= base + size) + continue; + if (end > base + size) + continue; + return i; + } + return SOF_FW_BLK_TYPE_INVALID; +} + +static int block_idx; + +static int write_block(struct image *image, struct manifest_module *module, + const struct module_section *section) +{ + const struct adsp *adsp = image->adsp; + struct snd_sof_blk_hdr block; + uint32_t padding = 0; + size_t count; + int ret; + + block.size = section->size; + if (block.size % 4) { + /* make block.size divisible by 4 to avoid unaligned accesses */ + padding = 4 - (block.size % 4); + block.size += padding; + } + + ret = get_mem_zone_type(&adsp->mem, section); + if (ret != SOF_FW_BLK_TYPE_INVALID) { + block.type = ret; + block.offset = section->load_address - adsp->mem.zones[ret].base + + adsp->mem.zones[ret].host_offset; + } else { + fprintf(stderr, "error: invalid block address/size 0x%x/0x%zx\n", + section->load_address, section->size); + return -EINVAL; + } + + /* write header */ + count = fwrite(&block, sizeof(block), 1, image->out_fd); + if (count != 1) + return file_error("Write header failed", image->out_file); + + /* write out section data */ + ret = module_write_section(&module->file, section, padding, image->out_fd, image->out_file); + if (ret) { + fprintf(stderr, "error: cant write section data. foffset %d size 0x%zx mem addr 0x%x\n", + section->header->data.off, section->size, section->load_address); + return ret; + } + + fprintf(stdout, "\t%d\t0x%8.8x\t0x%8.8zx\t0x%8.8lx\t%s\t%s\n", block_idx++, + section->load_address, section->size, ftell(image->out_fd), + block.type == SOF_FW_BLK_TYPE_IRAM ? "TEXT" : "DATA", + section->header->name); + + /* return padding size */ + if (ret >= 0) + return padding; + + return ret; +} + +/** + * Write all linked sections + * + * @param image program global structure + * @param module modules manifest description + * @param section module section descriptor + * @return size of used padding, error code on error + */ +static int write_blocks(struct image *image, struct manifest_module *module, + const struct module_section *section) +{ + int ret, padding = 0; + + while (section) { + ret = write_block(image, module, section); + if (ret < 0) { + fprintf(stderr, "error: failed to write section %s\n", + section->header->name); + return ret; + } + + padding += ret; + section = section->next_section; + } + + return padding; +} + +static int simple_write_module(struct image *image, struct manifest_module *module) +{ + struct snd_sof_mod_hdr hdr; + size_t count; + int err; + int ptr_hdr, ptr_cur; + uint32_t padding; + + hdr.num_blocks = module->file.text.count + module->file.data.count; + hdr.size = module->file.text.size + module->file.data.size + + sizeof(struct snd_sof_blk_hdr) * hdr.num_blocks; + hdr.type = SOF_FW_BASE; + + /* Get the pointer of writing hdr */ + ptr_hdr = ftell(image->out_fd); + if (ptr_hdr < 0) + return file_error("cant get file position", image->out_file); + + count = fwrite(&hdr, sizeof(hdr), 1, image->out_fd); + if (count != 1) + return file_error("failed to write section header", image->out_file); + + module_print_zones(&module->file); + + fprintf(stdout, "\tNo\tAddress\t\tSize\t\tFile\t\tType\tName\n"); + + /* Write text sections */ + err = write_blocks(image, module, module->file.text.first_section); + if (err < 0) + return err; + padding = err; + + /* Write data sections */ + err = write_blocks(image, module, module->file.data.first_section); + if (err < 0) + return err; + padding += err; + + hdr.size += padding; + /* Record current pointer, will set it back after overwriting hdr */ + ptr_cur = ftell(image->out_fd); + if (ptr_cur < 0) + return file_error("cant get file position", image->out_file); + + /* overwrite hdr */ + err = fseek(image->out_fd, ptr_hdr, SEEK_SET); + if (err) + return file_error("cant seek to header", image->out_file); + + count = fwrite(&hdr, sizeof(hdr), 1, image->out_fd); + if (count != 1) + return file_error("failed to write section header", image->out_file); + + err = fseek(image->out_fd, ptr_cur, SEEK_SET); + if (err) + return file_error("cant seek", image->out_file); + + fprintf(stdout, "\n"); + /* return padding size */ + return padding; +} + +static int write_block_reloc(struct image *image, struct manifest_module *module) +{ + struct snd_sof_blk_hdr block; + size_t count; + int ret; + + block.size = module->file.elf.file_size; + block.type = SOF_FW_BLK_TYPE_DRAM; + block.offset = 0; + + /* write header */ + count = fwrite(&block, sizeof(block), 1, image->out_fd); + if (count != 1) + return file_error("cant write header", image->out_file); + + ret = module_write_whole_elf(&module->file, image->out_fd, image->out_file); + if (ret) + return ret; + + fprintf(stdout, "\t%d\t0x%8.8x\t0x%8.8zx\t0x%8.8lx\t%s\n", block_idx++, + 0, module->file.elf.file_size, ftell(image->out_fd), + block.type == SOF_FW_BLK_TYPE_IRAM ? "TEXT" : "DATA"); + + return ret; +} + +static int simple_write_module_reloc(struct image *image, struct manifest_module *module) +{ + struct snd_sof_mod_hdr hdr; + size_t count; + int err; + + hdr.num_blocks = 1; + hdr.size = module->file.text.size + module->file.data.size; + hdr.type = SOF_FW_BASE; // module + + count = fwrite(&hdr, sizeof(hdr), 1, image->out_fd); + if (count != 1) + return file_error("failed to write section header", image->out_file); + + module_print_zones(&module->file); + + fprintf(stdout, "\tNo\tAddress\t\tSize\t\tFile\t\tType\n"); + + err = write_block_reloc(image, module); + if (err < 0) { + fprintf(stderr, "error: failed to write section #%d\n", err); + return err; + } + + fprintf(stdout, "\n"); + return 0; +} + +/* used by others */ +int simple_write_firmware(struct image *image) +{ + struct snd_sof_fw_header hdr; + struct manifest_module *module; + size_t count; + int i, ret; + + memcpy(hdr.sig, SND_SOF_FW_SIG, SND_SOF_FW_SIG_SIZE); + + hdr.num_modules = image->num_modules; + hdr.abi = SND_SOF_FW_ABI; + hdr.file_size = 0; + + for (i = 0; i < image->num_modules; i++) { + module = &image->module[i]; + module->output_size = module->file.data.size + module->file.text.size; + module->output_size += sizeof(struct snd_sof_blk_hdr) * + (module->file.data.count + module->file.text.count); + module->output_size += sizeof(struct snd_sof_mod_hdr) * + hdr.num_modules; + hdr.file_size += module->output_size; + } + + count = fwrite(&hdr, sizeof(hdr), 1, image->out_fd); + if (count != 1) + return file_error("failed to write header", image->out_file); + + for (i = 0; i < image->num_modules; i++) { + module = &image->module[i]; + + fprintf(stdout, "writing module %d %s\n", i, module->file.elf.filename); + + if (image->reloc) + ret = simple_write_module_reloc(image, module); + else + ret = simple_write_module(image, module); + if (ret < 0) { + fprintf(stderr, "error: failed to write module %d\n", + i); + return ret; + } + /* add padding size */ + hdr.file_size += ret; + } + /* overwrite hdr */ + ret = fseek(image->out_fd, 0, SEEK_SET); + if (ret) + return file_error("can't seek set", image->out_file); + + + count = fwrite(&hdr, sizeof(hdr), 1, image->out_fd); + if (count != 1) + return file_error("failed to write header", image->out_file); + + fprintf(stdout, "firmware: image size %ld (0x%lx) bytes %d modules\n\n", + (long)(hdr.file_size + sizeof(hdr)), + (long)(hdr.file_size + sizeof(hdr)), + hdr.num_modules); + + return 0; +} diff --git a/tools/rimage/src/file_utils.c b/tools/rimage/src/file_utils.c new file mode 100644 index 000000000000..89a89ae40954 --- /dev/null +++ b/tools/rimage/src/file_utils.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2018-2023 Intel Corporation. All rights reserved. +// +// Author: Adrian Warecki <adrian.warecki@intel.com> + +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <assert.h> +#include <string.h> + +#include <rimage/file_utils.h> + +int file_error(const char *msg, const char *filename) +{ + int code = errno; + char sys_msg[256]; + + strerror_r(code, sys_msg, sizeof(sys_msg)); + + fprintf(stderr, "%s:\terror: %s. %s (errno = %d)\n", filename, msg, sys_msg, code); + return -code; +} + +int create_file_name(char *new_name, const size_t name_size, const char *template_name, + const char *new_ext) +{ + int len; + + assert(new_name); + + len = snprintf(new_name, name_size, "%s.%s", template_name, new_ext); + if (len >= name_size) { + fprintf(stderr, "error: output file name too long\n"); + return -ENAMETOOLONG; + } + + unlink(new_name); + + return 0; +} + +int get_file_size(FILE *f, const char* filename, size_t *size) +{ + int ret; + long pos; + assert(size); + + /* get file size */ + ret = fseek(f, 0, SEEK_END); + if (ret) + return file_error("unable to seek eof", filename); + + pos = ftell(f); + if (pos < 0) + return file_error("unable to get file size", filename); + + ret = fseek(f, 0, SEEK_SET); + if (ret) + return file_error("unable to seek set", filename); + + *size = pos; + return 0; +} diff --git a/tools/rimage/src/hash.c b/tools/rimage/src/hash.c new file mode 100644 index 000000000000..0604670e9c6e --- /dev/null +++ b/tools/rimage/src/hash.c @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright(c) 2017 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> + * Keyon Jie <yang.jie@linux.intel.com> + * Adrian Warecki <adrian.warecki@intel.com> + */ + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> + +#include <openssl/conf.h> +#include <openssl/evp.h> +#include <openssl/err.h> + +#include <rimage/rimage.h> +#include <rimage/manifest.h> +#include <rimage/hash.h> + +#define DEBUG_HASH 0 + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +void EVP_MD_CTX_free(EVP_MD_CTX *ctx); +EVP_MD_CTX *EVP_MD_CTX_new(void); + +static void *OPENSSL_zalloc(size_t num) +{ + void *ret = OPENSSL_malloc(num); + + if (ret) + memset(ret, 0, num); + return ret; +} + +EVP_MD_CTX *EVP_MD_CTX_new(void) +{ + return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); +} + +void EVP_MD_CTX_free(EVP_MD_CTX *ctx) +{ + EVP_MD_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} +#endif + +static int hash_error(struct hash_context *context, int errcode, const char *msg) +{ + EVP_MD_CTX_free(context->context); + context->context = NULL; + context->state = HS_ERROR; + context->error = -errcode; + fprintf(stderr, "hash: %s\n", msg); + return context->error; +} + +int hash_init(struct hash_context *context, const EVP_MD *algo) +{ + assert(context); + assert(algo); + + context->error = 0; + context->digest_length = 0; + context->algo = algo; + + context->context = EVP_MD_CTX_new(); + if (!context->context) + return hash_error(context, ENOMEM, "Unable to allocate hash context."); + + if (!EVP_DigestInit_ex(context->context, context->algo, NULL)) { + EVP_MD_CTX_free(context->context); + return hash_error(context, ENOTRECOVERABLE, "Unable to initialize hash context."); + } + + context->state = HS_UPDATE; + return 0; +} + +int hash_sha256_init(struct hash_context *context) +{ + return hash_init(context, EVP_sha256()); +} + +int hash_sha384_init(struct hash_context *context) +{ + return hash_init(context, EVP_sha384()); +} + +int hash_update(struct hash_context *context, const void *data, size_t size) +{ + assert(context); + assert(data); + + if (context->error) + return context->error; + + assert(context->state == HS_UPDATE); + + if (!EVP_DigestUpdate(context->context, data, size)) + return hash_error(context, EINVAL, "Unable to update hash context."); + + return 0; +} + +int hash_finalize(struct hash_context *context) +{ + assert(context); + + if (context->error) + return context->error; + + assert(context->state == HS_UPDATE); + + if (!EVP_DigestFinal_ex(context->context, context->digest, &context->digest_length)) + return hash_error(context, EINVAL, "Unable to finalize hash context."); + + context->state = HS_DONE; + +#if DEBUG_HASH + fprintf(stdout, "Hash result is: "); + hash_print(context); +#endif + + EVP_MD_CTX_free(context->context); + context->context = NULL; + return 0; +} + +int hash_get_digest(struct hash_context *context, void *output, size_t output_len) +{ + assert(context); + assert(output); + + if (context->error) + return context->error; + + assert(context->state == HS_DONE); + + if (context->digest_length > output_len) + return -ENOBUFS; + + memcpy(output, context->digest, context->digest_length); + return context->digest_length; +} + +void hash_print(struct hash_context *context) +{ + unsigned int i; + + assert(context); + assert(context->state == HS_DONE); + assert(context->digest_length); + + for (i = 0; i < context->digest_length; i++) + fprintf(stdout, "%02x", context->digest[i]); + fprintf(stdout, "\n"); +} + +int hash_single(const void *data, size_t size, const EVP_MD *algo, void *output, size_t output_len) +{ + int algo_out_size; + + assert(algo); + assert(data); + assert(output); + + //algo_out_size = EVP_MD_get_size(algo); + algo_out_size = EVP_MD_size(algo); + if (algo_out_size <= 0) + return -EINVAL; + + if (output_len > algo_out_size) + return -ENOBUFS; + + if (!EVP_Digest(data, size, output, NULL, algo, NULL)) { + fprintf(stderr, "Unable to compute hash."); + return -ENOTRECOVERABLE; + } + + return 0; +} + +int hash_sha256(const void *data, size_t size, void *output, size_t output_len) +{ + return hash_single(data, size, EVP_sha256(), output, output_len); +} + +int hash_sha384(const void *data, size_t size, void *output, size_t output_len) +{ + return hash_single(data, size, EVP_sha384(), output, output_len); +} diff --git a/tools/rimage/src/include/rimage/adsp_config.h b/tools/rimage/src/include/rimage/adsp_config.h new file mode 100644 index 000000000000..e87c78c65f91 --- /dev/null +++ b/tools/rimage/src/include/rimage/adsp_config.h @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2020 Intel Corporation. All rights reserved. + +#include <rimage/rimage.h> +#include <stdbool.h> + +int adsp_parse_config(const char *file, struct image *image); +void adsp_free(struct adsp *adsp); diff --git a/tools/rimage/src/include/rimage/cavs/cavs_ext_manifest.h b/tools/rimage/src/include/rimage/cavs/cavs_ext_manifest.h new file mode 100644 index 000000000000..4002f37fddb1 --- /dev/null +++ b/tools/rimage/src/include/rimage/cavs/cavs_ext_manifest.h @@ -0,0 +1,251 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2021 Intel Corporation. All rights reserved. + * + * Author: Rander Wang <rander.wang@linux.intel.com> + */ + +#ifndef __RIMAGE_CAVS_EXT_MANIFEST_H__ +#define __RIMAGE_CAVS_EXT_MANIFEST_H__ + +/* Structure of ext manifest : + * ExtendedManifestHeader + * ExtendedModuleConfig[0] + * SchedulingCapability[] + * PinDescr[] + * ExtendedModuleConfig[1] + * SchedulingCapability[] + * PinDescr[] + * ... + * ExtendedModuleConfig[N] + * SchedulingCapability[] + * PinDescr[] + */ + +/* ExtendedManifestHeader id $AE1 */ +#define EXTENDED_MANIFEST_MAGIC_HEADER_ID 0x31454124 +#define EXTENDED_MANIFEST_VERSION_MAJOR 0x0001 +#define EXTENDED_MANIFEST_VERSION_MINOR 0x0000 + +#define FW_MAX_EXT_MODULE_NUM 32 + +struct uuid_t { + uint32_t d0; + uint16_t d1; + uint16_t d2; + uint8_t d3; + uint8_t d4; + uint8_t d5; + uint8_t d6; + uint8_t d7; + uint8_t d8; + uint8_t d9; + uint8_t d10; +} __attribute__((packed)); + +union mod_multiples { + uint16_t ul; + struct { + uint16_t x1 : 1; + uint16_t x2 : 1; + uint16_t x3 : 1; + uint16_t x4 : 1; + uint16_t x5 : 1; + uint16_t x6 : 1; + uint16_t x7 : 1; + uint16_t x8 : 1; + uint16_t x9 : 1; + uint16_t x10 : 1; + uint16_t x11 : 1; + uint16_t x12 : 1; + uint16_t x13 : 1; + uint16_t x14 : 1; + uint16_t x15 : 1; + uint16_t all : 1; + } r; +} __attribute__((packed)); + +struct mod_scheduling_caps { + /* scheduling period in Samples (sample groups) (note: 1 Sample = 1 sample per channel) */ + uint16_t frame_length; + union mod_multiples multiples_supported; +} __attribute__((packed)); + +enum mod_pin_direction { + pin_input = 0, + pin_output = 1 +}; + +union mod_pin_caps { + uint32_t ul; + struct { + uint16_t direction : 1; /* 0 : input; 1: output */ + uint16_t reserved0 : 15; + uint16_t reserved1 : 16; + } r; +} __attribute__((packed)); + +union mod_sample_rates { + uint32_t ul; + struct { + uint32_t freq_8000 : 1; + uint32_t freq_11025 : 1; + uint32_t freq_12000 : 1; + uint32_t freq_16000 : 1; + uint32_t freq_18900 : 1; + uint32_t freq_22050 : 1; + uint32_t freq_24000 : 1; + uint32_t freq_32000 : 1; + uint32_t freq_37800 : 1; + uint32_t freq_44100 : 1; + uint32_t freq_48000 : 1; + uint32_t freq_64000 : 1; + uint32_t freq_88200 : 1; + uint32_t freq_96000 : 1; + uint32_t freq_176400 : 1; + uint32_t freq_192000 : 1; + uint32_t reserved : 16; + } r; +} __attribute__((packed)); + +union mod_sample_sizes { + uint32_t ul; + struct { + uint16_t bits_8 : 1; + uint16_t bits_16 : 1; + uint16_t bits_24 : 1; + uint16_t bits_32 : 1; + uint16_t bits_64 : 1; + uint16_t reserved0 : 11; + uint16_t reserved1 : 16; + } r; +} __attribute__((packed)); + +union mod_sample_containers { + uint32_t ul; + struct { + uint16_t bits_8 : 1; + uint16_t bits_16 : 1; + uint16_t bits_24 : 1; + uint16_t bits_32 : 1; + uint16_t bits_64 : 1; + uint16_t reserved0 : 11; + uint16_t reserved1 : 16; + } r; +} __attribute__((packed)); + +union mod_channel_config { + uint32_t ul; + struct { + /* FRONT_CENTER */ + uint32_t channel_mono : 1; + /* FRONT_LEFT | BACK_LEFT */ + uint32_t channel_dual_mono : 1; + /* FRONT_LEFT | FRONT_RIGHT */ + uint32_t channel_stereo : 1; + /* FRONT_LEFT | FRONT_RIGHT | LOW_FREQUENCY */ + uint32_t channel_2_1 : 1; + /* FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER */ + uint32_t channel_3_0 : 1; + /* FRONT_LEFT | FRONT_RIGHT | BACK_LEFT | BACK_RIGHT */ + uint32_t channel_quad : 1; + /* FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | BACK_CENTER */ + uint32_t channel_surround : 1; + /* FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY */ + uint32_t channel_3_1 : 1; + /* FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | BACK_LEFT | BACK_RIGHT */ + uint32_t channel_5_0 : 1; + /* FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | SIDE_LEFT | SIDE_RIGHT */ + uint32_t channel_5_0_surround : 1; + /* FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | BACK_LEFT | + * BACK_RIGHT + */ + uint32_t channel_5_1 : 1; + /* FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | SIDE_LEFT | + * SIDE_RIGHT + */ + uint32_t channel_5_1_surround : 1; + /* FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | BACK_LEFT | BACK_RIGHT | + * FRONT_LEFT_OF_CENTER | FRONT_RIGHT_OF_CENTER + */ + uint32_t channel_7_0 : 1; + /* FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | BACK_LEFT | BACK_RIGHT | + * SIDE_LEFT | SIDE_RIGHT + */ + uint32_t channel_7_0_surround : 1; + /* FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | BACK_LEFT | + * BACK_RIGHT | FRONT_LEFT_OF_CENTER | FRONT_RIGHT_OF_CENTER + */ + uint32_t channel_7_1 : 1; + /* FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | BACK_LEFT | + * BACK_RIGHT | SIDE_LEFT | SIDE_RIGHT + */ + uint32_t channel_7_1_surround : 1; + uint32_t reserved : 16; + } r; +} __attribute__((packed)); + +enum mod_stream_type { + epcm = 0, /* PCM stream */ + emp3, /* MP3 encoded stream */ + eaac, /* AAC encoded stream */ + emax_stream_type, + estream_type_invalid = 0xFF +}; + +enum mod_type { + ebasefw = 0, + emixin, + emixout, + ecopier, + epeakvol, + eupdwmix, + emux, + esrc, + ewov, + efx, + eaec, + ekpb, + emicselect, + efxf, /*i.e.SmartAmp */ + eaudclass, + efakecopier, + eiodriver, + ewhm, + egdbstub, + esensing, + emax, + einvalid = emax +} ; + +struct fw_pin_description { + union mod_pin_caps caps; + enum mod_stream_type format_type; + union mod_sample_rates sample_rate; + union mod_sample_sizes sample_size; + union mod_sample_containers sample_container; + union mod_channel_config ch_cfg; +} __attribute__((packed)); + +struct fw_ext_man_cavs_header { + uint32_t id; + uint32_t len; /* sizeof(Extend Manifest) in bytes */ + uint16_t version_major; /* Version of Extended Manifest structure */ + uint16_t version_minor; /* Version of Extended Manifest structure */ + uint32_t num_module_entries; +} __attribute__((packed)); + +struct fw_ext_mod_config_header { + uint32_t ext_module_config_length; /* sizeof(fw_ext_mod_config_header) in bytes */ + uint32_t guid[4]; /* Module GUID */ + uint16_t version_major; /* Module version */ + uint16_t version_minor; /* Module version */ + uint16_t version_hotfix; /* Module version */ + uint16_t version_build; /* Module version */ + enum mod_type module_type; + uint32_t init_settings_min_size; /* Minimum size of initialization settings (in bytes) */ + uint16_t num_scheduling_capabilities; /* number scheduling capabilities supported by the module */ + uint16_t num_pin_entries; /* Number of Pin (inputs + ouptuts) */ +} __attribute__((packed)); + +#endif diff --git a/tools/rimage/src/include/rimage/cse.h b/tools/rimage/src/include/rimage/cse.h new file mode 100644 index 000000000000..9a14b93b99f6 --- /dev/null +++ b/tools/rimage/src/include/rimage/cse.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2017 Intel Corporation. All rights reserved. + */ + +#ifndef __CSE_H__ +#define __CSE_H__ + +#include <stdint.h> + +struct image; + +#define CSE_HEADER_MAKER 0x44504324 /* "DPC$" */ + +struct CsePartitionDirHeader { + uint32_t header_marker; + uint32_t nb_entries; + uint8_t header_version; + uint8_t entry_version; + uint8_t header_length; + uint8_t checksum; + uint8_t partition_name[4]; +} __attribute__((packed)); + +struct CsePartitionDirHeader_v2_5 { + uint32_t header_marker; + uint32_t nb_entries; + uint8_t header_version; + uint8_t entry_version; + uint8_t header_length; + uint8_t not_used; /* set to zero - old checksum */ + uint8_t partition_name[4]; + uint32_t checksum; /* crc32 checksum */ +} __attribute__((packed)); + +struct CsePartitionDirEntry { + uint8_t entry_name[12]; + uint32_t offset; + uint32_t length; + uint32_t reserved; +} __attribute__((packed)); + +void ri_cse_create(struct image *image); +void ri_cse_create_v2_5(struct image *image); +void ri_cse_create_ace_v1_5(struct image *image); + +#endif diff --git a/tools/rimage/src/include/rimage/css.h b/tools/rimage/src/include/rimage/css.h new file mode 100644 index 000000000000..6283cdaf9042 --- /dev/null +++ b/tools/rimage/src/include/rimage/css.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2017 Intel Corporation. All rights reserved. + */ + +#ifndef __CSS_H__ +#define __CSS_H__ + +#include <stdint.h> + +struct image; + +#define MAN_CSS_LT_MODULE_TYPE 0x00000006 +#define MAN_CSS_MOD_TYPE 4 +#define MAN_CSS_HDR_SIZE 161 /* in words */ +#define MAN_CSS_HDR_SIZE_2_5 225 /* in words */ +#define MAN_CSS_HDR_VERSION 0x10000 +#define MAN_CSS_HDR_VERSION_2_5 0x21000 +#define MAN_CSS_MOD_VENDOR 0x8086 +#define MAN_CSS_HDR_ID {'$', 'M', 'N', '2'} + +#define MAN_CSS_KEY_SIZE (MAN_RSA_KEY_MODULUS_LEN >> 2) +#define MAN_CSS_MOD_SIZE (MAN_RSA_KEY_MODULUS_LEN >> 2) +#define MAN_CSS_MOD_SIZE_2_5 (MAN_RSA_KEY_MODULUS_LEN_2_5 >> 2) +#define MAN_CSS_EXP_SIZE (MAN_RSA_KEY_EXPONENT_LEN >> 2) +#define MAN_CSS_MAN_SIZE_V1_8 \ + (sizeof(struct fw_image_manifest_v1_8) >> 2) +#define MAN_CSS_MAN_SIZE_V1_5 \ + (sizeof(struct fw_image_manifest_v1_5) >> 2) + +/* + * RSA Key and Crypto + */ +#define MAN_RSA_KEY_MODULUS_LEN 256 +#define MAN_RSA_KEY_MODULUS_LEN_2_5 384 +#define MAN_RSA_KEY_EXPONENT_LEN 4 +#define MAN_RSA_SIGNATURE_LEN 256 +#define MAN_RSA_SIGNATURE_LEN_2_5 384 + +struct fw_version { + uint16_t major_version; + uint16_t minor_version; + uint16_t hotfix_version; + uint16_t build_version; +} __attribute__((packed)); + +struct css_header_v2_5 { + uint32_t header_type; + uint32_t header_len; + uint32_t header_version; + uint32_t reserved0; /* must be 0x1 */ + uint32_t module_vendor; + uint32_t date; + uint32_t size; + uint8_t header_id[4]; + uint32_t padding; /* must be 0x0 */ + struct fw_version version; + uint32_t svn; + uint32_t reserved1[18]; /* must be 0x0 */ + uint32_t modulus_size; + uint32_t exponent_size; + uint8_t modulus[MAN_RSA_KEY_MODULUS_LEN_2_5]; + uint8_t exponent[MAN_RSA_KEY_EXPONENT_LEN]; + uint8_t signature[MAN_RSA_SIGNATURE_LEN_2_5]; +} __attribute__((packed)); + +struct css_header_v1_8 { + uint32_t header_type; + uint32_t header_len; + uint32_t header_version; + uint32_t reserved0; /* must be 0x0 */ + uint32_t module_vendor; + uint32_t date; + uint32_t size; + uint8_t header_id[4]; + uint32_t padding; /* must be 0x0 */ + struct fw_version version; + uint32_t svn; + uint32_t reserved1[18]; /* must be 0x0 */ + uint32_t modulus_size; + uint32_t exponent_size; + uint8_t modulus[MAN_RSA_KEY_MODULUS_LEN]; + uint8_t exponent[MAN_RSA_KEY_EXPONENT_LEN]; + uint8_t signature[MAN_RSA_SIGNATURE_LEN]; +} __attribute__((packed)); + +struct css_header_v1_5 { + uint32_t module_type; + uint32_t header_len; + uint32_t header_version; + uint32_t reserved0; /* must be 0x0 */ + uint32_t module_vendor; + uint32_t date; + uint32_t size; + uint32_t key_size; + uint32_t modulus_size; + uint32_t exponent_size; + uint32_t reserved[22]; + uint8_t modulus[MAN_RSA_KEY_MODULUS_LEN]; + uint8_t exponent[MAN_RSA_KEY_EXPONENT_LEN]; + uint8_t signature[MAN_RSA_SIGNATURE_LEN]; +} __attribute__((packed)); + +void ri_css_v1_8_hdr_create(struct image *image); +void ri_css_v1_5_hdr_create(struct image *image); +void ri_css_v2_5_hdr_create(struct image *image); + +#endif diff --git a/tools/rimage/src/include/rimage/elf.h b/tools/rimage/src/include/rimage/elf.h new file mode 100644 index 000000000000..13a4965e059e --- /dev/null +++ b/tools/rimage/src/include/rimage/elf.h @@ -0,0 +1,936 @@ +/* SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 1996-1998 John D. Polstra. All rights reserved. + * Copyright (c) 2001 David E. O'Brien + * Portions Copyright 2009 The Go Authors. All rights reserved. + */ + +#ifndef __ELF_H__ +#define __ELF_H__ + +/* + * ELF definitions that are independent of architecture or word size. + */ + +/* + * Note header. The ".note" section contains an array of notes. Each + * begins with this header, aligned to a word boundary. Immediately + * following the note header is n_namesz bytes of name, padded to the + * next word boundary. Then comes n_descsz bytes of descriptor, again + * padded to a word boundary. The values of n_namesz and n_descsz do + * not include the padding. + */ + +#include <stdint.h> + +typedef uint64_t uint64; +typedef uint32_t uint32; +typedef uint16_t uint16; +typedef uint8_t uint8; + +typedef int64_t int64; +typedef int32_t int32; +typedef int16_t int16; +typedef int8_t int8; + + +typedef struct { + uint32 n_namesz; /* Length of name. */ + uint32 n_descsz; /* Length of descriptor. */ + uint32 n_type; /* Type of this note. */ +} Elf_Note; + +/* Indexes into the e_ident array. Keep synced with + http://www.sco.com/developer/gabi/ch4.eheader.html */ +#define EI_MAG0 0 /* Magic number, byte 0. */ +#define EI_MAG1 1 /* Magic number, byte 1. */ +#define EI_MAG2 2 /* Magic number, byte 2. */ +#define EI_MAG3 3 /* Magic number, byte 3. */ +#define EI_CLASS 4 /* Class of machine. */ +#define EI_DATA 5 /* Data format. */ +#define EI_VERSION 6 /* ELF format version. */ +#define EI_OSABI 7 /* Operating system / ABI identification */ +#define EI_ABIVERSION 8 /* ABI version */ +#define OLD_EI_BRAND 8 /* Start of architecture identification. */ +#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */ +#define EI_NIDENT 16 /* Size of e_ident array. */ + +/* Values for the magic number bytes. */ +#define ELFMAG0 0x7f +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' +#define ELFMAG "\177ELF" /* magic string */ +#define SELFMAG 4 /* magic string size */ + +/* Values for e_ident[EI_VERSION] and e_version. */ +#define EV_NONE 0 +#define EV_CURRENT 1 + +/* Values for e_ident[EI_CLASS]. */ +#define ELFCLASSNONE 0 /* Unknown class. */ +#define ELFCLASS32 1 /* 32-bit architecture. */ +#define ELFCLASS64 2 /* 64-bit architecture. */ + +/* Values for e_ident[EI_DATA]. */ +#define ELFDATANONE 0 /* Unknown data format. */ +#define ELFDATA2LSB 1 /* 2's complement little-endian. */ +#define ELFDATA2MSB 2 /* 2's complement big-endian. */ + +/* Values for e_ident[EI_OSABI]. */ +#define ELFOSABI_NONE 0 /* UNIX System V ABI */ +#define ELFOSABI_HPUX 1 /* HP-UX operating system */ +#define ELFOSABI_NETBSD 2 /* NetBSD */ +#define ELFOSABI_LINUX 3 /* GNU/Linux */ +#define ELFOSABI_HURD 4 /* GNU/Hurd */ +#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ +#define ELFOSABI_SOLARIS 6 /* Solaris */ +#define ELFOSABI_AIX 7 /* AIX */ +#define ELFOSABI_IRIX 8 /* IRIX */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD */ +#define ELFOSABI_TRU64 10 /* TRU64 UNIX */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD */ +#define ELFOSABI_OPENVMS 13 /* Open VMS */ +#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */ +#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */ + +/* e_ident */ +#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ + (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ + (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ + (ehdr).e_ident[EI_MAG3] == ELFMAG3) + +/* Values for e_type. */ +#define ET_NONE 0 /* Unknown type. */ +#define ET_REL 1 /* Relocatable. */ +#define ET_EXEC 2 /* Executable. */ +#define ET_DYN 3 /* Shared object. */ +#define ET_CORE 4 /* Core file. */ +#define ET_LOOS 0xfe00 /* First operating system specific. */ +#define ET_HIOS 0xfeff /* Last operating system-specific. */ +#define ET_LOPROC 0xff00 /* First processor-specific. */ +#define ET_HIPROC 0xffff /* Last processor-specific. */ + +/* Values for e_machine. */ +#define EM_NONE 0 /* Unknown machine. */ +#define EM_M32 1 /* AT&T WE32100. */ +#define EM_SPARC 2 /* Sun SPARC. */ +#define EM_386 3 /* Intel i386. */ +#define EM_68K 4 /* Motorola 68000. */ +#define EM_88K 5 /* Motorola 88000. */ +#define EM_860 7 /* Intel i860. */ +#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */ +#define EM_S370 9 /* IBM System/370. */ +#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */ +#define EM_PARISC 15 /* HP PA-RISC. */ +#define EM_VPP500 17 /* Fujitsu VPP500. */ +#define EM_SPARC32PLUS 18 /* SPARC v8plus. */ +#define EM_960 19 /* Intel 80960. */ +#define EM_PPC 20 /* PowerPC 32-bit. */ +#define EM_PPC64 21 /* PowerPC 64-bit. */ +#define EM_S390 22 /* IBM System/390. */ +#define EM_V800 36 /* NEC V800. */ +#define EM_FR20 37 /* Fujitsu FR20. */ +#define EM_RH32 38 /* TRW RH-32. */ +#define EM_RCE 39 /* Motorola RCE. */ +#define EM_ARM 40 /* ARM. */ +#define EM_SH 42 /* Hitachi SH. */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit. */ +#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */ +#define EM_ARC 45 /* Argonaut RISC Core. */ +#define EM_H8_300 46 /* Hitachi H8/300. */ +#define EM_H8_300H 47 /* Hitachi H8/300H. */ +#define EM_H8S 48 /* Hitachi H8S. */ +#define EM_H8_500 49 /* Hitachi H8/500. */ +#define EM_IA_64 50 /* Intel IA-64 Processor. */ +#define EM_MIPS_X 51 /* Stanford MIPS-X. */ +#define EM_COLDFIRE 52 /* Motorola ColdFire. */ +#define EM_68HC12 53 /* Motorola M68HC12. */ +#define EM_MMA 54 /* Fujitsu MMA. */ +#define EM_PCP 55 /* Siemens PCP. */ +#define EM_NCPU 56 /* Sony nCPU. */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor. */ +#define EM_STARCORE 58 /* Motorola Star*Core processor. */ +#define EM_ME16 59 /* Toyota ME16 processor. */ +#define EM_ST100 60 /* STMicroelectronics ST100 processor. */ +#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */ +#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */ + +/* Non-standard or deprecated. */ +#define EM_486 6 /* Intel i486. */ +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ +#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */ +#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */ + +/* Special section indexes. */ +#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */ +#define SHN_LORESERVE 0xff00 /* First of reserved range. */ +#define SHN_LOPROC 0xff00 /* First processor-specific. */ +#define SHN_HIPROC 0xff1f /* Last processor-specific. */ +#define SHN_LOOS 0xff20 /* First operating system-specific. */ +#define SHN_HIOS 0xff3f /* Last operating system-specific. */ +#define SHN_ABS 0xfff1 /* Absolute values. */ +#define SHN_COMMON 0xfff2 /* Common data. */ +#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */ +#define SHN_HIRESERVE 0xffff /* Last of reserved range. */ + +/* sh_type */ +#define SHT_NULL 0 /* inactive */ +#define SHT_PROGBITS 1 /* program defined information */ +#define SHT_SYMTAB 2 /* symbol table section */ +#define SHT_STRTAB 3 /* string table section */ +#define SHT_RELA 4 /* relocation section with addends */ +#define SHT_HASH 5 /* symbol hash table section */ +#define SHT_DYNAMIC 6 /* dynamic section */ +#define SHT_NOTE 7 /* note section */ +#define SHT_NOBITS 8 /* no space section */ +#define SHT_REL 9 /* relocation section - no addends */ +#define SHT_SHLIB 10 /* reserved - purpose unknown */ +#define SHT_DYNSYM 11 /* dynamic symbol table section */ +#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */ +#define SHT_FINI_ARRAY 15 /* Termination function pointers. */ +#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */ +#define SHT_GROUP 17 /* Section group. */ +#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */ +#define SHT_LOOS 0x60000000 /* First of OS specific semantics */ +#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ +#define SHT_GNU_VERDEF 0x6ffffffd +#define SHT_GNU_VERNEED 0x6ffffffe +#define SHT_GNU_VERSYM 0x6fffffff +#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +#define SHT_HIPROC 0x7fffffff /* specific section header types */ +#define SHT_LOUSER 0x80000000 /* reserved range for application */ +#define SHT_HIUSER 0xffffffff /* specific indexes */ + +/* Flags for sh_flags. */ +#define SHF_WRITE 0x1 /* Section contains writable data. */ +#define SHF_ALLOC 0x2 /* Section occupies memory. */ +#define SHF_EXECINSTR 0x4 /* Section contains instructions. */ +#define SHF_MERGE 0x10 /* Section may be merged. */ +#define SHF_STRINGS 0x20 /* Section contains strings. */ +#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */ +#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */ +#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */ +#define SHF_GROUP 0x200 /* Member of section group. */ +#define SHF_TLS 0x400 /* Section contains TLS data. */ +#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */ +#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */ + +/* Values for p_type. */ +#define PT_NULL 0 /* Unused entry. */ +#define PT_LOAD 1 /* Loadable segment. */ +#define PT_DYNAMIC 2 /* Dynamic linking information segment. */ +#define PT_INTERP 3 /* Pathname of interpreter. */ +#define PT_NOTE 4 /* Auxiliary information. */ +#define PT_SHLIB 5 /* Reserved (not used). */ +#define PT_PHDR 6 /* Location of program header itself. */ +#define PT_TLS 7 /* Thread local storage segment */ +#define PT_LOOS 0x60000000 /* First OS-specific. */ +#define PT_HIOS 0x6fffffff /* Last OS-specific. */ +#define PT_LOPROC 0x70000000 /* First processor-specific type. */ +#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */ +#define PT_GNU_STACK 0x6474e551 +#define PT_PAX_FLAGS 0x65041580 + +/* Values for p_flags. */ +#define PF_X 0x1 /* Executable. */ +#define PF_W 0x2 /* Writable. */ +#define PF_R 0x4 /* Readable. */ +#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */ +#define PF_MASKPROC 0xf0000000 /* Processor-specific. */ + +/* Values for d_tag. */ +#define DT_NULL 0 /* Terminating entry. */ +/* String table offset of a needed shared library. */ +#define DT_NEEDED 1 +#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ +#define DT_PLTGOT 3 /* Processor-dependent address. */ +#define DT_HASH 4 /* Address of symbol hash table. */ +#define DT_STRTAB 5 /* Address of string table. */ +#define DT_SYMTAB 6 /* Address of symbol table. */ +#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ +#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ +#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ +#define DT_STRSZ 10 /* Size of string table. */ +#define DT_SYMENT 11 /* Size of each symbol table entry. */ +#define DT_INIT 12 /* Address of initialization function. */ +#define DT_FINI 13 /* Address of finalization function. */ +/* String table offset of shared object name. */ +#define DT_SONAME 14 +#define DT_RPATH 15 /* String table offset of library path. [sup] */ +#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */ +#define DT_REL 17 /* Address of ElfNN_Rel relocations. */ +#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ +#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ +#define DT_PLTREL 20 /* Type of relocation used for PLT. */ +#define DT_DEBUG 21 /* Reserved (not used). */ +/* Indicates there may be relocations in non-writable segments. [sup] */ +#define DT_TEXTREL 22 +#define DT_JMPREL 23 /* Address of PLT relocations. */ +#define DT_BIND_NOW 24 /* [sup] */ +/* Address of the array of pointers to initialization functions */ +#define DT_INIT_ARRAY 25 +/* Address of the array of pointers to termination functions */ +#define DT_FINI_ARRAY 26 +/* Size in bytes of the array of initialization functions. */ +#define DT_INIT_ARRAYSZ 27 +/* Size in bytes of the array of terminationfunctions. */ +#define DT_FINI_ARRAYSZ 28 +/* String table offset of a null-terminated library search path string. */ +#define DT_RUNPATH 29 +#define DT_FLAGS 30 /* Object specific flag values. */ +/* Values greater than or equal to DT_ENCODING and less than + DT_LOOS follow the rules for the interpretation of the d_un + union as follows: even == 'd_ptr', even == 'd_val' or none */ +#define DT_ENCODING 32 +/* Address of the array of pointers to pre-initialization functions. */ +#define DT_PREINIT_ARRAY 32 +/* Size in bytes of the array of pre-initialization functions. */ +#define DT_PREINIT_ARRAYSZ 33 +#define DT_LOOS 0x6000000d /* First OS-specific */ +#define DT_HIOS 0x6ffff000 /* Last OS-specific */ +#define DT_LOPROC 0x70000000 /* First processor-specific type. */ +#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */ + +#define DT_VERNEED 0x6ffffffe +#define DT_VERNEEDNUM 0x6fffffff +#define DT_VERSYM 0x6ffffff0 + +/* Values for DT_FLAGS */ +/* Indicates that the object being loaded may make reference to + the $ORIGIN substitution string */ +#define DF_ORIGIN 0x0001 +#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */ +/* Indicates there may be relocations in non-writable segments. */ +#define DF_TEXTREL 0x0004 +/* Indicates that the dynamic linker should process all + relocations for the object containing this entry before + transferring control to the program. */ +#define DF_BIND_NOW 0x0008 +/* Indicates that the shared object or executable contains code + using a static thread-local storage scheme. */ +#define DF_STATIC_TLS 0x0010 + +/* Values for n_type. Used in core files. */ +#define NT_PRSTATUS 1 /* Process status. */ +#define NT_FPREGSET 2 /* Floating point registers. */ +#define NT_PRPSINFO 3 /* Process state info. */ + +/* Symbol Binding - ELFNN_ST_BIND - st_info */ +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* like global - lower precedence */ +#define STB_LOOS 10 /* Reserved range for operating system */ +#define STB_HIOS 12 /* specific semantics. */ +#define STB_LOPROC 13 /* reserved range for processor */ +#define STB_HIPROC 15 /* specific semantics. */ + +/* Symbol type - ELFNN_ST_TYPE - st_info */ +#define STT_NOTYPE 0 /* Unspecified type. */ +#define STT_OBJECT 1 /* Data object. */ +#define STT_FUNC 2 /* Function. */ +#define STT_SECTION 3 /* Section. */ +#define STT_FILE 4 /* Source file. */ +#define STT_COMMON 5 /* Uninitialized common block. */ +#define STT_TLS 6 /* TLS object. */ +#define STT_LOOS 10 /* Reserved range for operating system */ +#define STT_HIOS 12 /* specific semantics. */ +#define STT_LOPROC 13 /* reserved range for processor */ +#define STT_HIPROC 15 /* specific semantics. */ + +/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */ +#define STV_DEFAULT 0x0 /* Default visibility (see binding). */ +#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */ +#define STV_HIDDEN 0x2 /* Not visible. */ +#define STV_PROTECTED 0x3 /* Visible but not preemptible. */ + +/* Special symbol table indexes. */ +#define STN_UNDEF 0 /* Undefined symbol index. */ + +/* + * ELF definitions common to all 32-bit architectures. + */ + +typedef uint32 Elf32_Addr; +typedef uint16 Elf32_Half; +typedef uint32 Elf32_Off; +typedef int32 Elf32_Sword; +typedef uint32 Elf32_Word; + +typedef Elf32_Word Elf32_Hashelt; + +/* Non-standard class-dependent datatype used for abstraction. */ +typedef Elf32_Word Elf32_Size; +typedef Elf32_Sword Elf32_Ssize; + +/* + * ELF header. + */ + +typedef struct { + unsigned char ident[EI_NIDENT]; /* File identification. */ + Elf32_Half type; /* File type. */ + Elf32_Half machine; /* Machine architecture. */ + Elf32_Word version; /* ELF format version. */ + Elf32_Addr entry; /* Entry point. */ + Elf32_Off phoff; /* Program header file offset. */ + Elf32_Off shoff; /* Section header file offset. */ + Elf32_Word flags; /* Architecture-specific flags. */ + Elf32_Half ehsize; /* Size of ELF header in bytes. */ + Elf32_Half phentsize; /* Size of program header entry. */ + Elf32_Half phnum; /* Number of program header entries. */ + Elf32_Half shentsize; /* Size of section header entry. */ + Elf32_Half shnum; /* Number of section header entries. */ + Elf32_Half shstrndx; /* Section name strings section. */ +} Elf32_Ehdr; + +/* + * Section header. + */ + +typedef struct { + Elf32_Word name; /* Section name (index into the + section header string table). */ + Elf32_Word type; /* Section type. */ + Elf32_Word flags; /* Section flags. */ + Elf32_Addr vaddr; /* Address in memory image. */ + Elf32_Off off; /* Offset in file. */ + Elf32_Word size; /* Size in bytes. */ + Elf32_Word link; /* Index of a related section. */ + Elf32_Word info; /* Depends on section type. */ + Elf32_Word addralign; /* Alignment in bytes. */ + Elf32_Word entsize; /* Size of each entry in section. */ +} Elf32_Shdr; + +/* + * Program header. + */ + +typedef struct { + Elf32_Word type; /* Entry type. */ + Elf32_Off off; /* File offset of contents. */ + Elf32_Addr vaddr; /* Virtual address in memory image. */ + Elf32_Addr paddr; /* Physical address (not used). */ + Elf32_Word filesz; /* Size of contents in file. */ + Elf32_Word memsz; /* Size of contents in memory. */ + Elf32_Word flags; /* Access permission flags. */ + Elf32_Word align; /* Alignment in memory and file. */ +} Elf32_Phdr; + +/* + * Dynamic structure. The ".dynamic" section contains an array of them. + */ + +typedef struct { + Elf32_Sword d_tag; /* Entry type. */ + union { + Elf32_Word d_val; /* Integer value. */ + Elf32_Addr d_ptr; /* Address value. */ + } d_un; +} Elf32_Dyn; + +/* + * Relocation entries. + */ + +/* Relocations that don't need an addend field. */ +typedef struct { + Elf32_Addr off; /* Location to be relocated. */ + Elf32_Word info; /* Relocation type and symbol index. */ +} Elf32_Rel; + +/* Relocations that need an addend field. */ +typedef struct { + Elf32_Addr off; /* Location to be relocated. */ + Elf32_Word info; /* Relocation type and symbol index. */ + Elf32_Sword addend; /* Addend. */ +} Elf32_Rela; + +/* Macros for accessing the fields of r_info. */ +#define ELF32_R_SYM(info) ((info) >> 8) +#define ELF32_R_TYPE(info) ((unsigned char)(info)) + +/* Macro for constructing r_info from field values. */ +#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type)) + +/* + * Relocation types. + */ + +#define R_X86_64_NONE 0 /* No relocation. */ +#define R_X86_64_64 1 /* Add 64 bit symbol value. */ +#define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */ +#define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */ +#define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */ +#define R_X86_64_COPY 5 /* Copy data from shared object. */ +#define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */ +#define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */ +#define R_X86_64_RELATIVE 8 /* Add load address of shared object. */ +#define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */ +#define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */ +#define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */ +#define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */ +#define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */ +#define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */ +#define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */ +#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ +#define R_X86_64_DTPOFF64 17 /* Offset in TLS block */ +#define R_X86_64_TPOFF64 18 /* Offset in static TLS block */ +#define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */ +#define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */ +#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ +#define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */ +#define R_X86_64_TPOFF32 23 /* Offset in static TLS block */ + +#define R_X86_64_COUNT 24 /* Count of defined relocation types. */ + + +#define R_ALPHA_NONE 0 /* No reloc */ +#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ +#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ +#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ +#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ +#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ +#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ +#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ +#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ +#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ +#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ +#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ +#define R_ALPHA_OP_PUSH 12 /* OP stack push */ +#define R_ALPHA_OP_STORE 13 /* OP stack pop and store */ +#define R_ALPHA_OP_PSUB 14 /* OP stack subtract */ +#define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */ +#define R_ALPHA_GPVALUE 16 +#define R_ALPHA_GPRELHIGH 17 +#define R_ALPHA_GPRELLOW 18 +#define R_ALPHA_IMMED_GP_16 19 +#define R_ALPHA_IMMED_GP_HI32 20 +#define R_ALPHA_IMMED_SCN_HI32 21 +#define R_ALPHA_IMMED_BR_HI32 22 +#define R_ALPHA_IMMED_LO32 23 +#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ +#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ +#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ +#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ + +#define R_ALPHA_COUNT 28 + + +#define R_ARM_NONE 0 /* No relocation. */ +#define R_ARM_PC24 1 +#define R_ARM_ABS32 2 +#define R_ARM_REL32 3 +#define R_ARM_PC13 4 +#define R_ARM_ABS16 5 +#define R_ARM_ABS12 6 +#define R_ARM_THM_ABS5 7 +#define R_ARM_ABS8 8 +#define R_ARM_SBREL32 9 +#define R_ARM_THM_PC22 10 +#define R_ARM_THM_PC8 11 +#define R_ARM_AMP_VCALL9 12 +#define R_ARM_SWI24 13 +#define R_ARM_THM_SWI8 14 +#define R_ARM_XPC25 15 +#define R_ARM_THM_XPC22 16 +#define R_ARM_COPY 20 /* Copy data from shared object. */ +#define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */ +#define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */ +#define R_ARM_RELATIVE 23 /* Add load address of shared object. */ +#define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */ +#define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */ +#define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */ +#define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */ +#define R_ARM_CALL 28 +#define R_ARM_JUMP24 29 +#define R_ARM_V4BX 40 +#define R_ARM_GOT_PREL 96 +#define R_ARM_GNU_VTENTRY 100 +#define R_ARM_GNU_VTINHERIT 101 +#define R_ARM_TLS_IE32 107 +#define R_ARM_TLS_LE32 108 +#define R_ARM_RSBREL32 250 +#define R_ARM_THM_RPC22 251 +#define R_ARM_RREL32 252 +#define R_ARM_RABS32 253 +#define R_ARM_RPC24 254 +#define R_ARM_RBASE 255 + +#define R_ARM_COUNT 38 /* Count of defined relocation types. */ + + +#define R_386_NONE 0 /* No relocation. */ +#define R_386_32 1 /* Add symbol value. */ +#define R_386_PC32 2 /* Add PC-relative symbol value. */ +#define R_386_GOT32 3 /* Add PC-relative GOT offset. */ +#define R_386_PLT32 4 /* Add PC-relative PLT offset. */ +#define R_386_COPY 5 /* Copy data from shared object. */ +#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */ +#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */ +#define R_386_RELATIVE 8 /* Add load address of shared object. */ +#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */ +#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */ +#define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */ +#define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */ +#define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */ +#define R_386_TLS_LE 17 /* Negative offset relative to static TLS */ +#define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */ +#define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */ +#define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */ +#define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */ +#define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */ +#define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */ +#define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */ +#define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */ +#define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */ +#define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */ +#define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */ +#define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */ +#define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */ +#define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */ +#define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */ +#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */ + +#define R_386_COUNT 38 /* Count of defined relocation types. */ + +#define R_PPC_NONE 0 /* No relocation. */ +#define R_PPC_ADDR32 1 +#define R_PPC_ADDR24 2 +#define R_PPC_ADDR16 3 +#define R_PPC_ADDR16_LO 4 +#define R_PPC_ADDR16_HI 5 +#define R_PPC_ADDR16_HA 6 +#define R_PPC_ADDR14 7 +#define R_PPC_ADDR14_BRTAKEN 8 +#define R_PPC_ADDR14_BRNTAKEN 9 +#define R_PPC_REL24 10 +#define R_PPC_REL14 11 +#define R_PPC_REL14_BRTAKEN 12 +#define R_PPC_REL14_BRNTAKEN 13 +#define R_PPC_GOT16 14 +#define R_PPC_GOT16_LO 15 +#define R_PPC_GOT16_HI 16 +#define R_PPC_GOT16_HA 17 +#define R_PPC_PLTREL24 18 +#define R_PPC_COPY 19 +#define R_PPC_GLOB_DAT 20 +#define R_PPC_JMP_SLOT 21 +#define R_PPC_RELATIVE 22 +#define R_PPC_LOCAL24PC 23 +#define R_PPC_UADDR32 24 +#define R_PPC_UADDR16 25 +#define R_PPC_REL32 26 +#define R_PPC_PLT32 27 +#define R_PPC_PLTREL32 28 +#define R_PPC_PLT16_LO 29 +#define R_PPC_PLT16_HI 30 +#define R_PPC_PLT16_HA 31 +#define R_PPC_SDAREL16 32 +#define R_PPC_SECTOFF 33 +#define R_PPC_SECTOFF_LO 34 +#define R_PPC_SECTOFF_HI 35 +#define R_PPC_SECTOFF_HA 36 + +#define R_PPC_COUNT 37 /* Count of defined relocation types. */ + +#define R_PPC_TLS 67 +#define R_PPC_DTPMOD32 68 +#define R_PPC_TPREL16 69 +#define R_PPC_TPREL16_LO 70 +#define R_PPC_TPREL16_HI 71 +#define R_PPC_TPREL16_HA 72 +#define R_PPC_TPREL32 73 +#define R_PPC_DTPREL16 74 +#define R_PPC_DTPREL16_LO 75 +#define R_PPC_DTPREL16_HI 76 +#define R_PPC_DTPREL16_HA 77 +#define R_PPC_DTPREL32 78 +#define R_PPC_GOT_TLSGD16 79 +#define R_PPC_GOT_TLSGD16_LO 80 +#define R_PPC_GOT_TLSGD16_HI 81 +#define R_PPC_GOT_TLSGD16_HA 82 +#define R_PPC_GOT_TLSLD16 83 +#define R_PPC_GOT_TLSLD16_LO 84 +#define R_PPC_GOT_TLSLD16_HI 85 +#define R_PPC_GOT_TLSLD16_HA 86 +#define R_PPC_GOT_TPREL16 87 +#define R_PPC_GOT_TPREL16_LO 88 +#define R_PPC_GOT_TPREL16_HI 89 +#define R_PPC_GOT_TPREL16_HA 90 + +#define R_PPC_EMB_NADDR32 101 +#define R_PPC_EMB_NADDR16 102 +#define R_PPC_EMB_NADDR16_LO 103 +#define R_PPC_EMB_NADDR16_HI 104 +#define R_PPC_EMB_NADDR16_HA 105 +#define R_PPC_EMB_SDAI16 106 +#define R_PPC_EMB_SDA2I16 107 +#define R_PPC_EMB_SDA2REL 108 +#define R_PPC_EMB_SDA21 109 +#define R_PPC_EMB_MRKREF 110 +#define R_PPC_EMB_RELSEC16 111 +#define R_PPC_EMB_RELST_LO 112 +#define R_PPC_EMB_RELST_HI 113 +#define R_PPC_EMB_RELST_HA 114 +#define R_PPC_EMB_BIT_FLD 115 +#define R_PPC_EMB_RELSDA 116 + + /* Count of defined relocation types. */ +#define R_PPC_EMB_COUNT (R_PPC_EMB_RELSDA - R_PPC_EMB_NADDR32 + 1) + + +#define R_SPARC_NONE 0 +#define R_SPARC_8 1 +#define R_SPARC_16 2 +#define R_SPARC_32 3 +#define R_SPARC_DISP8 4 +#define R_SPARC_DISP16 5 +#define R_SPARC_DISP32 6 +#define R_SPARC_WDISP30 7 +#define R_SPARC_WDISP22 8 +#define R_SPARC_HI22 9 +#define R_SPARC_22 10 +#define R_SPARC_13 11 +#define R_SPARC_LO10 12 +#define R_SPARC_GOT10 13 +#define R_SPARC_GOT13 14 +#define R_SPARC_GOT22 15 +#define R_SPARC_PC10 16 +#define R_SPARC_PC22 17 +#define R_SPARC_WPLT30 18 +#define R_SPARC_COPY 19 +#define R_SPARC_GLOB_DAT 20 +#define R_SPARC_JMP_SLOT 21 +#define R_SPARC_RELATIVE 22 +#define R_SPARC_UA32 23 +#define R_SPARC_PLT32 24 +#define R_SPARC_HIPLT22 25 +#define R_SPARC_LOPLT10 26 +#define R_SPARC_PCPLT32 27 +#define R_SPARC_PCPLT22 28 +#define R_SPARC_PCPLT10 29 +#define R_SPARC_10 30 +#define R_SPARC_11 31 +#define R_SPARC_64 32 +#define R_SPARC_OLO10 33 +#define R_SPARC_HH22 34 +#define R_SPARC_HM10 35 +#define R_SPARC_LM22 36 +#define R_SPARC_PC_HH22 37 +#define R_SPARC_PC_HM10 38 +#define R_SPARC_PC_LM22 39 +#define R_SPARC_WDISP16 40 +#define R_SPARC_WDISP19 41 +#define R_SPARC_GLOB_JMP 42 +#define R_SPARC_7 43 +#define R_SPARC_5 44 +#define R_SPARC_6 45 +#define R_SPARC_DISP64 46 +#define R_SPARC_PLT64 47 +#define R_SPARC_HIX22 48 +#define R_SPARC_LOX10 49 +#define R_SPARC_H44 50 +#define R_SPARC_M44 51 +#define R_SPARC_L44 52 +#define R_SPARC_REGISTER 53 +#define R_SPARC_UA64 54 +#define R_SPARC_UA16 55 + + +/* + * Magic number for the elf trampoline, chosen wisely to be an immediate + * value. + */ +#define ARM_MAGIC_TRAMP_NUMBER 0x5c000003 + + +/* + * Symbol table entries. + */ + +typedef struct { + Elf32_Word name; /* String table index of name. */ + Elf32_Addr value; /* Symbol value. */ + Elf32_Word size; /* Size of associated object. */ + unsigned char info; /* Type and binding information. */ + unsigned char other; /* Reserved (not used). */ + Elf32_Half shndx; /* Section index of symbol. */ +} Elf32_Sym; + +/* Macros for accessing the fields of st_info. */ +#define ELF32_ST_BIND(info) ((info) >> 4) +#define ELF32_ST_TYPE(info) ((info) & 0xf) + +/* Macro for constructing st_info from field values. */ +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* Macro for accessing the fields of st_other. */ +#define ELF32_ST_VISIBILITY(oth) ((oth) & 0x3) + +/* + * ELF definitions common to all 64-bit architectures. + */ + +typedef uint64 Elf64_Addr; +typedef uint16 Elf64_Half; +typedef uint64 Elf64_Off; +typedef int32 Elf64_Sword; +typedef int64 Elf64_Sxword; +typedef uint32 Elf64_Word; +typedef uint64 Elf64_Xword; + +/* + * Types of dynamic symbol hash table bucket and chain elements. + * + * This is inconsistent among 64 bit architectures, so a machine dependent + * typedef is required. + */ + +#ifdef __alpha__ +typedef Elf64_Off Elf64_Hashelt; +#else +typedef Elf64_Word Elf64_Hashelt; +#endif + +/* Non-standard class-dependent datatype used for abstraction. */ +typedef Elf64_Xword Elf64_Size; +typedef Elf64_Sxword Elf64_Ssize; + +/* + * ELF header. + */ + +typedef struct { + unsigned char ident[EI_NIDENT]; /* File identification. */ + Elf64_Half type; /* File type. */ + Elf64_Half machine; /* Machine architecture. */ + Elf64_Word version; /* ELF format version. */ + Elf64_Addr entry; /* Entry point. */ + Elf64_Off phoff; /* Program header file offset. */ + Elf64_Off shoff; /* Section header file offset. */ + Elf64_Word flags; /* Architecture-specific flags. */ + Elf64_Half ehsize; /* Size of ELF header in bytes. */ + Elf64_Half phentsize; /* Size of program header entry. */ + Elf64_Half phnum; /* Number of program header entries. */ + Elf64_Half shentsize; /* Size of section header entry. */ + Elf64_Half shnum; /* Number of section header entries. */ + Elf64_Half shstrndx; /* Section name strings section. */ +} Elf64_Ehdr; + +/* + * Section header. + */ + +typedef struct Elf64_Shdr Elf64_Shdr; +struct Elf64_Shdr { + Elf64_Word name; /* Section name (index into the + section header string table). */ + Elf64_Word type; /* Section type. */ + Elf64_Xword flags; /* Section flags. */ + Elf64_Addr addr; /* Address in memory image. */ + Elf64_Off off; /* Offset in file. */ + Elf64_Xword size; /* Size in bytes. */ + Elf64_Word link; /* Index of a related section. */ + Elf64_Word info; /* Depends on section type. */ + Elf64_Xword addralign; /* Alignment in bytes. */ + Elf64_Xword entsize; /* Size of each entry in section. */ +}; + +/* + * Program header. + */ + +typedef struct { + Elf64_Word type; /* Entry type. */ + Elf64_Word flags; /* Access permission flags. */ + Elf64_Off off; /* File offset of contents. */ + Elf64_Addr vaddr; /* Virtual address in memory image. */ + Elf64_Addr paddr; /* Physical address (not used). */ + Elf64_Xword filesz; /* Size of contents in file. */ + Elf64_Xword memsz; /* Size of contents in memory. */ + Elf64_Xword align; /* Alignment in memory and file. */ +} Elf64_Phdr; + +/* + * Dynamic structure. The ".dynamic" section contains an array of them. + */ + +typedef struct { + Elf64_Sxword d_tag; /* Entry type. */ + union { + Elf64_Xword d_val; /* Integer value. */ + Elf64_Addr d_ptr; /* Address value. */ + } d_un; +} Elf64_Dyn; + +/* + * Relocation entries. + */ + +/* Relocations that don't need an addend field. */ +typedef struct { + Elf64_Addr off; /* Location to be relocated. */ + Elf64_Xword info; /* Relocation type and symbol index. */ +} Elf64_Rel; + +/* Relocations that need an addend field. */ +typedef struct { + Elf64_Addr off; /* Location to be relocated. */ + Elf64_Xword info; /* Relocation type and symbol index. */ + Elf64_Sxword addend; /* Addend. */ +} Elf64_Rela; + +/* Macros for accessing the fields of r_info. */ +#define ELF64_R_SYM(info) ((info) >> 32) +#define ELF64_R_TYPE(info) ((info) & 0xffffffffL) + +/* Macro for constructing r_info from field values. */ +#define ELF64_R_INFO(sym, type) ((((uint64)(sym)) << 32) + (((uint64)(type)) & 0xffffffffULL)) + +/* + * Symbol table entries. + */ + +typedef struct { + Elf64_Word name; /* String table index of name. */ + unsigned char info; /* Type and binding information. */ + unsigned char other; /* Reserved (not used). */ + Elf64_Half shndx; /* Section index of symbol. */ + Elf64_Addr value; /* Symbol value. */ + Elf64_Xword size; /* Size of associated object. */ +} Elf64_Sym; + +/* Macros for accessing the fields of st_info. */ +#define ELF64_ST_BIND(info) ((info) >> 4) +#define ELF64_ST_TYPE(info) ((info) & 0xf) + +/* Macro for constructing st_info from field values. */ +#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* Macro for accessing the fields of st_other. */ +#define ELF64_ST_VISIBILITY(oth) ((oth) & 0x3) + +/* + * Go linker interface + */ + +#define ELF64HDRSIZE 64 +#define ELF64PHDRSIZE 56 +#define ELF64SHDRSIZE 64 +#define ELF64RELSIZE 16 +#define ELF64RELASIZE 24 +#define ELF64SYMSIZE sizeof(Elf64_Sym) + +#define ELF32HDRSIZE sizeof(Elf32_Ehdr) +#define ELF32PHDRSIZE sizeof(Elf32_Phdr) +#define ELF32SHDRSIZE sizeof(Elf32_Shdr) +#define ELF32SYMSIZE sizeof(Elf32_Sym) +#define ELF32RELSIZE 8 + +#endif /* __ELF_H__ */ diff --git a/tools/rimage/src/include/rimage/elf_file.h b/tools/rimage/src/include/rimage/elf_file.h new file mode 100644 index 000000000000..13bfe98cf1f7 --- /dev/null +++ b/tools/rimage/src/include/rimage/elf_file.h @@ -0,0 +1,178 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + * Author: Adrian Warecki <adrian.warecki@intel.com> + */ + +#ifndef __ELF_FILE_H__ +#define __ELF_FILE_H__ + +#include <stddef.h> + +#include "elf.h" + +struct elf_section_header { + Elf32_Shdr data; + char *name; +}; + +struct elf_section { + struct elf_section_header header; + void *data; +}; + +struct elf_strings { + struct elf_section section; +}; + +struct elf_file { + FILE *file; + char *filename; + size_t file_size; + Elf32_Ehdr header; + struct elf_section_header *sections; + Elf32_Phdr *programs; + uint16_t sections_count; + uint16_t programs_count; +}; + +/** + * Open elf file + * + * @param [out]elf elf file structure + * @param [in]filename File name to open + * @return error code, 0 when success + */ +int elf_open(struct elf_file *elf, const char *filename); + +/** + * Close elf file and release resources + * + * @param elf elf file structure + */ +void elf_free(struct elf_file *elf); + +/** + * Print elf file header + * + * @param elf elf file structure + */ +void elf_header_print(const struct elf_file *elf); + +/** + * Print program headers + * + * @param elf elf file structure + */ +void elf_print_programs(const struct elf_file *elf); + +/** + * Print single program header + * + * @param header program header structure + */ +void elf_program_header_print(const Elf32_Phdr *header); + +/** + * Print elf sections headers + * + * @param elf elf file structure + */ +void elf_print_sections(const struct elf_file *elf); + +/** + * Return section header by index + * + * @param [in]elf elf file structure + * @param [in]index section index + * @param [out]header section header data + * @return error code, 0 when success + */ +int elf_section_header_get_by_index(const struct elf_file *elf, int index, + const struct elf_section_header **header); + +/** + * Return section header by index + * + * @param [in]elf elf file structure + * @param [in]index section index + * @param [out]header section header data + * @return error code, 0 when success + */ +int elf_section_header_get_by_name(const struct elf_file *elf, const char* name, + const struct elf_section_header **header); +/** + * Print elf section header + * + * @param header section header structure + */ +void elf_section_header_print(const struct elf_section_header *header); + +/** + * Read elf section using given header + * + * @param [in]elf elf file structure + * @param [in]header section header + * @param [out]section section data + * @return error code, 0 when success + */ +int elf_section_read(const struct elf_file *elf, const struct elf_section_header *header, + struct elf_section *section); + +/** +* Read elf section using given header to specified buffer +* +* @param [in]elf elf file structure +* @param [in]header section header +* @param [out]buffer buffer for a section data +* @param [in]size buffer size +* @return error code, 0 when success +*/ +int elf_section_read_content(const struct elf_file *elf, const struct elf_section_header *header, + void *buffer, const size_t size); + +/** + * Read elf section with given name + * + * @param [in]elf elf file structure + * @param [in]name section name + * @param [out]section section data + * @return error code, 0 when success + */ +int elf_section_read_by_name(const struct elf_file *elf, const char *name, struct elf_section *section); + +/** + * Release section + * + * @param [in]section section structure + */ +void elf_section_free(struct elf_section *section); + +/** + * Read elf strings section with given index + * + * @param [in]elf elf file structure + * @param [in]index strings section index + * @param [out]strings strings section data + * @return error code, 0 when success + */ +int elf_strings_read_by_index(const struct elf_file *elf, int index, struct elf_strings *strings); + +/** + * Get string value. Allocate new copy using strdup. + * + * @param [in]strings strings section structure + * @param [in]index string index + * @param [out]str Pointer to the variable in which the pointer to the allocated string will be placed + * @return error code, 0 when success + */ +int elf_strings_get(const struct elf_strings *strings, int index, char **str); + +/** + * Release string section + * @param [in]strings strings section structure + */ +void elf_strings_free(struct elf_strings *strings); + +#endif /* __ELF_FILE_H__ */ diff --git a/tools/rimage/src/include/rimage/ext_manifest_gen.h b/tools/rimage/src/include/rimage/ext_manifest_gen.h new file mode 100644 index 000000000000..7f106834a0ca --- /dev/null +++ b/tools/rimage/src/include/rimage/ext_manifest_gen.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2020 Intel Corporation. All rights reserved. + * + * Author: Karol Trzcinski <karolx.trzcinski@linux.intel.com> + */ + +/* + * Extended manifest is a place to store metadata about firmware, known during + * compilation time - for example firmware version or used compiler. + * Given information are read on host side before firmware startup. + * This part of output binary is not signed. + * + * To add new content to ext_man, in firmware code define struct which starts + * with ext_man_elem_head followed by usage dependent content and place whole + * struct in "fw_metadata" section. Moreover kernel code should be modified to + * properly read new packet. + * + * Extended manifest designed to be extensible. In header there is a field which + * describe header length, so after appending some data to header then it can be + * easily skipped by device with older version of this header. + * From other side, unknown ext_man elements should be just skipped by host, + * to be backward compatible. Field ext_man_elem_header.elem_size should be + * used in such a situation. + */ + +#ifndef __EXT_MAN_H__ +#define __EXT_MAN_H__ + +#include <rimage/rimage.h> + +#define EXT_MAN_DATA_SECTION ".fw_metadata" + +int ext_man_write(struct image *image); +int ext_man_write_cavs_25(struct image *image); + +#endif /* __EXT_MAN_H__ */ diff --git a/tools/rimage/src/include/rimage/file_utils.h b/tools/rimage/src/include/rimage/file_utils.h new file mode 100644 index 000000000000..34ecc89f5bad --- /dev/null +++ b/tools/rimage/src/include/rimage/file_utils.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + */ + +#ifndef __FILE_UTILS_H__ +#define __FILE_UTILS_H__ + +#include <stddef.h> + +/** + * Print file operation error message + * @param [in]msg error message + * @param [in]filename File name used to display the error message + * @param error code + */ +int file_error(const char *msg, const char *filename); + +/** + * Create new file name using output file name as template. + * @param [out] new_name char[] destination of new file name + * @param [in] name_size new file name buffer capacity + * @param [in] template_name File name used as a template for the new name + * @param [in] new_ext extension of the new file name + * @param error code, 0 when success + */ +int create_file_name(char *new_name, const size_t name_size, const char *template_name, + const char *new_ext); + +/** + * Get file size + * @param [in] f file handle + * @param [in] filename File name used to display the error message + * @param [out] size output for file size + * @param error code, 0 when success + */ +int get_file_size(FILE *f, const char *filename, size_t *size); + +#endif /* __FILE_UTILS_H__ */ diff --git a/tools/rimage/src/include/rimage/hash.h b/tools/rimage/src/include/rimage/hash.h new file mode 100644 index 000000000000..47a00101af4f --- /dev/null +++ b/tools/rimage/src/include/rimage/hash.h @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + */ + +#ifndef __HASH_H__ +#define __HASH_H__ + +#include <openssl/conf.h> +#include <openssl/evp.h> +#include <openssl/err.h> + +#include <stdint.h> + +/* Hash context state used to detect invalid use of hash functions */ +enum hash_state { HS_INIT, HS_UPDATE, HS_DONE, HS_ERROR }; + +struct hash_context { + enum hash_state state; + EVP_MD_CTX *context; + const EVP_MD *algo; + uint8_t digest[EVP_MAX_MD_SIZE]; + unsigned int digest_length; + int error; +}; + +/** + * Initialize hash context with given algorithm + * @param [out]context structure storing the hash context + * @param [in]algo hash algorithm + * @return error code, 0 when success + */ +int hash_init(struct hash_context *context, const EVP_MD *algo); + +/** + * Initialize sha256 hash context + * @param [out]context structure storing the hash context + * @return error code, 0 when success + */ +int hash_sha256_init(struct hash_context *context); + +/** + * Initialize sha384 hash context + * @param [out]context structure storing the hash context + * @return error code, 0 when success + */ +int hash_sha384_init(struct hash_context *context); + +/** + * Add data to hash + * @param [in]context structure storing the hash context + * @param [in]data data to be added + * @param [in]size length of data in bytes + * @return error code, 0 when success + */ +int hash_update(struct hash_context *context, const void *data, size_t size); + +/** + * Completes the hash calculation. No more data can be added! + * @param [in]context structure storing the hash context + * @return error code, 0 when success + */ +int hash_finalize(struct hash_context *context); + +/** + * Read out computed digest. Must finalize first. + * @param [in]context structure storing the hash context + * @param [out]output pointer to array where place hash value + * @param [in]output_len size of the output buffer + * @return copied digest length, < 0 if error + */ +int hash_get_digest(struct hash_context *context, void *output, size_t output_len); + +/** + * Print digest value + * @param [in]context structure storing the hash context + */ +void hash_print(struct hash_context *context); + +/** + * Calculates hash of a single memory buffer + * @param [in]data pointer to the data to be processed + * @param [in]size length of the data to be processed + * @param [in]algo hash algorithm + * @param [out]output pointer to array where place hash value + * @param [in]output_len size of the output buffer + * @return error code, 0 when success + */ +int hash_single(const void* data, size_t size, const EVP_MD *algo, void *output, size_t output_len); + +/** + * Calculates sha256 hash of a memory buffer + * @param [in]data pointer to the data to be processed + * @param [in]size length of the data to be processed + * @param [out]output pointer to array where place hash value + * @param [in]output_len size of the output buffer + * @return error code, 0 when success + */ +int hash_sha256(const void* data, size_t size, void *output, size_t output_len); + +/** + * Calculates sha384 hash of a memory buffer + * @param [in]data pointer to the data to be processed + * @param [in]size length of the data to be processed + * @param [out]output pointer to array where place hash value + * @param [in]output_len size of the output buffer + * @return error code, 0 when success + */ +int hash_sha384(const void* data, size_t size, void *output, size_t output_len); + +#endif /* __HASH_H__ */ diff --git a/tools/rimage/src/include/rimage/manifest.h b/tools/rimage/src/include/rimage/manifest.h new file mode 100644 index 000000000000..840cd7d797bf --- /dev/null +++ b/tools/rimage/src/include/rimage/manifest.h @@ -0,0 +1,239 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2017 Intel Corporation. All rights reserved. + */ + +#ifndef __MANIFEST_H__ +#define __MANIFEST_H__ + +#include <stdint.h> +#include <stdbool.h> +#include <rimage/sof/user/manifest.h> +#include <rimage/css.h> +#include <rimage/cse.h> +#include <rimage/plat_auth.h> +#include <rimage/module.h> + +/* + * Manifest module data + */ +struct manifest_module { + struct module file; + + /* Following fields are used in manifest creation process */ + bool is_bootloader; + + /* Size of the module in the output image. + * Includes text and data sections size + image headers*/ + size_t output_size; + + /* executable header module */ + int exec_header; + + /* module offset in image file */ + size_t foffset; + + size_t text_fixup_size; +}; + +#define MAN_PAGE_SIZE 4096 + +/* start offset for modules built using xcc */ +#define DEFAULT_XCC_MOD_OFFSET 0x8 + +/* start offset for base FW module */ +#define FILE_TEXT_OFFSET_V1_8 0x8000 +#define FILE_TEXT_OFFSET_V1_5 0x2000 +#define FILE_TEXT_OFFSET_V1_5_SUE 0xA000 + +/* + * CSE values for CNL + */ +#define MAN_CSE_PARTS 3 + + +#define MAN_CSE_HDR_OFFSET 0 +#define MAN_CSE_PADDING_SIZE 0x30 +#define MAN_EXT_PADDING 0x20 +#define MAN_DESC_OFFSET_V1_8 0x2000 +#define MAN_DESC_OFFSET_V1_5 0x284 +#define MAN_DESC_OFFSET_V1_5_SUE 0x2000 +#define MAN_DEFAULT_IMR_TYPE 3 + +#define MAN_CSS_HDR_OFFSET \ + (MAN_CSE_HDR_OFFSET + \ + sizeof(struct CsePartitionDirHeader) + \ + MAN_CSE_PARTS * sizeof(struct CsePartitionDirEntry)) + +#define MAN_CSS_HDR_OFFSET_2_5 \ + (MAN_CSE_HDR_OFFSET + \ + sizeof(struct CsePartitionDirHeader_v2_5) + \ + MAN_CSE_PARTS * sizeof(struct CsePartitionDirEntry)) + +#define MAN_FW_DESC_OFFSET_ACE_V1_5 \ + (MAN_META_EXT_OFFSET_ACE_V1_5 + \ + sizeof(struct sof_man_adsp_meta_file_ext_v2_5) + \ + MAN_EXT_PADDING) + +#define MAN_FW_DESC_OFFSET_V2_5 \ + (MAN_META_EXT_OFFSET_V2_5 + \ + sizeof(struct sof_man_adsp_meta_file_ext_v2_5) + \ + MAN_EXT_PADDING) + +#define MAN_DESC_PADDING_SIZE_ACE_V1_5 \ + (MAN_DESC_OFFSET_V1_8 - MAN_FW_DESC_OFFSET_ACE_V1_5) + +#define MAN_DESC_PADDING_SIZE_V2_5 \ + (MAN_DESC_OFFSET_V1_8 - MAN_FW_DESC_OFFSET_V2_5) + +#define MAN_SIG_PKG_OFFSET_V1_8 \ + (MAN_CSS_HDR_OFFSET + \ + sizeof(struct css_header_v1_8)) + +#define MAN_SIG_PKG_OFFSET_V2_5 \ + (MAN_CSS_HDR_OFFSET_2_5 + \ + sizeof(struct css_header_v2_5)) + +#define MAN_PART_INFO_OFFSET_V1_8 \ + (MAN_SIG_PKG_OFFSET_V1_8 + \ + sizeof(struct signed_pkg_info_ext)) + +#define MAN_PART_INFO_OFFSET_ACE_V1_5 \ + (MAN_SIG_PKG_OFFSET_V2_5 + \ + sizeof(struct signed_pkg_info_ext_ace_v1_5)) + +#define MAN_PART_INFO_OFFSET_V2_5 \ + (MAN_SIG_PKG_OFFSET_V2_5 + \ + sizeof(struct signed_pkg_info_ext_v2_5)) + +#define MAN_META_EXT_OFFSET_V1_8 \ + (MAN_SIG_PKG_OFFSET_V1_8 + \ + sizeof(struct signed_pkg_info_ext) + \ + sizeof(struct partition_info_ext) + \ + MAN_CSE_PADDING_SIZE) + +#define MAN_META_EXT_OFFSET_ACE_V1_5 \ + (MAN_SIG_PKG_OFFSET_V2_5 + \ + sizeof(struct signed_pkg_info_ext_ace_v1_5) + \ + sizeof(struct info_ext_0x16) + \ + 0) + +#define MAN_META_EXT_OFFSET_V2_5 \ + (MAN_SIG_PKG_OFFSET_V2_5 + \ + sizeof(struct signed_pkg_info_ext_v2_5) + \ + sizeof(struct info_ext_0x16) + \ + 0) + +#define MAN_FW_DESC_OFFSET_V1_8 \ + (MAN_META_EXT_OFFSET_V1_8 + \ + sizeof(struct sof_man_adsp_meta_file_ext_v1_8) + \ + MAN_EXT_PADDING) + +#define MAN_DESC_PADDING_SIZE_V1_8 \ + (MAN_DESC_OFFSET_V1_8 - MAN_FW_DESC_OFFSET_V1_8) + +#define MAN_SIG_PKG_OFFSET_V1_5 \ + (MAN_CSS_HDR_OFFSET + \ + sizeof(struct css_header_v1_5)) + +#define MAN_META_EXT_OFFSET_V1_5 \ + (MAN_SIG_PKG_OFFSET_V1_5 + \ + sizeof(struct signed_pkg_info_ext) + \ + sizeof(struct partition_info_ext) + \ + MAN_CSE_PADDING_SIZE) + +#define MAN_FW_DESC_OFFSET_V1_5 \ + (MAN_META_EXT_OFFSET_V1_5 + \ + sizeof(struct sof_man_adsp_meta_file_ext_v1_8) + \ + MAN_EXT_PADDING) + +/* + * Firmware manifest header ACE V1_5 used on MTL onwards + */ +struct fw_image_manifest_ace_v1_5 { + /* MEU tool needs these sections to be 0s */ + struct CsePartitionDirHeader_v2_5 cse_partition_dir_header; + struct CsePartitionDirEntry cse_partition_dir_entry[MAN_CSE_PARTS]; + struct css_header_v2_5 css; + struct signed_pkg_info_ext_ace_v1_5 signed_pkg; + struct info_ext_0x16 info_0x16; + + struct sof_man_adsp_meta_file_ext_v2_5 adsp_file_ext; + + /* reserved / pading at end of ext data - all 0s*/ + uint8_t reserved[MAN_EXT_PADDING]; + + /* start of the unsigned binary for MEU input must start at MAN_DESC_OFFSET */ + uint8_t padding[MAN_DESC_PADDING_SIZE_ACE_V1_5]; + + struct sof_man_fw_desc desc; /* at offset MAN_DESC_OFFSET */ +} __attribute__((packed)); + +/* + * Firmware manifest header V2.5 used on TGL onwards + */ +struct fw_image_manifest_v2_5 { + /* MEU tool needs these sections to be 0s */ + struct CsePartitionDirHeader_v2_5 cse_partition_dir_header; + struct CsePartitionDirEntry cse_partition_dir_entry[MAN_CSE_PARTS]; + struct css_header_v2_5 css; + struct signed_pkg_info_ext_v2_5 signed_pkg; + struct info_ext_0x16 info_0x16; + + struct sof_man_adsp_meta_file_ext_v2_5 adsp_file_ext; + + /* reserved / pading at end of ext data - all 0s*/ + uint8_t reserved[MAN_EXT_PADDING]; + + /* start of the unsigned binary for MEU input must start at MAN_DESC_OFFSET */ + uint8_t padding[MAN_DESC_PADDING_SIZE_V2_5]; + + struct sof_man_fw_desc desc; /* at offset MAN_DESC_OFFSET */ +} __attribute__((packed)); + +/* + * Firmware manifest header V1.8 used on APL onwards + */ +struct fw_image_manifest_v1_8 { + /* MEU tool needs these sections to be 0s */ + struct CsePartitionDirHeader cse_partition_dir_header; + struct CsePartitionDirEntry cse_partition_dir_entry[MAN_CSE_PARTS]; + struct css_header_v1_8 css; + struct signed_pkg_info_ext signed_pkg; + struct partition_info_ext partition_info; + uint8_t cse_padding[MAN_CSE_PADDING_SIZE]; + struct sof_man_adsp_meta_file_ext_v1_8 adsp_file_ext; + + /* reserved / pading at end of ext data - all 0s*/ + uint8_t reserved[MAN_EXT_PADDING]; + + /* start of the unsigned binary for MEU input must start at MAN_DESC_OFFSET */ + uint8_t padding[MAN_DESC_PADDING_SIZE_V1_8]; + + struct sof_man_fw_desc desc; /* at offset MAN_DESC_OFFSET */ +} __attribute__((packed)); + +/* + * Firmware manifest header V1.5 used on SKL and KBL + */ +struct fw_image_manifest_v1_5 { + struct css_header_v1_5 css_header; + struct sof_man_fw_desc desc; +} __attribute__((packed)); + +struct fw_image_manifest_v1_5_sue { + struct sof_man_fw_desc desc; +} __attribute__((packed)); + +struct image; +int simple_write_firmware(struct image *image); +int man_write_fw_v1_5(struct image *image); +int man_write_fw_v1_5_sue(struct image *image); +int man_write_fw_v1_8(struct image *image); +int man_write_fw_v2_5(struct image *image); +int man_write_fw_ace_v1_5(struct image *image); +int man_write_fw_meu_v1_5(struct image *image); +int man_write_fw_meu_v1_8(struct image *image); +int man_write_fw_meu_v2_5(struct image *image); + +#endif diff --git a/tools/rimage/src/include/rimage/misc_utils.h b/tools/rimage/src/include/rimage/misc_utils.h new file mode 100644 index 000000000000..e3432d57a391 --- /dev/null +++ b/tools/rimage/src/include/rimage/misc_utils.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + */ + +#ifndef __MISC_UTILS_H__ +#define __MISC_UTILS_H__ + +#include <stdint.h> + +#define DIV_ROUND_UP(val, div) (((val) + (div) - 1) / (div)) + +/** + * Reverses the order of bytes in the array + * @param ptr pointer to a array + * @param size of the array + */ +void bytes_swap(uint8_t *ptr, uint32_t size); + +struct name_val { + const char *name; + unsigned long value; +}; + +#define NAME_VAL_ENTRY(x) { .name = #x, .value = x } +#define NAME_VAL_END { .name = 0, .value = 0 } + +void print_enum(unsigned long value, const struct name_val *values); +void print_flags(unsigned long value, const struct name_val *flags); + +#endif /* __MISC_UTILS_H__ */ diff --git a/tools/rimage/src/include/rimage/module.h b/tools/rimage/src/include/rimage/module.h new file mode 100644 index 000000000000..872b559ddbd2 --- /dev/null +++ b/tools/rimage/src/include/rimage/module.h @@ -0,0 +1,191 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + * Author: Adrian Warecki <adrian.warecki@intel.com> + */ + +#ifndef __MODULE_H__ +#define __MODULE_H__ + +#include <stdint.h> +#include <stdbool.h> +#include <stdio.h> + +#include <rimage/elf_file.h> + +enum module_section_type { + MST_UNKNOWN, MST_DATA, MST_TEXT, MST_BSS, MST_NOTE +}; + +struct module_section { + const struct elf_section_header *header; + enum module_section_type type; + + /* The contents of the section lie in the rom memory space */ + bool rom; + + /* ADSP devices have their RAM regions mapped twice. The first mapping is set in the CPU + * to bypass the L1 cache, and so access through pointers in that region is coherent between + * CPUs (but slow). The second region accesses the same memory through the L1 cache and + * requires careful flushing when used with shared data. + * + * This distinction is exposed in the linker script, where some symbols (e.g. stack regions) + * are linked into cached memory, but others (general kernel memory) are not. + * + * Addresses of sections belonging to a rom memory are not converted. */ + + /* section virtual address, converted to cached address space */ + uint32_t address; + + /* section physical load address, converted to cached address space */ + uint32_t load_address; + + size_t size; + + /* next section of this type */ + struct module_section *next_section; +}; + +struct module_sections_info { + /* start address */ + uint32_t start; + + /* end address */ + uint32_t end; + + /* size without any gaps */ + size_t size; + + /* size include gap to nearest page */ + size_t file_size; + + /* sections count */ + unsigned int count; + + /* sections list */ + struct module_section *first_section; + struct module_section *last_section; +}; + +/* + * ELF module data + */ +struct module { + struct elf_file elf; + + /* Array of valid sections */ + struct module_section *sections; + + /* Number of valid sections */ + unsigned int num_sections; + + struct module_sections_info text; + struct module_sections_info data; + struct module_sections_info bss; +}; + +struct image; +struct memory_alias; +struct memory_config; + +/** + * Convert uncached memory address to cached + * + * @param alias alias memory configration + * @param address address to be converted + * @return cached address + */ +unsigned long uncache_to_cache(const struct memory_alias *alias, unsigned long address); + + +/** + * Load module file + * + * @param module module structure + * @param filename module file name + * @param verbose verbose logging selection + * @return error code + */ +int module_open(struct module *module, const char *filename, const bool verbose); + +/** + * Unloads module + * + * @param module module structure + */ +void module_close(struct module *module); + +/** + * Parse module sections + * + * @param module module structure + * @param mem_cfg memory configration structure + * @param verbose verbose logging selection + * @return error code + */ +void module_parse_sections(struct module *module, const struct memory_config *mem_cfg, + bool verbose); + +/** + * Read module section to memory buffer + * + * @param [in]module module structure + * @param [in]section module section structure + * @param [out]buffer destination buffer + * @param [in]size destination buffer size + * @return error code + */ +int module_read_section(const struct module *module, const struct module_section *section, + void *buffer, const size_t size); + +/** + * Read module section and write it to a file + * + * @param module module structure + * @param section module section structure + * @param padding count of padding bytes to write after section content + * @param out_file destination file handle + * @param filename output file name used to print error message + * @return error code + */ +int module_write_section(const struct module *module, const struct module_section *section, + const int padding, FILE *out_file, const char *filename); + +/** + * Read whole module elf file to a memory buffer + * + * @param [in]module module structure + * @param [out]buffer destination buffer + * @param [in]size destination buffer size + * @return error code + */ +int module_read_whole_elf(const struct module *module, void *buffer, size_t size); + +/** + * Read whore module elf file and write it to a file + * + * @param module module structure + * @param out_file destination file handle + * @param filename output file name used to print error message + * @return error code + */ +int module_write_whole_elf(const struct module *module, FILE *out_file, const char *filename); + +/** + * Displays information about the occupancy of each memory zone + * + * @param module module structure + */ +void module_print_zones(const struct module *module); + +/** + * Checks all modules to make sure their sections do not overlap with each other + * + * @param module module structure + * @param image program global structure + * @return error code + */ +int modules_validate(const struct image *image); + +#endif /* __MODULE_H__ */ diff --git a/tools/rimage/src/include/rimage/plat_auth.h b/tools/rimage/src/include/rimage/plat_auth.h new file mode 100644 index 000000000000..64cdcd98db5f --- /dev/null +++ b/tools/rimage/src/include/rimage/plat_auth.h @@ -0,0 +1,155 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2017 Intel Corporation. All rights reserved. + */ + +#ifndef __PLAT_AUTH_H__ +#define __PLAT_AUTH_H__ + +#include <stdint.h> + +struct image; + +#define PLAT_AUTH_SHA256_LEN 32 +#define PLAT_AUTH_SHA384_LEN 48 +#define PLAT_AUTH_NAME_LEN 12 +#define PLAT_AUTH_PADDING 48 /* pad at end of struct */ + +#define SIGN_PKG_EXT_TYPE 15 +#define SIGN_PKG_NUM_MODULE 1 + +#define SIGN_PKG_EXT_TYPE_ACE_V1_5 0x23 + +struct signed_pkg_info_module { + uint8_t name[PLAT_AUTH_NAME_LEN]; /* must be padded with 0 */ + uint8_t type; + uint8_t hash_algo; + uint16_t hash_size; + uint32_t meta_size; + uint8_t hash[PLAT_AUTH_SHA256_LEN]; +} __attribute__((packed)); + +struct signed_pkg_info_module_v2_5 { + uint8_t name[PLAT_AUTH_NAME_LEN]; /* must be padded with 0 */ + uint8_t type; + uint8_t hash_algo; + uint16_t hash_size; + uint32_t meta_size; + uint8_t hash[PLAT_AUTH_SHA384_LEN]; +} __attribute__((packed)); + +struct signed_pkg_info_ext { + uint32_t ext_type; + uint32_t ext_len; + + uint8_t name[4]; + uint32_t vcn; + uint8_t bitmap[16]; + uint32_t svn; + uint8_t fw_type; + uint8_t fw_sub_type; + uint8_t reserved[14]; /* must be 0 */ + + /* variable length of modules */ + struct signed_pkg_info_module module[SIGN_PKG_NUM_MODULE]; +} __attribute__((packed)); + +struct signed_pkg_info_ext_v2_5 { + uint32_t ext_type; + uint32_t ext_len; + + uint8_t name[4]; + uint32_t vcn; /* 0 */ + uint8_t bitmap[16]; + uint32_t svn; + uint8_t fw_type; + uint8_t fw_sub_type; + uint8_t reserved[14]; /* must be 0 */ + + /* variable length of modules */ + struct signed_pkg_info_module_v2_5 module[SIGN_PKG_NUM_MODULE]; +} __attribute__((packed)); + +struct signed_pkg_info_module_ace_v1_5 { + uint8_t name[PLAT_AUTH_NAME_LEN]; /* must be padded with 0 */ + uint8_t type; + uint8_t hash_algo; + uint8_t reserved[2]; + uint32_t meta_size; + uint8_t hash[PLAT_AUTH_SHA384_LEN]; +} __attribute__((packed)); + +struct signed_pkg_info_ext_ace_v1_5 { + uint32_t ext_type; + uint32_t ext_len; + + uint8_t name[4]; + uint32_t vcn; /* 0 */ + uint32_t svn; + uint8_t partition_usage; + uint8_t reserved0; + uint8_t fw_type; + uint8_t fw_sub_type; + uint8_t number_of_modules; + uint8_t boot_strap_svn; + uint8_t reserved[14]; /* must be 0 */ + + /* variable length of modules */ + struct signed_pkg_info_module_ace_v1_5 module[SIGN_PKG_NUM_MODULE]; +} __attribute__((packed)); + +#define PART_INFO_EXT_TYPE 3 +#define PART_INFO_NUM_MODULE 1 + +struct partition_info_module { + uint8_t name[PLAT_AUTH_NAME_LEN]; /* must be padded with 0 */ + uint8_t type; + uint8_t reserved[3]; + uint32_t meta_size; + uint8_t hash[PLAT_AUTH_SHA256_LEN]; +} __attribute__((packed)); + +struct partition_info_ext { + uint32_t ext_type; + uint32_t ext_len; + + uint8_t name[4]; /* "ADSP" */ + uint32_t length; + uint8_t hash[PLAT_AUTH_SHA256_LEN]; + + uint32_t vcn; + uint32_t part_version; + uint32_t fmt_version; + uint32_t instance_id; + uint32_t part_flags; + uint8_t reserved[20]; /* must be 0 */ + + /* variable length of modules */ + struct partition_info_module module[PART_INFO_NUM_MODULE]; +} __attribute__((packed)); + +/* offset 0x458 id */ +struct info_ext_0x16 { + uint32_t ext_type; /* 0x16 */ + uint32_t ext_len; /* 0x68 */ + uint8_t name[4]; /* ADSP */ + uint32_t size; /* file size */ + uint32_t data[5]; /* 0 = 0x10000000, 0, 1, 1, 0x3003 */ + uint8_t hash[PLAT_AUTH_SHA384_LEN]; + uint32_t data1[5]; +} __attribute__((packed)); + + +#define PLAT_AUTH_SIZE \ + (sizeof(struct partition_info_ext) + \ + sizeof(struct signed_pkg_info_ext)) + +void ri_adsp_meta_data_create_v1_8(struct image *image, int meta_start_offset, + int meta_end_offset); +void ri_adsp_meta_data_create_v2_5(struct image *image, int meta_start_offset, + int meta_end_offset); +void ri_plat_ext_data_create(struct image *image); +void ri_plat_ext_data_create_v2_5(struct image *image); +void ri_plat_ext_data_create_ace_v1_5(struct image *image); + +#endif diff --git a/tools/rimage/src/include/rimage/rimage.h b/tools/rimage/src/include/rimage/rimage.h new file mode 100644 index 000000000000..61bc77bfca42 --- /dev/null +++ b/tools/rimage/src/include/rimage/rimage.h @@ -0,0 +1,175 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2015-2018 Intel Corporation. All rights reserved. + */ + +#ifndef __RIMAGE_H__ +#define __RIMAGE_H__ + +#include <stdint.h> +#include <stdio.h> + +#include <rimage/manifest.h> +#include <rimage/cavs/cavs_ext_manifest.h> +#include <rimage/sof/kernel/fw.h> + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#define MAX_MODULES 32 + +struct adsp; + +/* + * Firmware image context. + */ +struct image { + + const char *out_file; + const char *in_file; + FILE *out_fd; + void *pos; + + struct adsp *adsp; + int abi; + int verbose; + int reloc; /* ELF data is relocatable */ + int num_modules; + struct manifest_module module[MAX_MODULES]; + uint32_t image_end;/* module end, equal to output image size */ + int meu_offset; + const char *verify_file; + + /* private key file name*/ + const char *key_name; + + /* file IO */ + void *fw_image; + void *rom_image; + FILE *out_rom_fd; + FILE *out_man_fd; + FILE *out_ext_man_fd; + FILE *out_unsigned_fd; + char out_rom_file[256]; + char out_man_file[256]; + char out_ext_man_file[256]; + char out_unsigned_file[256]; + + /* fw version and build id */ + char* fw_ver_string; + char* fw_ver_build_string; + uint16_t fw_ver_major; + uint16_t fw_ver_minor; + uint16_t fw_ver_micro; + uint16_t fw_ver_build; + + uint32_t imr_type; + + /* Output image is a loadable module */ + bool loadable_module; +}; + +struct memory_zone { + uint32_t base; + uint32_t size; + uint32_t host_offset; +}; + +struct memory_alias { + uint32_t mask; + uint32_t cached; + uint32_t uncached; +}; + +struct memory_config { + struct memory_zone zones[SOF_FW_BLK_TYPE_NUM]; + struct memory_alias alias; +}; + +struct fw_image_ext_mod_config { + struct fw_ext_mod_config_header header; + struct mod_scheduling_caps sched_caps; + struct fw_pin_description *pin_desc; +}; + +struct fw_image_ext_module { + uint32_t mod_conf_count; + struct fw_image_ext_mod_config ext_mod_config_array[FW_MAX_EXT_MODULE_NUM]; +}; + +/* + * module manifest information defined in config file + */ +struct fw_image_manifest_module { + struct fw_image_ext_module mod_ext; + uint32_t mod_cfg_count; + struct sof_man_mod_config *mod_cfg; + uint32_t mod_man_count; + struct sof_man_module *mod_man; +}; + +/* + * Audio DSP descriptor and operations. + */ +struct adsp { + const char *name; + struct memory_config mem; + + uint32_t image_size; + + int (*write_firmware_ext_man)(struct image *image); + int (*write_firmware)(struct image *image); + int (*write_firmware_meu)(struct image *image); + int (*verify_firmware)(struct image *image); + struct fw_image_manifest_ace_v1_5 *man_ace_v1_5; + struct fw_image_manifest_v2_5 *man_v2_5; + struct fw_image_manifest_v1_8 *man_v1_8; + struct fw_image_manifest_v1_5 *man_v1_5; + struct fw_image_manifest_v1_5_sue *man_v1_5_sue; + struct fw_image_manifest_module *modules; + int exec_boot_ldr; +}; + +int ri_manifest_sign_v1_5(struct image *image); +int ri_manifest_sign_v1_8(struct image *image); +int ri_manifest_sign_v2_5(struct image *image); +int ri_manifest_sign_ace_v1_5(struct image *image); + +int pkcs_v1_5_sign_man_v1_5(struct image *image, + struct fw_image_manifest_v1_5 *man, + void *ptr1, unsigned int size1); +int pkcs_v1_5_sign_man_v1_8(struct image *image, + struct fw_image_manifest_v1_8 *man, + void *ptr1, unsigned int size1, void *ptr2, + unsigned int size2); +int pkcs_v1_5_sign_man_v2_5(struct image *image, + struct fw_image_manifest_v2_5 *man, + void *ptr1, unsigned int size1, void *ptr2, + unsigned int size2); +int pkcs_v1_5_sign_man_ace_v1_5(struct image *image, + struct fw_image_manifest_ace_v1_5 *man, + void *ptr1, unsigned int size1, void *ptr2, + unsigned int size2); + +int verify_image(struct image *image); +int ri_manifest_verify_v1_5(struct image *image); +int ri_manifest_verify_v1_8(struct image *image); +int ri_manifest_verify_v2_5(struct image *image); +int pkcs_v1_5_verify_man_v1_5(struct image *image, + struct fw_image_manifest_v1_5 *man, + void *ptr1, unsigned int size1); +int pkcs_v1_5_verify_man_v1_8(struct image *image, + struct fw_image_manifest_v1_8 *man, + void *ptr1, unsigned int size1, void *ptr2, + unsigned int size2); +int pkcs_v1_5_verify_man_v2_5(struct image *image, + struct fw_image_manifest_v2_5 *man, + void *ptr1, unsigned int size1, void *ptr2, + unsigned int size2); +int pkcs_v1_5_verify_man_ace_v1_5(struct image *image, + struct fw_image_manifest_ace_v1_5 *man, + void *ptr1, unsigned int size1, void *ptr2, + unsigned int size2); + +int resign_image(struct image *image); +int get_key_size(struct image *image); + +#endif diff --git a/tools/rimage/src/include/rimage/sof/kernel/ext_manifest.h b/tools/rimage/src/include/rimage/sof/kernel/ext_manifest.h new file mode 100644 index 000000000000..7d9b77735a11 --- /dev/null +++ b/tools/rimage/src/include/rimage/sof/kernel/ext_manifest.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2020 Intel Corporation. All rights reserved. + * + * Author: Karol Trzcinski <karolx.trzcinski@linux.intel.com> + */ + +/* + * Extended manifest is a place to store metadata about firmware, known during + * compilation time - for example firmware version or used compiler. + * Given information are read on host side before firmware startup. + * This part of output binary is not signed. + * + * To add new content to ext_man, in firmware code define struct which starts + * with ext_man_elem_head followed by usage dependent content and place whole + * struct in "fw_metadata" section. Moreover kernel code should be modified to + * properly read new packet. + * + * Extended manifest is designed to be extensible. In header there is a field + * which describe header length, so after appending some data to header then it + * can be easily skipped by device with older version of this header. + * Unknown ext_man elements should be just skipped by host, + * to be backward compatible. Field `ext_man_elem_header.elem_size` should be + * used in such a situation. + */ + +#ifndef __RIMAGE_KERNEL_EXT_MANIFEST_H__ +#define __RIMAGE_KERNEL_EXT_MANIFEST_H__ + +#include <stdint.h> + +#ifndef __packed +#define __packed __attribute__((packed)) +#endif + +/* In ASCII `XMan` */ +#define EXT_MAN_MAGIC_NUMBER 0x6e614d58 + +/* Build u32 number in format MMmmmppp */ +#define EXT_MAN_BUILD_VERSION(MAJOR, MINOR, PATH) ( \ + ((uint32_t)(MAJOR) << 24) | \ + ((uint32_t)(MINOR) << 12) | \ + (uint32_t)(PATH)) + +/* check extended manifest version consistency */ +#define EXT_MAN_VERSION_INCOMPATIBLE(host_ver, cli_ver) ( \ + ((host_ver) & GENMASK(31, 24)) != \ + ((cli_ver) & GENMASK(31, 24))) + +/* used extended manifest header version */ +#define EXT_MAN_VERSION EXT_MAN_BUILD_VERSION(1, 0, 0) + +/* struct size alignment for ext_man elements */ +#define EXT_MAN_ALIGN 16 + +/* extended manifest header, deleting any field breaks backward compatibility */ +struct ext_man_header { + uint32_t magic; /**< identification number, */ + /**< EXT_MAN_MAGIC_NUMBER */ + uint32_t full_size; /**< [bytes] full size of ext_man, */ + /**< (header + content + padding) */ + uint32_t header_size; /**< [bytes] makes header extensionable, */ + /**< after append new field to ext_man header */ + /**< then backward compatible won't be lost */ + uint32_t header_version; /**< value of EXT_MAN_VERSION */ + /**< not related with following content */ + + /* just after this header should be list of ext_man_elem_* elements */ +} __packed; + +/* Now define extended manifest elements */ + +/* extended manifest element header */ +struct ext_man_elem_header { + uint32_t type; /**< EXT_MAN_ELEM_* */ + uint32_t elem_size; /**< in bytes, including header size */ + + /* just after this header should be type dependent content */ +} __packed; + +#endif /* __RIMAGE_KERNEL_EXT_MANIFEST_H__ */ diff --git a/tools/rimage/src/include/rimage/sof/kernel/fw.h b/tools/rimage/src/include/rimage/sof/kernel/fw.h new file mode 100644 index 000000000000..14c8ca0c1585 --- /dev/null +++ b/tools/rimage/src/include/rimage/sof/kernel/fw.h @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2018 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> + * Keyon Jie <yang.jie@linux.intel.com> + */ + +/* + * Firmware file format . + */ + +#ifndef __RIMAGE_KERNEL_FW_H__ +#define __RIMAGE_KERNEL_FW_H__ + +#include <stdint.h> + +#define SND_SOF_FW_SIG_SIZE 4 +#define SND_SOF_FW_ABI 1 +#define SND_SOF_FW_SIG "Reef" + +/* + * Firmware module is made up of 1 . N blocks of different types. The + * Block header is used to determine where and how block is to be copied in the + * DSP/host memory space. + */ +enum snd_sof_fw_blk_type { + SOF_FW_BLK_TYPE_INVALID = -1, + SOF_FW_BLK_TYPE_START = 0, + SOF_FW_BLK_TYPE_RSRVD0 = SOF_FW_BLK_TYPE_START, + SOF_FW_BLK_TYPE_IRAM = 1, /* local instruction RAM */ + SOF_FW_BLK_TYPE_DRAM = 2, /* local data RAM */ + SOF_FW_BLK_TYPE_SRAM = 3, /* system RAM */ + SOF_FW_BLK_TYPE_ROM = 4, + SOF_FW_BLK_TYPE_IMR = 5, + SOF_FW_BLK_TYPE_HPSRAM = 6, + SOF_FW_BLK_TYPE_LPSRAM = 7, + SOF_FW_BLK_TYPE_RSRVD8 = 8, + SOF_FW_BLK_TYPE_RSRVD9 = 9, + SOF_FW_BLK_TYPE_RSRVD10 = 10, + SOF_FW_BLK_TYPE_RSRVD11 = 11, + SOF_FW_BLK_TYPE_RSRVD12 = 12, + SOF_FW_BLK_TYPE_RSRVD13 = 13, + SOF_FW_BLK_TYPE_RSRVD14 = 14, + /* use SOF_FW_BLK_TYPE_RSVRDX for new block types */ + SOF_FW_BLK_TYPE_NUM +}; + +struct snd_sof_blk_hdr { + enum snd_sof_fw_blk_type type; + uint32_t size; /* bytes minus this header */ + uint32_t offset; /* offset from base */ +} __attribute__((packed)); + +/* + * Firmware file is made up of 1 .. N different modules types. The module + * type is used to determine how to load and parse the module. + */ +enum snd_sof_fw_mod_type { + SOF_FW_BASE = 0, /* base firmware image */ + SOF_FW_MODULE = 1, /* firmware module */ +}; + +struct snd_sof_mod_hdr { + enum snd_sof_fw_mod_type type; + uint32_t size; /* bytes minus this header */ + uint32_t num_blocks; /* number of blocks */ +} __attribute__((packed)); + +/* + * Firmware file header. + */ +struct snd_sof_fw_header { + unsigned char sig[SND_SOF_FW_SIG_SIZE]; /* "Reef" */ + uint32_t file_size; /* size of file minus this header */ + uint32_t num_modules; /* number of modules */ + uint32_t abi; /* version of header format */ +} __attribute__((packed)); + +#endif /* __RIMAGE_KERNEL_FW_H__ */ diff --git a/tools/rimage/src/include/rimage/sof/user/manifest.h b/tools/rimage/src/include/rimage/sof/user/manifest.h new file mode 100644 index 000000000000..d270ce98b309 --- /dev/null +++ b/tools/rimage/src/include/rimage/sof/user/manifest.h @@ -0,0 +1,238 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2017 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> + */ + +/** + * \file include/user/manifest.h + * \brief FW Image Manifest definitions. + * \author Liam Girdwood <liam.r.girdwood@linux.intel.com> + */ + +#ifndef __RIMAGE_USER_MANIFEST_H__ +#define __RIMAGE_USER_MANIFEST_H__ + +#include <stdint.h> + +/* start offset for base FW module */ +#define SOF_MAN_ELF_TEXT_OFFSET 0x2000 + +/* FW Extended Manifest Header id = $AE1 */ +#define SOF_MAN_EXT_HEADER_MAGIC 0x31454124 + +/* module type load type */ +#define SOF_MAN_MOD_TYPE_BUILTIN 0 +#define SOF_MAN_MOD_TYPE_MODULE 1 + +/* module init config */ +#define SOF_MAN_MOD_INIT_CONFIG_BASE_CFG 0 /* Base config only */ +#define SOF_MAN_MOD_INIT_CONFIG_BASE_CFG_WITH_EXT 1 /* Base config with extension */ + +#define MAN_MAX_SIZE_V1_8 (38 * 1024) + + +struct sof_man_module_type { + uint32_t load_type:4; /* SOF_MAN_MOD_TYPE_ */ + uint32_t auto_start:1; + uint32_t domain_ll:1; + uint32_t domain_dp:1; + uint32_t lib_code:1; + uint32_t init_config:4; /* SOF_MAN_MOD_INIT_CONFIG_ */ + uint32_t rsvd_:20; +}; + +/* segment flags.type */ +#define SOF_MAN_SEGMENT_TEXT 0 +#define SOF_MAN_SEGMENT_RODATA 1 +#define SOF_MAN_SEGMENT_DATA 1 +#define SOF_MAN_SEGMENT_BSS 2 +#define SOF_MAN_SEGMENT_EMPTY 15 + +union sof_man_segment_flags { + uint32_t ul; + struct { + uint32_t contents:1; + uint32_t alloc:1; + uint32_t load:1; + uint32_t readonly:1; + uint32_t code:1; + uint32_t data:1; + uint32_t _rsvd0:2; + uint32_t type:4; /* MAN_SEGMENT_ */ + uint32_t _rsvd1:4; + uint32_t length:16; /* of segment in pages */ + } r; +} __attribute__((packed)); + +/* + * Module segment descriptor. Used by ROM - Immutable. + */ +struct sof_man_segment_desc { + union sof_man_segment_flags flags; + uint32_t v_base_addr; + uint32_t file_offset; +} __attribute__((packed)); + +/* + * The firmware binary can be split into several modules. + */ + +#define SOF_MAN_MOD_ID_LEN 4 +#define SOF_MAN_MOD_NAME_LEN 8 +#define SOF_MAN_MOD_SHA256_LEN 32 +#define SOF_MAN_MOD_SHA384_LEN 48 +#define SOF_MAN_MOD_ID {'$', 'A', 'M', 'E'} + +/* + * Each module has an entry in the FW header. Used by ROM - Immutable. + */ +struct sof_man_module { + uint8_t struct_id[SOF_MAN_MOD_ID_LEN]; /* SOF_MAN_MOD_ID */ + uint8_t name[SOF_MAN_MOD_NAME_LEN]; + uint8_t uuid[16]; + struct sof_man_module_type type; + uint8_t hash[SOF_MAN_MOD_SHA256_LEN]; + uint32_t entry_point; + uint16_t cfg_offset; + uint16_t cfg_count; + uint32_t affinity_mask; + uint16_t instance_max_count; /* max number of instances */ + uint16_t instance_bss_size; /* instance (pages) */ + struct sof_man_segment_desc segment[3]; +} __attribute__((packed)); + +/* + * Each module has a configuration in the FW header. Used by ROM - Immutable. + */ +struct sof_man_mod_config { + uint32_t par[4]; /* module parameters */ + uint32_t is_pages; /* actual size of instance .bss (pages) */ + uint32_t cps; /* cycles per second */ + uint32_t ibs; /* input buffer size (bytes) */ + uint32_t obs; /* output buffer size (bytes) */ + uint32_t module_flags; /* flags, reserved for future use */ + uint32_t cpc; /* cycles per single run */ + uint32_t obls; /* output block size, reserved for future use */ +} __attribute__((packed)); + +/* + * FW Manifest Header + */ + +#define SOF_MAN_FW_HDR_FW_NAME_LEN 8 +#define SOF_MAN_FW_HDR_ID {'$', 'A', 'M', '1'} +#define SOF_MAN_FW_HDR_NAME "ADSPFW" +#define SOF_MAN_FW_HDR_FLAGS 0x0 +#define SOF_MAN_FW_HDR_FEATURES 0xffff + +/* + * The firmware has a standard header that is checked by the ROM on firmware + * loading. preload_page_count is used by DMA code loader and is entire + * image size on CNL. i.e. CNL: total size of the binary’s .text and .rodata + * Used by ROM - Immutable. + */ +struct sof_man_fw_header { + uint8_t header_id[4]; + uint32_t header_len; + uint8_t name[SOF_MAN_FW_HDR_FW_NAME_LEN]; + /* number of pages of preloaded image loaded by driver */ + uint32_t preload_page_count; + uint32_t fw_image_flags; + uint32_t feature_mask; + uint16_t major_version; + uint16_t minor_version; + uint16_t hotfix_version; + uint16_t build_version; + uint32_t num_module_entries; + uint32_t fw_compat; + uint32_t hw_buf_length; + /* target address for binary loading as offset in IMR - must be == base offset */ + uint32_t load_offset; +} __attribute__((packed)); + +/* + * Firmware manifest descriptor. This can contain N modules and N module + * configs. Used by ROM - Immutable. + */ +struct sof_man_fw_desc { + struct sof_man_fw_header header; + + /* Warning - hack for module arrays. For some unknown reason the we + * have a variable size array of struct man_module followed by a + * variable size array of struct mod_config. These should have been + * merged into a variable array of a parent structure. We have to hack + * around this in many places.... + * + * struct sof_man_module man_module[]; + * struct sof_man_mod_config mod_config[]; + */ + +} __attribute__((packed)); + +#define SOF_MAN_COMP_SHA256_LEN 32 +#define SOF_MAN_COMP_SHA384_LEN 48 + +/* + * Component Descriptor for manifest v1.8. Used by ROM - Immutable. + */ +struct sof_man_component_desc_v1_8 { + uint32_t reserved[2]; /* all 0 */ + uint32_t version; + uint8_t hash[SOF_MAN_COMP_SHA256_LEN]; + uint32_t base_offset; + uint32_t limit_offset; + uint32_t attributes[4]; +} __attribute__((packed)); + +/* + * Audio DSP extended metadata for manifest v1.8. Used by ROM - Immutable. + */ +struct sof_man_adsp_meta_file_ext_v1_8 { + uint32_t ext_type; /* always 17 for ADSP extension */ + uint32_t ext_len; + uint32_t imr_type; + uint8_t reserved[16]; /* all 0 */ + struct sof_man_component_desc_v1_8 comp_desc[1]; +} __attribute__((packed)); + +/* + * Component Descriptor for manifest v2.5. Used by ROM - Immutable. + */ +struct sof_man_component_desc_v2_5 { + uint32_t reserved[2]; /* all 0 */ + uint32_t version; + uint8_t hash[SOF_MAN_COMP_SHA384_LEN]; + uint32_t base_offset; + uint32_t limit_offset; + uint32_t attributes[4]; +} __attribute__((packed)); + +/* + * Audio DSP extended metadata for manifest v2.5. Used by ROM - Immutable. + */ +struct sof_man_adsp_meta_file_ext_v2_5 { + uint32_t ext_type; /* always 17 for ADSP extension */ + uint32_t ext_len; + uint32_t imr_type; + uint8_t reserved[16]; /* all 0 */ + struct sof_man_component_desc_v2_5 comp_desc[1]; +} __attribute__((packed)); + +/* + * Module Manifest for rimage module metadata. Not used by ROM. + */ +struct sof_man_module_manifest { + struct sof_man_module module; + uint32_t text_size; +}; + +/* + * Module offset in manifest. + */ +#define SOF_MAN_MODULE_OFFSET(index) \ + (sizeof(struct sof_man_fw_header) + \ + (index) * sizeof(struct sof_man_module)) + +#endif /* __RIMAGE_USER_MANIFEST_H__ */ diff --git a/tools/rimage/src/include/rimage/toml_utils.h b/tools/rimage/src/include/rimage/toml_utils.h new file mode 100644 index 000000000000..22f257c2c65d --- /dev/null +++ b/tools/rimage/src/include/rimage/toml_utils.h @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + * Author: Karol Trzcinski <karolx.trzcinski@linux.intel.com> + * Marc Herbert <marc.herbert@intel.com> + */ + +#ifndef __TOML_UTILS_H__ +#define __TOML_UTILS_H__ + +#include "toml.h" + +#include <stdint.h> +#include <stdio.h> +#include <stdarg.h> + +/** parser counter, used to assert nothing left unparsed in toml data */ +struct parse_ctx { + int key_cnt; /**< number of parsed key */ + int table_cnt; /**< number of parsed tables */ + int array_cnt; /**< number of parsed arrays */ +}; + +/* macros used to dump values after parsing */ +#define DUMP_KEY_FMT " %20s: " +#define DUMP(fmt, ...) fprintf(stdout, fmt "\n", ##__VA_ARGS__) +#define DUMP_KEY(key, fmt, ...) DUMP(DUMP_KEY_FMT fmt, key, ##__VA_ARGS__) + +void print_bytes(FILE *out, const uint8_t *arr, size_t len); + +#define DUMP_PRINTABLE_BYTES(name, var) _dump_printable_bytes(name, var, sizeof(var)) + +void _dump_printable_bytes(const char *name, const uint8_t *arr, size_t len); + +/** private parser error trace function */ +void vlog_err(const char *msg, va_list vl); + +/** parser error trace function, error code is returned to shorten client code */ +int log_err(int err_code, const char *msg, ...); + +/** log malloc error message for given key */ +int err_malloc(const char *key); + +/** log key not found error */ +int err_key_not_found(const char *key); + +/** error during parsing key value, possible detailed message */ +int err_key_parse(const char *key, const char *extra_msg, ...); + +/** initialize parser context before parsing */ +void parse_ctx_init(struct parse_ctx *ctx); + +/** check nothing left unparsed in given parsing context */ +int assert_everything_parsed(const toml_table_t *table, struct parse_ctx *ctx); + +/** + * Parse hex value from key in given toml table + * @param table toml table where key is specified + * @param ctx parsing context, key counter will be incremented after successful key parse + * @param key field name + * @param def is default value or -1 when value don't have default value + * @param error code, 0 when success + * @return default, parsed, or UINT32_MAX value for error cases + */ +uint32_t parse_uint32_hex_key(const toml_table_t *table, struct parse_ctx *ctx, + const char *key, int64_t def, int *error); + +/** + * Parse integer value from key in given toml table + * @param table toml table where key is specified + * @param ctx parsing context, key counter will be incremented after successful key parse + * @param key field name + * @param def is default value or -1 when value don't have default value + * @param error code, 0 when success + * @return default, parsed, or UINT32_MAX value for error cases + */ +uint32_t parse_uint32_key(const toml_table_t *table, struct parse_ctx *ctx, const char *key, + int64_t def, int *error); + +/** + * Parse string value from key in given toml table to uint8_t array. The + * destination is NOT a string because it is padded with zeros if and + * only if there is some capacity left. For string destinations use + * parse_str_key(). + * + * @param table toml table where key is specified + * @param ctx parsing context, key counter will be incremented after successful key parse + * @param key field name + * @param dst uint8_t[] destination + * @param capacity dst array size + * @param error code, 0 when success + */ +void parse_printable_key(const toml_table_t *table, struct parse_ctx *ctx, const char *key, + uint8_t *dst, int capacity, int *error); + +/** + * Parse string value from key in given toml table to given + * char[]. Destination is padded with zeros. As the only difference with + * parse_printable_key(), dst is guaranteed to be null-terminated when + * there is no error because the last destination byte is reserved for + * that. + * + * @param table toml table where key is specified + * @param ctx parsing context, key counter will be incremented after successful key parse + * @param key field name + * @param dst char[] destination + * @param capacity dst array size including null termination. + * @param error code, 0 when success + */ +void parse_str_key(const toml_table_t *table, struct parse_ctx *ctx, const char *key, + char *dst, int capacity, int *error); + +/** + * Parse UUID hex string into a byte array. The endianness of the output + * is architecture-dependent: do not use in any portable code. + */ +void parse_uuid(const char *buf, uint8_t *uuid); + +/** version is stored as toml array with integer number, something like: + * "version = [1, 8]" + */ +int parse_version(toml_table_t *toml, int64_t version[2]); + +#endif /* __TOML_UTILS_H__ */ diff --git a/tools/rimage/src/manifest.c b/tools/rimage/src/manifest.c new file mode 100644 index 000000000000..19b73ee38e35 --- /dev/null +++ b/tools/rimage/src/manifest.c @@ -0,0 +1,1631 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2018-2022 Intel Corporation. All rights reserved. +// +// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> +// Keyon Jie <yang.jie@linux.intel.com> +// Janusz Jankowski <janusz.jankowski@linux.intel.com> + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> +#include <time.h> +#include <sys/time.h> + +#include <rimage/sof/user/manifest.h> + +#include <rimage/rimage.h> +#include <rimage/css.h> +#include <rimage/cse.h> +#include <rimage/plat_auth.h> +#include <rimage/manifest.h> +#include <rimage/file_utils.h> +#include <rimage/misc_utils.h> +#include <rimage/hash.h> + +static int man_open_rom_file(struct image *image) +{ + uint32_t size; + int ret; + + ret = create_file_name(image->out_rom_file, sizeof(image->out_rom_file), image->out_file, + "rom"); + if (ret) + return ret; + + size = image->adsp->mem.zones[SOF_FW_BLK_TYPE_ROM].size; + + /* allocate ROM image */ + image->rom_image = calloc(size, 1); + if (!image->rom_image) + return -ENOMEM; + + /* open ROM outfile for writing */ + image->out_rom_fd = fopen(image->out_rom_file, "wb"); + if (!image->out_rom_fd) + return file_error("unable to open file for writing", image->out_rom_file); + + return 0; +} + +static int man_open_unsigned_file(struct image *image) +{ + int ret; + + ret = create_file_name(image->out_unsigned_file, sizeof(image->out_unsigned_file), + image->out_file, "uns"); + if (ret) + return ret; + + /* open unsigned FW outfile for writing */ + image->out_unsigned_fd = fopen(image->out_unsigned_file, "wb"); + if (!image->out_unsigned_fd) + return file_error("unable to open file for writing", image->out_unsigned_file); + + return 0; +} + +static int man_open_manifest_file(struct image *image) +{ + int ret; + + ret = create_file_name(image->out_man_file, sizeof(image->out_man_file), image->out_file, + "met"); + if (ret) + return ret; + + /* open manifest outfile for writing */ + image->out_man_fd = fopen(image->out_man_file, "wb"); + if (!image->out_man_fd) + return file_error("unable to open file for writing", image->out_man_file); + + return 0; +} + +static int man_init_image_v1_5(struct image *image) +{ + /* allocate image and copy template manifest */ + image->fw_image = calloc(image->adsp->image_size, 1); + if (!image->fw_image) + return -ENOMEM; + + memcpy(image->fw_image, image->adsp->man_v1_5, + sizeof(struct fw_image_manifest_v1_5)); + + return 0; +} + +static int man_init_image_v1_5_sue(struct image *image) +{ + /* allocate image and copy template manifest */ + image->fw_image = calloc(image->adsp->image_size, 1); + if (!image->fw_image) + return -ENOMEM; + + /* copy 1.5 sue manifest */ + memcpy(image->fw_image + MAN_DESC_OFFSET_V1_5_SUE, + image->adsp->man_v1_5_sue, + sizeof(struct fw_image_manifest_v1_5_sue)); + + return 0; +} + +static int man_init_image_v1_8(struct image *image) +{ + /* allocate image and copy template manifest */ + image->fw_image = calloc(image->adsp->image_size, 1); + if (!image->fw_image) + return -ENOMEM; + + memcpy(image->fw_image, image->adsp->man_v1_8, + sizeof(struct fw_image_manifest_v1_8)); + + return 0; +} + +static int man_init_image_v2_5(struct image *image) +{ + /* allocate image and copy template manifest */ + image->fw_image = calloc(image->adsp->image_size, 1); + if (!image->fw_image) + return -ENOMEM; + + memcpy(image->fw_image, image->adsp->man_v2_5, + sizeof(struct fw_image_manifest_v2_5)); + + return 0; +} + +/* write SRAM sections */ +static int man_copy_sram(struct image *image, const struct manifest_module *module, + const struct sof_man_segment_desc *segment, + const struct module_section *section) +{ + uint32_t offset, end; + int ret; + + assert(section->load_address >= segment->v_base_addr); + offset = segment->file_offset + section->load_address - segment->v_base_addr; + end = offset + section->size; + assert((uint64_t)offset + section->size <= image->adsp->image_size); + + ret = module_read_section(&module->file, section, image->fw_image + offset, + image->adsp->image_size - offset); + if (ret) + return ret; + + /* get module end offset ? */ + if (end > image->image_end) + image->image_end = end; + + fprintf(stdout, "\t0x%x\t0x%zx\t\t0x%x\t%s\t%s\n", section->load_address, section->size, + offset, section->type == MST_TEXT ? "TEXT" : "DATA", section->header->name); + + return 0; +} + +/** + * Write all linked sections + * + * @param image program global structure + * @param module modules manifest description + * @param section module section descriptor + * @return error code on error, 0 on success + */ +static int man_copy_elf_sections(struct image *image, struct manifest_module *module, + const struct sof_man_segment_desc *segment, + const struct module_section *section) +{ + int ret; + + while (section) { + ret = man_copy_sram(image, module, segment, section); + if (ret < 0) { + fprintf(stderr, "error: failed to write section %s\n", + section->header->name); + return ret; + } + + section = section->next_section; + } + + return 0; +} + +static int man_get_module_manifest(struct image *image, struct manifest_module *module, + struct sof_man_module *man_module) +{ + struct elf_section section; + struct sof_man_segment_desc *segment; + const struct sof_man_module_manifest *sof_mod; + int ret; + + fprintf(stdout, "Module Write: %s\n", module->file.elf.filename); + + /* load in module manifest data */ + ret = elf_section_read_by_name(&module->file.elf, ".module", §ion); + if (ret) { + fprintf(stderr, "error: can't read module manifest from '.module' section.\n"); + return ret; + } + + if (sizeof(*sof_mod) > section.header.data.size) { + fprintf(stderr, "error: Invalid module manifest in '.module' section.\n"); + ret = -ENODATA; + goto error; + } + sof_mod = section.data; + + /* configure man_module with sofmod data */ + memcpy(man_module->struct_id, "$AME", 4); + man_module->entry_point = sof_mod->module.entry_point; + memcpy(man_module->name, sof_mod->module.name, SOF_MAN_MOD_NAME_LEN); + memcpy(man_module->uuid, sof_mod->module.uuid, 16); + man_module->affinity_mask = sof_mod->module.affinity_mask; + man_module->type.auto_start = sof_mod->module.type.auto_start; + man_module->type.domain_dp = sof_mod->module.type.domain_dp; + man_module->type.domain_ll = sof_mod->module.type.domain_ll; + man_module->type.load_type = sof_mod->module.type.load_type; + + /* read out text_fixup_size from memory mapping */ + module->text_fixup_size = sof_mod->text_size; + + /* text segment */ + segment = &man_module->segment[SOF_MAN_SEGMENT_TEXT]; + segment->flags.r.contents = 1; + segment->flags.r.alloc = 1; + segment->flags.r.load = 1; + segment->flags.r.readonly = 1; + segment->flags.r.code = 1; + + /* data segment */ + segment = &man_module->segment[SOF_MAN_SEGMENT_RODATA]; + segment->flags.r.contents = 1; + segment->flags.r.alloc = 1; + segment->flags.r.load = 1; + segment->flags.r.readonly = 1; + segment->flags.r.data = 1; + segment->flags.r.type = 1; + + /* bss segment */ + segment = &man_module->segment[SOF_MAN_SEGMENT_BSS]; + segment->flags.r.alloc = 1; + segment->flags.r.type = 2; + + fprintf(stdout, " Entry point 0x%8.8x\n", man_module->entry_point); + +error: + elf_section_free(§ion); + return ret; +} + +static inline const char *segment_name(int i) +{ + switch (i) { + case SOF_MAN_SEGMENT_TEXT: + return "TEXT"; + case SOF_MAN_SEGMENT_RODATA: + return "DATA"; + case SOF_MAN_SEGMENT_BSS: + return "BSS"; + default: + return "NONE"; + } +} + +/* make sure no segments collide */ +static int man_module_validate(struct sof_man_module *man_module) +{ + uint32_t istart, iend; + uint32_t jstart, jend; + int i, j; + + for (i = 0; i < 3; i++) { + istart = man_module->segment[i].v_base_addr; + iend = istart + man_module->segment[i].flags.r.length * + MAN_PAGE_SIZE; + + for (j = 0; j < 3; j++) { + /* don't validate segment against itself */ + if (i == j) + continue; + + jstart = man_module->segment[j].v_base_addr; + jend = jstart + man_module->segment[j].flags.r.length * + MAN_PAGE_SIZE; + + if (jstart > istart && jstart < iend) + goto err; + + if (jend > istart && jend < iend) + goto err; + } + } + + /* success, no overlapping segments */ + return 0; + +err: + fprintf(stderr, "error: segment %s [0x%8.8x:0x%8.8x] overlaps", + segment_name(i), istart, iend); + fprintf(stderr, " with %s [0x%8.8x:0x%8.8x]\n", + segment_name(j), jstart, jend); + return -EINVAL; +} + +static int man_module_create(struct image *image, struct manifest_module *module, + struct sof_man_module *man_module) +{ + /* create module and segments */ + int err; + unsigned int pages; + const struct elf_section_header *bss; + + image->image_end = 0; + + err = man_get_module_manifest(image, module, man_module); + if (err < 0) + return err; + + /* stack size ??? convert sizes to PAGES */ + man_module->instance_bss_size = 1; + + /* max number of instances of this module ?? */ + man_module->instance_max_count = 1; + + module_print_zones(&module->file); + + /* main module */ + fprintf(stdout, "\tAddress\t\tSize\t\tFile\tType\tName\n"); + + /* text section is first */ + man_module->segment[SOF_MAN_SEGMENT_TEXT].file_offset = module->foffset; + man_module->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr = module->file.text.start; + + /* calculates those padding 0s by the start of next segment */ + /* file_size is already aligned to MAN_PAGE_SIZE */ + pages = module->file.text.file_size / MAN_PAGE_SIZE; + + if (module->text_fixup_size == 0) + module->text_fixup_size = module->file.text.file_size; + + /* check if text_file_size is bigger then text_fixup_size */ + if (module->file.text.file_size > module->text_fixup_size) { + fprintf(stderr, "error: too small text size assigned!\n"); + return -EINVAL; + } + + man_module->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length = pages; + + /* Copy text sections content */ + err = man_copy_elf_sections(image, module, &man_module->segment[SOF_MAN_SEGMENT_TEXT], + module->file.text.first_section); + if (err) + return err; + + + /* data section */ + man_module->segment[SOF_MAN_SEGMENT_RODATA].v_base_addr = module->file.data.start; + man_module->segment[SOF_MAN_SEGMENT_RODATA].file_offset = module->foffset + + module->text_fixup_size; + + /* file_size is already aligned to MAN_PAGE_SIZE */ + pages = module->file.data.file_size / MAN_PAGE_SIZE; + + man_module->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length = pages; + + /* Copy data sections content */ + err = man_copy_elf_sections(image, module, &man_module->segment[SOF_MAN_SEGMENT_RODATA], + module->file.data.first_section); + if (err) + return err; + + /* bss is last */ + + /* I do not understand why only the section named .bss was taken into account. Other + * sections of the same type were ignored (type = SHT_NOBITS, flags = SHF_ALLOC). I added + * the reading of the .bss section here, to not change the behavior of the program. + */ + bss = NULL; + + if (module->is_bootloader) { + /* Bootloader should not have .bss section. */ + fprintf(stdout, "info: ignore .bss section for bootloader module\n"); + } else { + err = elf_section_header_get_by_name(&module->file.elf, ".bss", &bss); + if (err) + fprintf(stderr, "warning: can't find '.bss' section in module %s.\n", + module->file.elf.filename); + + } + + man_module->segment[SOF_MAN_SEGMENT_BSS].file_offset = 0; + man_module->segment[SOF_MAN_SEGMENT_BSS].v_base_addr = 0; + pages = 0; + + if (bss) { + man_module->segment[SOF_MAN_SEGMENT_BSS].v_base_addr = + uncache_to_cache(&image->adsp->mem.alias, bss->data.vaddr); + + pages = DIV_ROUND_UP(bss->data.size, MAN_PAGE_SIZE); + } + + man_module->segment[SOF_MAN_SEGMENT_BSS].flags.r.length = pages; + if (pages == 0) { + man_module->segment[SOF_MAN_SEGMENT_BSS].flags.ul = 0; + man_module->segment[SOF_MAN_SEGMENT_BSS].flags.r.type = SOF_MAN_SEGMENT_EMPTY; + } + + if (man_module_validate(man_module) < 0) + return -EINVAL; + + fprintf(stdout, "\n"); + + /* no need to update end for exec headers */ + if (module->exec_header) { + image->image_end = FILE_TEXT_OFFSET_V1_5_SUE; + goto out; + } + + /* round module end upto nearest page */ + if (image->image_end % MAN_PAGE_SIZE) { + image->image_end = (image->image_end / MAN_PAGE_SIZE) + 1; + image->image_end *= MAN_PAGE_SIZE; + } + +out: + fprintf(stdout, " Total pages text %d data %d bss %d module file limit: 0x%x\n\n", + man_module->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length, + man_module->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length, + man_module->segment[SOF_MAN_SEGMENT_BSS].flags.r.length, + image->image_end); + return 0; +} + +static int man_module_create_reloc(struct image *image, struct manifest_module *module, + struct sof_man_module *man_module) +{ + /* create module and segments */ + int err; + + image->image_end = 0; + + err = man_get_module_manifest(image, module, man_module); + if (err < 0) + return err; + + /* stack size ??? convert sizes to PAGES */ + man_module->instance_bss_size = 1; + + /* max number of instances of this module ?? */ + man_module->instance_max_count = 1; + + module_print_zones(&module->file); + + /* main module */ + /* text section is first */ + man_module->segment[SOF_MAN_SEGMENT_TEXT].file_offset = + module->foffset; + man_module->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr = 0; + man_module->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length = 0; + + /* data section */ + man_module->segment[SOF_MAN_SEGMENT_RODATA].v_base_addr = 0; + man_module->segment[SOF_MAN_SEGMENT_RODATA].file_offset = module->foffset; + man_module->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length = module->file.data.file_size / + MAN_PAGE_SIZE; + + /* bss is last */ + man_module->segment[SOF_MAN_SEGMENT_BSS].file_offset = 0; + man_module->segment[SOF_MAN_SEGMENT_BSS].v_base_addr = 0; + man_module->segment[SOF_MAN_SEGMENT_BSS].flags.r.length = 0; + + fprintf(stdout, "\tNo\tAddress\t\tSize\t\tFile\tType\n"); + + assert((module->file.elf.file_size + module->foffset) <= image->adsp->image_size); + err = module_read_whole_elf(&module->file, image->fw_image + module->foffset, + image->image_end - module->foffset); + if (err) + return err; + + fprintf(stdout, "\t%d\t0x%8.8x\t0x%8.8zx\t0x%x\t%s\n", 0, + 0, module->file.elf.file_size, 0, "DATA"); + + fprintf(stdout, "\n"); + image->image_end = module->foffset + module->file.elf.file_size; + + /* round module end up to nearest page */ + if (image->image_end % MAN_PAGE_SIZE) { + image->image_end = (image->image_end / MAN_PAGE_SIZE) + 1; + image->image_end *= MAN_PAGE_SIZE; + } + + fprintf(stdout, " Total pages text %d data %d bss %d module file limit: 0x%x\n\n", + man_module->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length, + man_module->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length, + man_module->segment[SOF_MAN_SEGMENT_BSS].flags.r.length, + image->image_end); + return 0; +} + +static int man_write_unsigned_mod(struct image *image, int meta_start_offset, + int meta_end_offset, size_t ext_file_size) +{ + int count; + + /* write metadata file for unsigned FW */ + count = fwrite(image->fw_image + meta_start_offset, + ext_file_size, 1, + image->out_man_fd); + + /* did the metadata/manifest write succeed ? */ + if (count != 1) + return file_error("failed to write meta", image->out_man_file); + + fclose(image->out_man_fd); + + /* now prepare the unsigned rimage */ + count = fwrite(image->fw_image + meta_end_offset, + image->image_end - meta_end_offset, + 1, image->out_unsigned_fd); + + /* did the unsigned FW write succeed ? */ + if (count != 1) + return file_error("failed to write firmware", image->out_unsigned_file); + fclose(image->out_unsigned_fd); + + return 0; +} + +static int man_write_fw_mod(struct image *image) +{ + int count; + + /* write manifest and signed image */ + count = fwrite(image->fw_image, image->image_end, 1, image->out_fd); + + /* did the image write succeed ? */ + if (count != 1) + return file_error("failed to write signed firmware", image->out_file); + + return 0; +} + +static int man_create_modules(struct image *image, struct sof_man_fw_desc *desc, + int file_text_offset) +{ + struct manifest_module *module; + struct sof_man_module *man_module; + int err; + int i = 0, offset = 0; + + /* if first module is executable then write before manifest */ + if (image->adsp->exec_boot_ldr) { + man_module = (void *)desc + SOF_MAN_MODULE_OFFSET(0); + module = &image->module[0]; + + fprintf(stdout, "Module: %s used as executable header\n", + module->file.elf.filename); + module->exec_header = 1; + + /* set module file offset */ + module->foffset = 0; + + err = man_module_create(image, module, man_module); + if (err < 0) + return err; + + /* setup man_modules for missing exec loader module */ + i = 1; + offset = 1; + } + + for (; i < image->num_modules; i++) { + man_module = (void *)desc + SOF_MAN_MODULE_OFFSET(i - offset); + + /* Some platforms dont have modules configuration in toml file */ + if (image->adsp->modules) { + /* Use manifest created using toml files as template */ + assert(i < image->adsp->modules->mod_man_count); + memcpy(man_module, &image->adsp->modules->mod_man[i], sizeof(*man_module)); + } + + module = &image->module[i]; + + if (i == 0) + module->foffset = file_text_offset; + else + module->foffset = image->image_end; + + if (image->reloc) + err = man_module_create_reloc(image, module, + man_module); + else + err = man_module_create(image, module, man_module); + + if (err < 0) + return err; + } + + return 0; +} + +static void man_create_modules_in_config(struct image *image, struct sof_man_fw_desc *desc) +{ + struct fw_image_manifest_module *modules; + struct sof_man_module *man_module; + void *cfg_start; + int i; + + modules = image->adsp->modules; + if (!modules) + return; + + /* skip modules passed as parameters. Their manifests have already been copied by the + * man_create_modules function. */ + for (i = image->num_modules; i < modules->mod_man_count; i++) { + man_module = (void *)desc + SOF_MAN_MODULE_OFFSET(i); + memcpy(man_module, &modules->mod_man[i], sizeof(*man_module)); + } + + /* We need to copy the configurations for all modules. */ + cfg_start = (void *)desc + SOF_MAN_MODULE_OFFSET(i); + memcpy(cfg_start, modules->mod_cfg, modules->mod_cfg_count * sizeof(struct sof_man_mod_config)); + + desc->header.num_module_entries = modules->mod_man_count; +} + +static int man_hash_modules(struct image *image, struct sof_man_fw_desc *desc) +{ + struct sof_man_module *man_module; + size_t mod_offset, mod_size; + int i, ret = 0; + + for (i = 0; i < image->num_modules; i++) { + man_module = (void *)desc + SOF_MAN_MODULE_OFFSET(i); + + if (image->adsp->exec_boot_ldr && i == 0) { + fprintf(stdout, " module: no need to hash %s\n as its exec header\n", + man_module->name); + continue; + } + + mod_offset = man_module->segment[SOF_MAN_SEGMENT_TEXT].file_offset; + mod_size = (man_module->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length + + man_module->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length) * + MAN_PAGE_SIZE; + + assert((mod_offset + mod_size) <= image->adsp->image_size); + + ret = hash_sha256(image->fw_image + mod_offset, mod_size, man_module->hash, sizeof(man_module->hash)); + if (ret) + break; + } + + return ret; +} + +/* used by others */ +int man_write_fw_v1_5(struct image *image) +{ + struct sof_man_fw_desc *desc; + struct fw_image_manifest_v1_5 *m; + int ret; + + /* init image */ + ret = man_init_image_v1_5(image); + if (ret < 0) + goto err; + + /* open ROM image */ + ret = man_open_rom_file(image); + if (ret < 0) + goto err; + + /* open unsigned firmware */ + ret = man_open_unsigned_file(image); + if (ret < 0) + goto err; + + /* create the manifest */ + ret = man_open_manifest_file(image); + if (ret < 0) + goto err; + + /* create the module */ + m = image->fw_image; + desc = image->fw_image + MAN_DESC_OFFSET_V1_5; + + /* firmware and build version */ + m->desc.header.major_version = image->fw_ver_major; + m->desc.header.minor_version = image->fw_ver_minor; + m->desc.header.hotfix_version = image->fw_ver_micro; + m->desc.header.build_version = image->fw_ver_build; + + /* create each module */ + m->desc.header.num_module_entries = image->num_modules; + ret = man_create_modules(image, desc, FILE_TEXT_OFFSET_V1_5); + if (ret) + goto err; + + fprintf(stdout, "Firmware completing manifest v1.5\n"); + + /* create structures from end of file to start of file */ + ri_css_v1_5_hdr_create(image); + + fprintf(stdout, "Firmware file size 0x%x page count %d\n", + FILE_TEXT_OFFSET_V1_5 - MAN_DESC_OFFSET_V1_5 + image->image_end, + desc->header.preload_page_count); + + /* calculate hash for each module */ + man_hash_modules(image, desc); + + /* sign manifest */ + ret = ri_manifest_sign_v1_5(image); + if (ret < 0) + goto err; + + /* write the firmware */ + ret = man_write_fw_mod(image); + if (ret < 0) + goto err; + + /* write the unsigned files*/ + ret = man_write_unsigned_mod(image, MAN_META_EXT_OFFSET_V1_5, + MAN_FW_DESC_OFFSET_V1_5, + sizeof(struct sof_man_adsp_meta_file_ext_v1_8)); + if (ret < 0) + goto err; + + fprintf(stdout, "Firmware manifest and signing completed !\n"); + return 0; + +err: + free(image->rom_image); + free(image->fw_image); + unlink(image->out_file); + unlink(image->out_rom_file); + return ret; +} + +/* used by others */ +int man_write_fw_v1_5_sue(struct image *image) +{ + struct fw_image_manifest_v1_5_sue *m; + uint32_t preload_size; + int ret; + + /* init image */ + ret = man_init_image_v1_5_sue(image); + if (ret < 0) + goto err; + + /* create the manifest */ + ret = man_open_manifest_file(image); + if (ret < 0) + goto err; + + /* create the module */ + m = image->fw_image + MAN_DESC_OFFSET_V1_5_SUE; + + /* firmware and build version */ + m->desc.header.major_version = image->fw_ver_major; + m->desc.header.minor_version = image->fw_ver_minor; + m->desc.header.hotfix_version = image->fw_ver_micro; + m->desc.header.build_version = image->fw_ver_build; + + /* create each module - subtract the boot loader exec header */ + m->desc.header.num_module_entries = image->num_modules - 1; + ret = man_create_modules(image, &m->desc, FILE_TEXT_OFFSET_V1_5_SUE); + if (ret) + goto err; + + fprintf(stdout, "Firmware completing manifest v1.5\n"); + + /* write preload page count */ + preload_size = image->image_end - MAN_DESC_OFFSET_V1_5_SUE; + preload_size += MAN_PAGE_SIZE - (preload_size % MAN_PAGE_SIZE); + m->desc.header.preload_page_count = preload_size / MAN_PAGE_SIZE; + + fprintf(stdout, "Firmware file size 0x%x page count %d\n", + FILE_TEXT_OFFSET_V1_5_SUE - MAN_DESC_OFFSET_V1_5_SUE + + image->image_end, m->desc.header.preload_page_count); + + /* calculate hash for each module */ + man_hash_modules(image, &m->desc); + + /* write the firmware */ + ret = man_write_fw_mod(image); + if (ret < 0) + goto err; + + fprintf(stdout, "Firmware manifest and signing completed !\n"); + return 0; + +err: + free(image->fw_image); + unlink(image->out_file); + return ret; +} + +/* used by others */ +int man_write_fw_v1_8(struct image *image) +{ + struct sof_man_fw_desc *desc; + struct fw_image_manifest_v1_8 *m; + int ret; + + /* init image */ + ret = man_init_image_v1_8(image); + if (ret < 0) + goto err; + + /* open ROM image */ + ret = man_open_rom_file(image); + if (ret < 0) + goto err; + + /* open unsigned firmware */ + ret = man_open_unsigned_file(image); + if (ret < 0) + goto err; + + /* create the manifest */ + ret = man_open_manifest_file(image); + if (ret < 0) + goto err; + + /* create the module */ + m = image->fw_image; + desc = image->fw_image + MAN_DESC_OFFSET_V1_8; + + /* firmware and build version */ + m->css.version.major_version = image->fw_ver_major; + m->css.version.minor_version = image->fw_ver_minor; + m->css.version.build_version = image->fw_ver_build; + m->desc.header.major_version = image->fw_ver_major; + m->desc.header.minor_version = image->fw_ver_minor; + m->desc.header.hotfix_version = image->fw_ver_micro; + m->desc.header.build_version = image->fw_ver_build; + + /* create each module */ + m->desc.header.num_module_entries = image->num_modules; + ret = man_create_modules(image, desc, FILE_TEXT_OFFSET_V1_8); + if (ret) + goto err; + + fprintf(stdout, "Firmware completing manifest v1.8\n"); + + /* create structures from end of file to start of file */ + ri_adsp_meta_data_create_v1_8(image, MAN_META_EXT_OFFSET_V1_8, + MAN_FW_DESC_OFFSET_V1_8); + ri_plat_ext_data_create(image); + ri_css_v1_8_hdr_create(image); + ri_cse_create(image); + + fprintf(stdout, "Firmware file size 0x%x page count %d\n", + FILE_TEXT_OFFSET_V1_8 - MAN_DESC_OFFSET_V1_8 + image->image_end, + desc->header.preload_page_count); + + /* calculate hash for each module */ + man_hash_modules(image, desc); + + /* calculate hash for ADSP meta data extension - 0x480 to end */ + /* image_end is updated every time a section is added */ + assert(image->image_end > MAN_FW_DESC_OFFSET_V1_8); + ret = hash_sha256(image->fw_image + MAN_FW_DESC_OFFSET_V1_8, + image->image_end - MAN_FW_DESC_OFFSET_V1_8, + m->adsp_file_ext.comp_desc[0].hash, + sizeof(m->adsp_file_ext.comp_desc[0].hash)); + if (ret) + goto err; + + /* calculate hash for platform auth data - repeated in hash 2 and 4 */ + assert(image->image_end > (MAN_FW_DESC_OFFSET_V1_8 + + sizeof(struct sof_man_adsp_meta_file_ext_v1_8))); + + ret = hash_sha256(image->fw_image + MAN_FW_DESC_OFFSET_V1_8, + image->image_end - MAN_FW_DESC_OFFSET_V1_8, + m->signed_pkg.module[0].hash, + sizeof(m->signed_pkg.module[0].hash)); + if (ret) + goto err; + + /* hash values in reverse order */ + bytes_swap(m->signed_pkg.module[0].hash, sizeof(m->signed_pkg.module[0].hash)); + + /* Copy module hash to partition_info */ + assert(sizeof(m->partition_info.module[0].hash) == sizeof(m->signed_pkg.module[0].hash)); + memcpy(m->partition_info.module[0].hash, m->signed_pkg.module[0].hash, + sizeof(m->partition_info.module[0].hash)); + + /* sign manifest */ + ret = ri_manifest_sign_v1_8(image); + if (ret < 0) + goto err; + + /* write the firmware */ + ret = man_write_fw_mod(image); + if (ret < 0) + goto err; + + /* write the unsigned files*/ + ret = man_write_unsigned_mod(image, MAN_META_EXT_OFFSET_V1_8, + MAN_FW_DESC_OFFSET_V1_8, + sizeof(struct sof_man_adsp_meta_file_ext_v1_8)); + if (ret < 0) + goto err; + + fprintf(stdout, "Firmware manifest and signing completed !\n"); + return 0; + +err: + free(image->rom_image); + free(image->fw_image); + unlink(image->out_file); + unlink(image->out_rom_file); + return ret; +} + +/* used to sign with MEU */ +int man_write_fw_meu_v1_5(struct image *image) +{ + const int meta_start_offset = image->meu_offset - + sizeof(struct sof_man_adsp_meta_file_ext_v1_8) - MAN_EXT_PADDING; + struct sof_man_adsp_meta_file_ext_v1_8 *meta; + struct sof_man_fw_desc *desc; + uint32_t preload_size; + int ret; + + /* allocate image */ + image->fw_image = calloc(image->adsp->image_size, 1); + if (!image->fw_image) { + ret = -ENOMEM; + goto err; + } + + /* open unsigned firmware */ + ret = man_open_unsigned_file(image); + if (ret < 0) + goto err; + + /* create the manifest */ + ret = man_open_manifest_file(image); + if (ret < 0) + goto err; + + /* create the module */ + meta = image->fw_image + meta_start_offset; + desc = image->fw_image + MAN_DESC_OFFSET_V1_5; + + /* copy data */ + memcpy(desc, &image->adsp->man_v1_5->desc, + sizeof(struct sof_man_fw_desc)); + + /* firmware and build version */ + desc->header.major_version = image->fw_ver_major; + desc->header.minor_version = image->fw_ver_minor; + desc->header.hotfix_version = image->fw_ver_micro; + desc->header.build_version = image->fw_ver_build; + + /* create each module */ + desc->header.num_module_entries = image->num_modules; + ret = man_create_modules(image, desc, FILE_TEXT_OFFSET_V1_5); + if (ret) + goto err; + + fprintf(stdout, "Firmware completing manifest v1.5\n"); + + /* create structures from end of file to start of file */ + ri_adsp_meta_data_create_v1_8(image, meta_start_offset, + image->meu_offset); + + /* write preload page count */ + preload_size = meta->comp_desc[0].limit_offset - MAN_DESC_OFFSET_V1_5; + preload_size += MAN_PAGE_SIZE - (preload_size % MAN_PAGE_SIZE); + desc->header.preload_page_count = preload_size / MAN_PAGE_SIZE; + + /* calculate hash for each module */ + man_hash_modules(image, desc); + + /* calculate hash for ADSP meta data extension */ + assert(image->meu_offset < image->image_end); + ret = hash_sha256(image->fw_image + image->meu_offset, image->image_end - image->meu_offset, + meta->comp_desc[0].hash, sizeof(meta->comp_desc[0].hash)); + if (ret) + goto err; + + /* write the unsigned files */ + ret = man_write_unsigned_mod(image, meta_start_offset, + image->meu_offset, + sizeof(struct sof_man_adsp_meta_file_ext_v1_8)); + if (ret < 0) + goto err; + + fprintf(stdout, "Firmware manifest completed!\n"); + return 0; + +err: + free(image->fw_image); + unlink(image->out_file); + return ret; +} + +/* used to sign with MEU */ +int man_write_fw_meu_v1_8(struct image *image) +{ + const int meta_start_offset = image->meu_offset - + sizeof(struct sof_man_adsp_meta_file_ext_v1_8) - MAN_EXT_PADDING; + struct sof_man_adsp_meta_file_ext_v1_8 *meta; + struct sof_man_fw_desc *desc; + uint32_t preload_size; + int ret; + + /* allocate image */ + image->fw_image = calloc(image->adsp->image_size, 1); + if (!image->fw_image) { + ret = -ENOMEM; + goto err; + } + + /* open unsigned firmware */ + ret = man_open_unsigned_file(image); + if (ret < 0) + goto err; + + /* create the manifest */ + ret = man_open_manifest_file(image); + if (ret < 0) + goto err; + + /* create the module */ + meta = image->fw_image + meta_start_offset; + desc = image->fw_image + MAN_DESC_OFFSET_V1_8; + + /* copy data */ + memcpy(meta, &image->adsp->man_v1_8->adsp_file_ext, + sizeof(struct sof_man_adsp_meta_file_ext_v1_8)); + memcpy(desc, &image->adsp->man_v1_8->desc, + sizeof(struct sof_man_fw_desc)); + + /* firmware and build version */ + desc->header.major_version = image->fw_ver_major; + desc->header.minor_version = image->fw_ver_minor; + desc->header.hotfix_version = image->fw_ver_micro; + desc->header.build_version = image->fw_ver_build; + + /* create each module */ + desc->header.num_module_entries = image->num_modules; + ret = man_create_modules(image, desc, FILE_TEXT_OFFSET_V1_8); + if (ret) + goto err; + + fprintf(stdout, "Firmware completing manifest v1.8\n"); + + /* create structures from end of file to start of file */ + ri_adsp_meta_data_create_v1_8(image, meta_start_offset, + image->meu_offset); + + /* write preload page count */ + preload_size = meta->comp_desc[0].limit_offset - MAN_DESC_OFFSET_V1_8; + preload_size += MAN_PAGE_SIZE - (preload_size % MAN_PAGE_SIZE); + desc->header.preload_page_count = preload_size / MAN_PAGE_SIZE; + + /* calculate hash for each module */ + man_hash_modules(image, desc); + + /* calculate hash for ADSP meta data extension */ + assert(image->meu_offset < image->image_end); + ret = hash_sha256(image->fw_image + image->meu_offset, image->image_end - image->meu_offset, + meta->comp_desc[0].hash, sizeof(meta->comp_desc[0].hash)); + if (ret) + goto err; + + /* write the unsigned files */ + ret = man_write_unsigned_mod(image, meta_start_offset, + image->meu_offset, + sizeof(struct sof_man_adsp_meta_file_ext_v1_8)); + if (ret < 0) + goto err; + + fprintf(stdout, "Firmware manifest completed!\n"); + return 0; + +err: + free(image->fw_image); + unlink(image->out_file); + return ret; +} + +/* used to sign with MEU */ +int man_write_fw_meu_v2_5(struct image *image) +{ + const int meta_start_offset = image->meu_offset - + sizeof(struct sof_man_adsp_meta_file_ext_v2_5) - MAN_EXT_PADDING; + struct sof_man_adsp_meta_file_ext_v2_5 *meta; + struct sof_man_fw_desc *desc; + uint32_t preload_size; + int ret; + + /* allocate image */ + image->fw_image = calloc(image->adsp->image_size, 1); + if (!image->fw_image) { + ret = -ENOMEM; + goto err; + } + + /* open unsigned firmware */ + ret = man_open_unsigned_file(image); + if (ret < 0) + goto err; + + /* create the manifest */ + ret = man_open_manifest_file(image); + if (ret < 0) + goto err; + + /* create the module */ + meta = image->fw_image + meta_start_offset; + desc = image->fw_image + MAN_DESC_OFFSET_V1_8; + + /* copy data */ + memcpy(meta, &image->adsp->man_v2_5->adsp_file_ext, + sizeof(struct sof_man_adsp_meta_file_ext_v2_5)); + memcpy(desc, &image->adsp->man_v2_5->desc, + sizeof(struct sof_man_fw_desc)); + + /* firmware and build version */ + desc->header.major_version = image->fw_ver_major; + desc->header.minor_version = image->fw_ver_minor; + desc->header.hotfix_version = image->fw_ver_micro; + desc->header.build_version = image->fw_ver_build; + + /* create each module */ + desc->header.num_module_entries = image->num_modules; + ret = man_create_modules(image, desc, FILE_TEXT_OFFSET_V1_8); + if (ret) + goto err; + + /* platform config defines some modules except bringup & base modules */ + man_create_modules_in_config(image, desc); + + fprintf(stdout, "Firmware completing manifest v2.5\n"); + + /* create structures from end of file to start of file */ + ri_adsp_meta_data_create_v2_5(image, meta_start_offset, + image->meu_offset); + + /* write preload page count */ + preload_size = meta->comp_desc[0].limit_offset - MAN_DESC_OFFSET_V1_8; + preload_size += MAN_PAGE_SIZE - (preload_size % MAN_PAGE_SIZE); + desc->header.preload_page_count = preload_size / MAN_PAGE_SIZE; + + /* calculate hash for each module */ + man_hash_modules(image, desc); + + /* calculate hash for ADSP meta data extension */ + assert(image->meu_offset < image->image_end); + ret = hash_sha384(image->fw_image + image->meu_offset, image->image_end - image->meu_offset, + meta->comp_desc[0].hash, sizeof(meta->comp_desc[0].hash)); + if (ret) + goto err; + + /* write the unsigned files */ + ret = man_write_unsigned_mod(image, meta_start_offset, + image->meu_offset, + sizeof(struct sof_man_adsp_meta_file_ext_v2_5)); + if (ret < 0) + goto err; + + fprintf(stdout, "Firmware manifest completed!\n"); + return 0; + +err: + free(image->fw_image); + unlink(image->out_file); + return ret; +} + +/* used by others */ +int man_write_fw_v2_5(struct image *image) +{ + struct sof_man_fw_desc *desc; + struct fw_image_manifest_v2_5 *m; + int ret; + + /* init image */ + ret = man_init_image_v2_5(image); + if (ret < 0) + goto err; + + /* use default meu offset for TGL if not provided */ + if (!image->meu_offset) + image->meu_offset = MAN_FW_DESC_OFFSET_V2_5 - 0x10; + + /* open ROM image */ + ret = man_open_rom_file(image); + if (ret < 0) + goto err; + + /* open unsigned firmware */ + ret = man_open_unsigned_file(image); + if (ret < 0) + goto err; + + /* create the manifest */ + ret = man_open_manifest_file(image); + if (ret < 0) + goto err; + + /* create the module */ + m = image->fw_image; + desc = image->fw_image + MAN_DESC_OFFSET_V1_8; + + /* firmware and build version */ + m->css.version.major_version = image->fw_ver_major; + m->css.version.minor_version = image->fw_ver_minor; + m->css.version.build_version = image->fw_ver_build; + m->desc.header.major_version = image->fw_ver_major; + m->desc.header.minor_version = image->fw_ver_minor; + m->desc.header.hotfix_version = image->fw_ver_micro; + m->desc.header.build_version = image->fw_ver_build; + + /* create each module */ + m->desc.header.num_module_entries = image->num_modules; + ret = man_create_modules(image, desc, FILE_TEXT_OFFSET_V1_8); + if (ret) + goto err; + + /* platform config defines some modules except bringup & base modules */ + man_create_modules_in_config(image, desc); + + fprintf(stdout, "Firmware completing manifest v2.5\n"); + + /* create structures from end of file to start of file */ + ri_adsp_meta_data_create_v2_5(image, MAN_META_EXT_OFFSET_V2_5, + image->meu_offset); + ri_plat_ext_data_create_v2_5(image); + ri_css_v2_5_hdr_create(image); + ri_cse_create_v2_5(image); + + fprintf(stdout, "Firmware file size 0x%x page count %d\n", + FILE_TEXT_OFFSET_V1_8 - MAN_DESC_OFFSET_V1_8 + image->image_end, + desc->header.preload_page_count); + + /* calculate hash for each module */ + man_hash_modules(image, desc); + + /* calculate hash inside ADSP meta data extension for padding to end */ + assert(image->meu_offset < image->image_end); + ret = hash_sha384(image->fw_image + image->meu_offset, image->image_end - image->meu_offset, + m->adsp_file_ext.comp_desc[0].hash, + sizeof(m->adsp_file_ext.comp_desc[0].hash)); + if (ret) + goto err; + + /* mue writes 0xff to 16 bytes of padding */ + memset(m->reserved, 0xff, 16); + + /* calculate hash inside ext info 16 of sof_man_adsp_meta_file_ext_v2_5 */ + assert((MAN_META_EXT_OFFSET_V2_5 + sizeof(struct sof_man_adsp_meta_file_ext_v2_5)) < + image->image_end); + + ret = hash_sha384(image->fw_image + MAN_META_EXT_OFFSET_V2_5, + sizeof(struct sof_man_adsp_meta_file_ext_v2_5), + m->signed_pkg.module[0].hash, sizeof(m->signed_pkg.module[0].hash)); + if (ret) + goto err; + + /* hash values in reverse order */ + bytes_swap(m->signed_pkg.module[0].hash, sizeof(m->signed_pkg.module[0].hash)); + + /* sign manifest */ + ret = ri_manifest_sign_v2_5(image); + if (ret < 0) + goto err; + +#if 0 + /* calculate hash - SHA384 on CAVS2_5+ */ + module_sha384_create(image); + module_sha_update(image, image->fw_image, + sizeof(struct CsePartitionDirHeader_v2_5) + + sizeof(struct CsePartitionDirEntry) * 3); + module_sha_update(image, image->fw_image + 0x4c0, image->image_end - 0x4c0); + module_sha_complete(image, hash); + + /* hash values in reverse order */ + for (i = 0; i < SOF_MAN_MOD_SHA384_LEN; i++) { + m->info_0x16.hash[i] = + hash[SOF_MAN_MOD_SHA384_LEN - 1 - i]; + } +#endif + /* write the firmware */ + ret = man_write_fw_mod(image); + if (ret < 0) + goto err; + + /* write the unsigned files*/ + ret = man_write_unsigned_mod(image, MAN_META_EXT_OFFSET_V2_5, + MAN_FW_DESC_OFFSET_V2_5, + sizeof(struct sof_man_adsp_meta_file_ext_v2_5)); + if (ret < 0) + goto err; + + fprintf(stdout, "Firmware manifest and signing completed !\n"); + return 0; + +err: + free(image->rom_image); + free(image->fw_image); + unlink(image->out_file); + unlink(image->out_rom_file); + return ret; +} + +static int man_init_image_ace_v1_5(struct image *image) +{ + /* allocate image and copy template manifest */ + image->fw_image = calloc(image->adsp->image_size, 1); + if (!image->fw_image) + return -ENOMEM; + + memcpy(image->fw_image, image->adsp->man_ace_v1_5, + sizeof(struct fw_image_manifest_ace_v1_5)); + + return 0; +} + +int man_write_fw_ace_v1_5(struct image *image) +{ + struct hash_context hash; + struct sof_man_fw_desc *desc; + struct fw_image_manifest_ace_v1_5 *m; + int ret; + + /* init image */ + ret = man_init_image_ace_v1_5(image); + if (ret < 0) + goto err; + + /* use default meu offset for TGL if not provided */ + if (!image->meu_offset) + image->meu_offset = MAN_FW_DESC_OFFSET_ACE_V1_5 - 0x10; + + /* open ROM image */ + ret = man_open_rom_file(image); + if (ret < 0) + goto err; + + /* open unsigned firmware */ + ret = man_open_unsigned_file(image); + if (ret < 0) + goto err; + + /* create the manifest */ + ret = man_open_manifest_file(image); + if (ret < 0) + goto err; + + /* create the module */ + m = image->fw_image; + desc = image->fw_image + MAN_DESC_OFFSET_V1_8; + + /* firmware and build version */ + m->css.version.major_version = image->fw_ver_major; + m->css.version.minor_version = image->fw_ver_minor; + m->css.version.build_version = image->fw_ver_build; + m->desc.header.major_version = image->fw_ver_major; + m->desc.header.minor_version = image->fw_ver_minor; + m->desc.header.hotfix_version = image->fw_ver_micro; + m->desc.header.build_version = image->fw_ver_build; + + m->desc.header.feature_mask = 0x2; // -> should be feature mask - to fix + m->desc.header.fw_image_flags = 0x2; // -> should be feature mask - to fix + m->desc.header.fw_compat = 0x100000; // -> PUT PROPER STRUCT + + /* create each module */ + m->desc.header.num_module_entries = image->num_modules; + ret = man_create_modules(image, desc, FILE_TEXT_OFFSET_V1_8); + if (ret) + goto err; + + /* platform config defines some modules except bringup & base modules */ + man_create_modules_in_config(image, desc); + + fprintf(stdout, "Firmware completing manifest v2.5\n"); + + /* create structures from end of file to start of file */ + ri_adsp_meta_data_create_v2_5(image, MAN_META_EXT_OFFSET_ACE_V1_5, + image->meu_offset); + ri_plat_ext_data_create_ace_v1_5(image); + ri_css_v2_5_hdr_create(image); + ri_cse_create_ace_v1_5(image); + + fprintf(stdout, "Firmware file size 0x%x page count %d\n", + FILE_TEXT_OFFSET_V1_8 - MAN_DESC_OFFSET_V1_8 + image->image_end, + desc->header.preload_page_count); + + /* calculate hash for each module */ + man_hash_modules(image, desc); + + /* calculate hash inside ADSP meta data extension for padding to end */ + assert(image->meu_offset < image->image_end); + ret = hash_sha384(image->fw_image + image->meu_offset, image->image_end - image->meu_offset, + m->adsp_file_ext.comp_desc[0].hash, + sizeof(m->adsp_file_ext.comp_desc[0].hash)); + if (ret) + goto err; + + /* mue writes 0xff to 16 bytes of padding */ + memset(m->reserved, 0xff, 16); + + /* calculate hash inside ext info 16 of sof_man_adsp_meta_file_ext_v2_5 */ + assert((MAN_META_EXT_OFFSET_ACE_V1_5 + sizeof(struct sof_man_adsp_meta_file_ext_v2_5)) < + image->image_end); + + ret = hash_sha384(image->fw_image + MAN_META_EXT_OFFSET_ACE_V1_5, + sizeof(struct sof_man_adsp_meta_file_ext_v2_5), + m->signed_pkg.module[0].hash, sizeof(m->signed_pkg.module[0].hash)); + if (ret) + goto err; + + /* hash values in reverse order */ + bytes_swap(m->signed_pkg.module[0].hash, sizeof(m->signed_pkg.module[0].hash)); + + /* calculate hash - SHA384 on CAVS2_5+ */ + hash_sha384_init(&hash); + hash_update(&hash, image->fw_image, + sizeof(struct CsePartitionDirHeader_v2_5) + + sizeof(struct CsePartitionDirEntry) * 3); + + hash_update(&hash, image->fw_image + 0x4c0, image->image_end - 0x4c0); + hash_finalize(&hash); + + /* hash values in reverse order */ + ret = hash_get_digest(&hash, m->info_0x16.hash, sizeof(m->info_0x16.hash)); + if (ret < 0) + goto err; + bytes_swap(m->info_0x16.hash, sizeof(m->info_0x16.hash)); + + /* sign manifest */ + ret = ri_manifest_sign_ace_v1_5(image); + if (ret < 0) + goto err; + + /* write the firmware */ + ret = man_write_fw_mod(image); + if (ret < 0) + goto err; + + /* write the unsigned files*/ + ret = man_write_unsigned_mod(image, MAN_META_EXT_OFFSET_ACE_V1_5, + MAN_FW_DESC_OFFSET_ACE_V1_5, + sizeof(struct sof_man_adsp_meta_file_ext_v2_5)); + if (ret < 0) + goto err; + + fprintf(stdout, "Firmware manifest and signing completed !\n"); + return 0; + +err: + free(image->rom_image); + free(image->fw_image); + unlink(image->out_file); + unlink(image->out_rom_file); + return ret; +} + +int verify_image(struct image *image) +{ + FILE *in_file; + int ret; + void *buffer; + size_t size, read, i; + + /* is verify supported for target ? */ + if (!image->adsp->verify_firmware) { + fprintf(stderr, "error: verify not supported for target\n"); + return -EINVAL; + } + + /* open image for reading */ + in_file = fopen(image->verify_file, "rb"); + if (!in_file) + return file_error("unable to open file for reading", image->verify_file); + + /* get file size */ + ret = get_file_size(in_file, image->verify_file, &size); + if (ret < 0) { + goto out; + } + + /* allocate buffer for parsing */ + buffer = malloc(size); + if (!buffer) { + ret = -ENOMEM; + goto out; + } + + /* find start of fw image and verify */ + read = fread(buffer, 1, size, in_file); + if (read != size) { + ret = file_error("unable to read whole file", image->verify_file); + goto out; + } + for (i = 0; i < size; i += sizeof(uint32_t)) { + /* find CSE header marker "$CPD" */ + if (*(uint32_t *)(buffer + i) == CSE_HEADER_MAKER) { + image->fw_image = buffer + i; + ret = image->adsp->verify_firmware(image); + goto out; + } + } + + /* no header found */ + fprintf(stderr, "error: could not find valid CSE header $CPD in %s\n", + image->verify_file); +out: + fclose(in_file); + return 0; +} + + +int resign_image(struct image *image) +{ + int key_size, key_file_size; + void *buffer = NULL; + size_t size, read; + FILE *in_file; + int ret, i; + + /* open image for reading */ + in_file = fopen(image->in_file, "rb"); + if (!in_file) + return file_error("unable to open file for reading", image->in_file); + + /* get file size */ + ret = get_file_size(in_file, image->in_file, &size); + if (ret < 0) { + goto out; + } + + /* allocate buffer for parsing */ + buffer = malloc(size); + if (!buffer) { + ret = -ENOMEM; + goto out; + } + + /* read file into buffer */ + read = fread(buffer, 1, size, in_file); + if (read != size) { + ret = file_error("unable to read whole file", image->in_file); + goto out; + } + + fclose(in_file); + + for (i = 0; i < size; i += sizeof(uint32_t)) { + /* find CSE header marker "$CPD" */ + if (*(uint32_t *)(buffer + i) == CSE_HEADER_MAKER) { + image->fw_image = buffer + i; + break; + } + } + + if (i >= size) { + fprintf(stderr, "error: didn't found header marker %d\n", i); + ret = -EINVAL; + goto out; + } + + image->image_end = size; + + /* check that key size matches */ + if (image->adsp->man_v2_5) { + key_size = 384; + } else { + key_size = 256; + } + + key_file_size = get_key_size(image); + + if (key_file_size > key_size) { + fprintf(stderr, "error: key size %d is longer than original key %d\n", + key_file_size, key_size); + ret = -EINVAL; + goto out; + } + + /* resign */ + if (image->adsp->man_v1_5) + ret = ri_manifest_sign_v1_5(image); + else if (image->adsp->man_v1_8) + ret = ri_manifest_sign_v1_8(image); + else if (image->adsp->man_v2_5) + ret = ri_manifest_sign_v2_5(image); + else + ret = -EINVAL; + + if (ret < 0) { + fprintf(stderr, "error: unable to sign image\n"); + goto out; + } + + /* open outfile for writing */ + unlink(image->out_file); + image->out_fd = fopen(image->out_file, "wb"); + if (!image->out_fd) { + ret = file_error("unable to open file for writting", image->out_file); + goto out; + } + + man_write_fw_mod(image); + +out: + free(buffer); + return ret; +} diff --git a/tools/rimage/src/misc_utils.c b/tools/rimage/src/misc_utils.c new file mode 100644 index 000000000000..2c0146f5bdd9 --- /dev/null +++ b/tools/rimage/src/misc_utils.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright(c) 2018-2023 Intel Corporation. All rights reserved. + * + * Author: Adrian Warecki <adrian.warecki@intel.com> + */ + +#include <stdio.h> +#include <rimage/misc_utils.h> + +void bytes_swap(uint8_t *ptr, uint32_t size) +{ + uint8_t tmp; + uint32_t index; + + for (index = 0; index < (size / 2); index++) { + tmp = ptr[index]; + ptr[index] = ptr[size - 1 - index]; + ptr[size - 1 - index] = tmp; + } +} + +void print_enum(unsigned long value, const struct name_val *values) +{ + while (values->name) { + if (values->value == value) { + fprintf(stdout, "%s\n", values->name); + return; + } + + values++; + } + + printf("Unknown: 0x%lx\n", value); +} + +void print_flags(unsigned long value, const struct name_val *flags) +{ + while (flags->name) { + if (value & flags->value) { + fprintf(stdout, "%s ", flags->name); + value &= ~flags->value; + } + + flags++; + } + + if (value) + fprintf(stdout, "+ 0x%lx", value); + printf("\n"); +} diff --git a/tools/rimage/src/module.c b/tools/rimage/src/module.c new file mode 100644 index 000000000000..b150e246ca8c --- /dev/null +++ b/tools/rimage/src/module.c @@ -0,0 +1,509 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + * Author: Adrian Warecki <adrian.warecki@intel.com> + */ + +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <assert.h> + +#include <rimage/module.h> +#include <rimage/elf_file.h> +#include <rimage/file_utils.h> +#include <rimage/rimage.h> + + +int module_read_section(const struct module *module, const struct module_section *section, + void *buffer, const size_t size) +{ + return elf_section_read_content(&module->elf, section->header, buffer, size); +} + +int module_write_section(const struct module *module, const struct module_section *section, + const int padding, FILE *out_file, const char *filename) +{ + int ret; + struct elf_section section_data; + size_t count; + char padding_buf[4]; + + ret = elf_section_read(&module->elf, section->header, §ion_data); + if (ret) + return ret; + + /* write out section data */ + count = fwrite(section_data.data, section->size, 1, out_file); + if (count != 1) { + ret = file_error("cant write section", filename); + goto out; + } + + /* write padding data */ + if (padding) { + assert(padding <= sizeof(padding_buf)); + + memset(padding_buf, 0, padding); + count = fwrite(padding_buf, padding, 1, out_file); + if (count != 1) { + ret = file_error("cant write padding", filename); + goto out; + } + } + +out: + elf_section_free(§ion_data); + return ret; +} + +int module_read_whole_elf(const struct module *module, void *buffer, size_t size) +{ + int ret; + size_t count; + + if (module->elf.file_size > size) { + fprintf(stderr, "error: Output buffer too small.\n"); + return -ENOSPC; + } + + /* read in file data */ + ret = fseek(module->elf.file, 0, SEEK_SET); + if (ret) + return file_error("can't seek set", module->elf.filename); + + count = fread(buffer, module->elf.file_size, 1, module->elf.file); + if (count != 1) + return file_error("can't read data", module->elf.filename); + + return ret; +} + +int module_write_whole_elf(const struct module *module, FILE *out_file, const char *filename) +{ + int ret; + char *buffer; + size_t count; + + /* alloc data data */ + buffer = calloc(1, module->elf.file_size); + if (!buffer) + return -ENOMEM; + + ret = module_read_whole_elf(module, buffer, module->elf.file_size); + if (ret) + goto out; + + /* write out section data */ + count = fwrite(buffer, module->elf.file_size, 1, out_file); + if (count != 1) { + ret = file_error("can't write data", "");// TODO: image->out_file); + goto out; + } + +out: + free(buffer); + return ret; +} + +void module_print_zones(const struct module *module) +{ + fprintf(stdout, "\n\tTotals\tStart\t\tEnd\t\tSize"); + + fprintf(stdout, "\n\tTEXT\t0x%8.8x\t0x%8.8x\t0x%x\n", + module->text.start, module->text.end, + module->text.end - module->text.start); + fprintf(stdout, "\tDATA\t0x%8.8x\t0x%8.8x\t0x%x\n", + module->data.start, module->data.end, + module->data.end - module->data.start); + fprintf(stdout, "\tBSS\t0x%8.8x\t0x%8.8x\t0x%x\n\n", + module->bss.start, module->bss.end, + module->bss.end - module->bss.start); +} + +/** + * Print a list of valid program headers + * + * @param module pointer to a module structure + */ +static void module_print_programs(const struct module *module) +{ + const Elf32_Phdr *header; + int i; + + /* check each program */ + for (i = 0; i < module->elf.header.phnum; i++) { + header = &module->elf.programs[i]; + + if (header->filesz == 0 || header->type != PT_LOAD) + continue; + + fprintf(stdout, "%s program-%d:\n", module->elf.filename, i); + elf_program_header_print(header); + } +} + +/** + * Goes through program headers array to find the physical address based on the virtual address. + * + * @param elf elf file structure + * @param vaddr virtual address + * @return physical address when success, virtual address on error + */ +static uint32_t find_physical_address(struct elf_file *file, size_t vaddr) +{ + uint16_t i; + const Elf32_Phdr *prog; + + for (i = 0; i < file->programs_count; i++) { + prog = &file->programs[i]; + + if (prog->type != PT_LOAD) + continue; + + if (vaddr >= prog->vaddr && vaddr < (prog->vaddr + file->programs[i].memsz)) + return file->programs[i].paddr + vaddr - prog->vaddr; + } + + return vaddr; +} + +unsigned long uncache_to_cache(const struct memory_alias *alias, unsigned long address) +{ + return (address & ~alias->mask) | alias->cached; +} + +/** + * Checks if the section is placed in the rom memory address space + * + * @param config Memory configuration structure + * @param section section to be checked + * @return true if section is placed in rom memory address space + */ +static bool section_is_rom(const struct memory_config *config, + const struct elf_section_header *section) +{ + uint32_t sect_start, sect_end; + uint32_t rom_start, rom_end; + + sect_start = section->data.vaddr; + sect_end = sect_start + section->data.size; + + rom_start = config->zones[SOF_FW_BLK_TYPE_ROM].base; + rom_end = rom_start + config->zones[SOF_FW_BLK_TYPE_ROM].size; + + if (sect_end <= rom_start || sect_start >= rom_end) + return false; + if (sect_start >= rom_start && sect_end <= rom_end) + return true; + + fprintf(stderr, "Warning! Section %s partially overlaps with rom memory.\n", section->name); + return false; +} + +/** + * Initialize module_sections_info structure + * + * @param info Pointer to a module_sections_info structure + */ +static void sections_info_init(struct module_sections_info *info) +{ + memset(info, 0, sizeof(*info)); + + info->start = UINT32_MAX; +} + +/** + * Adds section to module_sections_info structure + * + * @param info Pointer to a module_sections_info structure + * @param section module_section structure + */ +static void sections_info_add(struct module_sections_info *info, struct module_section *section) +{ + const uint32_t end = section->load_address + section->size; + + if (section->load_address < info->start) + info->start = section->load_address; + + if (end > info->end) + info->end = end; + + info->size += section->size; + info->count++; + + /* Add section to list */ + section->next_section = NULL; + + if (info->last_section) + info->last_section->next_section = section; + + info->last_section = section; + + if (!info->first_section) + info->first_section = section; +} + +/** + * Calculates file size after adding all sections + * + * @param info Pointer to a module_sections_info structure + */ +static void sections_info_finalize(struct module_sections_info *info) +{ + info->file_size = info->end - info->start; + + /* file sizes round up to nearest page */ + info->file_size = (info->file_size + MAN_PAGE_SIZE - 1) & ~(MAN_PAGE_SIZE - 1); +} + +/** + * Checks the section header (type and flags) to determine the section type. + * + * @param section section header + * @return enum module_section_type + */ +static enum module_section_type get_section_type(const struct elf_section_header *section) +{ + switch (section->data.type) { + case SHT_INIT_ARRAY: + /* fall through */ + case SHT_PROGBITS: + /* text or data */ + return (section->data.flags & SHF_EXECINSTR) ? MST_TEXT : MST_DATA; + + case SHT_NOBITS: + /* bss or heap */ + return MST_BSS; + + case SHT_NOTE: + return MST_NOTE; + + default: + return MST_UNKNOWN; + } +} + +void module_parse_sections(struct module *module, const struct memory_config *mem_cfg, bool verbose) +{ + const uint32_t valid = (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR); + uint16_t i; + + struct module_section *out_section = module->sections; + + fprintf(stdout, " Found %d sections, listing valid sections...\n", + module->elf.sections_count); + + fprintf(stdout, "\tNo\tLMA\t\tVMA\t\tEnd\t\tSize\tType\tName\n"); + + /* parse each section */ + for (i = 0; i < module->elf.sections_count; i++) { + const struct elf_section_header *sect = &module->elf.sections[i]; + struct module_sections_info *info = NULL; + + /* only write valid sections */ + if (!(sect->data.flags & valid)) + continue; + + /* Comment from fix_elf_addrs.py: + * The sof-derived linker scripts currently emit some zero-length sections + * at address zero. This is benign, and the linker is happy + * + * So we gleefully skip them. */ + if (sect->data.size == 0) + continue; + + out_section->header = sect; + out_section->size = sect->data.size; + out_section->type = get_section_type(sect); + out_section->rom = section_is_rom(mem_cfg, sect); + out_section->address = sect->data.vaddr; + out_section->load_address = find_physical_address(&module->elf, sect->data.vaddr); + + /* Don't convert ROM addresses, ROM sections aren't included in the output image */ + if (!out_section->rom) { + /* Walk the sections in the ELF file, changing the VMA/LMA of each uncached section + * to the equivalent address in the cached area of memory. */ + out_section->address = uncache_to_cache(&mem_cfg->alias, + out_section->address); + out_section->load_address = uncache_to_cache(&mem_cfg->alias, + out_section->load_address); + } + + fprintf(stdout, "\t%d\t0x%8.8x\t0x%8.8x\t0x%8.8zx\t0x%zx", i, + out_section->load_address, out_section->address, + out_section->address + out_section->size, out_section->size); + + + switch (out_section->type) { + case MST_DATA: + info = &module->data; + fprintf(stdout, "\tDATA"); + break; + + case MST_TEXT: + info = &module->text; + fprintf(stdout, "\tTEXT"); + break; + + case MST_BSS: + info = &module->bss; + fprintf(stdout, "\tBSS"); + break; + + case MST_NOTE: + fprintf(stdout, "\tNOTE"); + break; + + default: + break; + } + + if (out_section->rom) { + /* ROM sections aren't included in the output image */ + fprintf(stdout, " ROM"); + } else { + /* Add section to list */ + if (info) + sections_info_add(info, out_section); + } + + module->num_sections++; + out_section++; + + /* section name */ + fprintf(stdout, "\t%s\n", sect->name); + + if (verbose) { + fprintf(stdout, "%s section-%d:\n", module->elf.filename, i); + elf_section_header_print(sect); + } + } + + sections_info_finalize(&module->text); + sections_info_finalize(&module->data); + sections_info_finalize(&module->bss); + + size_t fw_size = module->data.size + module->text.size; + + fprintf(stdout, " module: input size %zd (0x%zx) bytes %d sections\n", + fw_size, fw_size, module->num_sections); + fprintf(stdout, " module: text %zu (0x%zx) bytes\n" + "\tdata %zu (0x%zx) bytes\n" + "\tbss %zu (0x%zx) bytes\n\n", + module->text.size, module->text.size, + module->data.size, module->data.size, + module->bss.size, module->bss.size); +} + +int module_open(struct module *module, const char *filename, const bool verbose) +{ + int ret; + + memset(module, 0, sizeof(*module)); + + ret = elf_open(&module->elf, filename); + if (ret) + return ret; + + if (verbose) { + fprintf(stdout, "%s elf header:\n", module->elf.filename); + elf_header_print(&module->elf); + module_print_programs(module); + } + + module->sections = calloc(module->elf.sections_count, sizeof(struct module_section)); + if (!module->sections) { + elf_free(&module->elf); + return -ENOMEM; + } + + sections_info_init(&module->data); + sections_info_init(&module->bss); + sections_info_init(&module->text); + + return 0; +} + +void module_close(struct module *module) +{ + elf_free(&module->elf); +} + +/** + * Checks if the contents of the section overlaps + * + * @param a first section to check + * @param b second section to check + * @return true if space of a sections overlap + */ +static bool section_check_overlap(const struct module_section *a, const struct module_section *b) +{ + uint32_t a_start = a->address; + uint32_t a_end = a_start + a->size; + + uint32_t b_start = b->address; + uint32_t b_end = b_start + b->size; + + /* is section start overlapping ? */ + return (a_start >= b_start && a_start < b_end) || + /* is section end overlapping ? */ + (a_end > b_start && a_end <= b_end); +} + +/** + * Checks if the contents of the modules overlaps + * + * @param mod first module to check + * @param mod2 second module to check + * @return error code + */ +static int module_check_overlap(const struct module *mod, const struct module *mod2) +{ + unsigned int i, j; + + /* for each section from first module */ + for (i = 0; i < mod->num_sections; i++) { + /* and for each section from second module */ + for (j = 0; j < mod2->num_sections; j++) { + const struct module_section *section = &mod->sections[i]; + const struct module_section *section2 = &mod2->sections[j]; + + /* don't compare section with itself */ + if (section == section2) + continue; + + /* check section overlapping */ + if (section_check_overlap(section, section2)) { + + fprintf(stderr, "error: Detected overlapping sections:\n"); + fprintf(stderr, "\t[0x%x : 0x%zx] %s from %s\n", section->address, + section->address + section->size - 1, + section->header->name, mod->elf.filename); + fprintf(stderr, "\t[0x%x : 0x%zx] %s from %s\n", section2->address, + section2->address + section2->size - 1, + section2->header->name, mod2->elf.filename); + + return -EINVAL; + } + } + } + + return 0; +} + +int modules_validate(const struct image *image) +{ + int i, j, ret; + + for (i = 0; i < image->num_modules; i++) { + for (j = 0; j < image->num_modules; j++) { + ret = module_check_overlap(&image->module[i].file, &image->module[j].file); + if (ret) + return ret; + } + } + + return 0; +} diff --git a/tools/rimage/src/pkcs1_5.c b/tools/rimage/src/pkcs1_5.c new file mode 100644 index 000000000000..de063ee03bec --- /dev/null +++ b/tools/rimage/src/pkcs1_5.c @@ -0,0 +1,970 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2017 Intel Corporation. All rights reserved. +// +// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> +// Keyon Jie <yang.jie@linux.intel.com> + +#include <openssl/pem.h> +#include <openssl/ssl.h> +#include <openssl/rsa.h> +#include <openssl/evp.h> +#include <openssl/bio.h> +#include <openssl/sha.h> +#include <openssl/objects.h> +#include <openssl/bn.h> +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include <openssl/core_names.h> +#endif +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include <rimage/rimage.h> +#include <rimage/css.h> +#include <rimage/manifest.h> +#include <rimage/misc_utils.h> +#include <rimage/file_utils.h> +#include <rimage/hash.h> + +#define DEBUG_PKCS 0 + +enum manver { + V15 = 0, + V18 = 1, + V25 = 2, + VACE15 = 3 +}; + +static int rimage_read_key(EVP_PKEY **privkey, struct image *image) +{ + char path[256]; + FILE *fp; + + /* requires private key */ + if (!image->key_name) { + fprintf(stderr, "error: no private key set \n"); + return -EINVAL; + } + + /* create new key */ + *privkey = EVP_PKEY_new(); + if (!(*privkey)) + return -ENOMEM; + + /* load in RSA private key from PEM file */ + memset(path, 0, sizeof(path)); + strncpy(path, image->key_name, sizeof(path) - 1); + + fprintf(stdout, " %s: read key '%s'\n", __func__, path); + fp = fopen(path, "rb"); + if (!fp) + return file_error("unable to open file for reading", path); + + PEM_read_PrivateKey(fp, privkey, NULL, NULL); + fclose(fp); + + return 0; +} + +/* + * Here we have different implementations of following functionality + * (based on different openssl versions): + * + * rimage_check_key + * + * rimage_set_modexp + * + * rimage_sign + * + * rimage_verify + * + * rimage_get_key_size + * +*/ + +#if OPENSSL_VERSION_NUMBER < 0x30000000L +static int rimage_check_key(EVP_PKEY *privkey) +{ + RSA *priv_rsa = NULL; + + priv_rsa = EVP_PKEY_get1_RSA(privkey); + + return RSA_check_key(priv_rsa); +} +#else +static int rimage_check_key(EVP_PKEY *privkey) +{ + EVP_PKEY_CTX *ctx; + int ret = 0; + + ctx = EVP_PKEY_CTX_new(privkey, NULL /* no engine */); + if (!ctx) + return -EINVAL; + + ret = EVP_PKEY_private_check(ctx); + + EVP_PKEY_CTX_free(ctx); + + return ret; +} +#endif + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static void rimage_set_modexp(EVP_PKEY *privkey, unsigned char *mod, unsigned char *exp) +{ + RSA *priv_rsa = NULL; + const BIGNUM *n; + const BIGNUM *e; + + priv_rsa = EVP_PKEY_get1_RSA(privkey); + + n = priv_rsa->n; + e = priv_rsa->e; + + BN_bn2bin(n, mod); + BN_bn2bin(e, exp); +} +#elif OPENSSL_VERSION_NUMBER < 0x30000000L +static void rimage_set_modexp(EVP_PKEY *privkey, unsigned char *mod, unsigned char *exp) +{ + const BIGNUM *n; + const BIGNUM *e; + const BIGNUM *d; + RSA *priv_rsa = NULL; + + priv_rsa = EVP_PKEY_get1_RSA(privkey); + + RSA_get0_key(priv_rsa, &n, &e, &d); + + BN_bn2bin(n, mod); + BN_bn2bin(e, exp); +} +#else +static void rimage_set_modexp(EVP_PKEY *privkey, unsigned char *mod, unsigned char *exp) +{ + BIGNUM *n = NULL; + BIGNUM *e = NULL; + + EVP_PKEY_get_bn_param(privkey, OSSL_PKEY_PARAM_RSA_N, &n); + EVP_PKEY_get_bn_param(privkey, OSSL_PKEY_PARAM_RSA_E, &e); + + BN_bn2bin(n, mod); + BN_bn2bin(e, exp); +} +#endif + +#if OPENSSL_VERSION_NUMBER < 0x30000000L +static int rimage_sign(EVP_PKEY *privkey, enum manver ver, struct hash_context *digest, + unsigned char *signature) +{ + unsigned char sig[MAN_RSA_SIGNATURE_LEN_2_5]; + unsigned int siglen = MAN_RSA_SIGNATURE_LEN; + RSA *priv_rsa = NULL; + int ret; + + priv_rsa = EVP_PKEY_get1_RSA(privkey); + + switch (ver) { + case V15: + /* fallthrough */ + case V18: + ret = RSA_sign(NID_sha256, digest->digest, digest->digest_length, + signature, &siglen, priv_rsa); + break; + case V25: + /* fallthrough */ + case VACE15: + ret = RSA_padding_add_PKCS1_PSS(priv_rsa, sig, digest->digest, digest->algo, + /* salt length */ 32); + if (ret > 0) + ret = RSA_private_encrypt(RSA_size(priv_rsa), sig, signature, priv_rsa, + RSA_NO_PADDING); + break; + default: + return -EINVAL; + } + + return ret; +} +#else +static int rimage_sign(EVP_PKEY *privkey, enum manver ver, + struct hash_context *digest, unsigned char *signature) +{ + EVP_PKEY_CTX *ctx = NULL; + size_t siglen = MAN_RSA_SIGNATURE_LEN; + int ret; + + ctx = EVP_PKEY_CTX_new(privkey, NULL /* no engine */); + if (!ctx) + return -ENOMEM; + + ret = EVP_PKEY_sign_init(ctx); + if (ret <= 0) + goto out; + + if (ver == V25 || ver == VACE15) { + ret = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING); + if (ret <= 0) { + fprintf(stderr, "error: failed to set rsa padding\n"); + goto out; + } + + ret = EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, 32); + if (ret <= 0) { + fprintf(stderr, "error: failed to set saltlen\n"); + goto out; + } + + siglen = MAN_RSA_SIGNATURE_LEN_2_5; + } + + ret = EVP_PKEY_CTX_set_signature_md(ctx, digest->algo); + if (ret <= 0) { + fprintf(stderr, "error: failed to set signature algorithm\n"); + goto out; + } + + ret = EVP_PKEY_sign(ctx, signature, &siglen, digest->digest, digest->digest_length); + if (ret <= 0) { + fprintf(stderr, "error: failed to sign manifest\n"); + goto out; + } + +out: + EVP_PKEY_CTX_free(ctx); + + return ret; +} +#endif + +#if OPENSSL_VERSION_NUMBER < 0x30000000L +static int rimage_verify(EVP_PKEY *privkey, enum manver ver, struct hash_context *digest, + unsigned char *signature) +{ + unsigned char sig[MAN_RSA_SIGNATURE_LEN_2_5]; + unsigned int siglen = MAN_RSA_SIGNATURE_LEN; + RSA *priv_rsa = NULL; + char err_buf[256]; + int ret; + + priv_rsa = EVP_PKEY_get1_RSA(privkey); + + switch (ver) { + case V15: + /* fallthrough */ + case V18: + ret = RSA_verify(NID_sha256, digest->digest, digest->digest_length, signature, + siglen, priv_rsa); + + if (ret <= 0) { + ERR_error_string(ERR_get_error(), err_buf); + fprintf(stderr, "error: verify %s\n", err_buf); + } + break; + case V25: + /* fallthrough */ + case VACE15: + /* decrypt signature */ + ret = RSA_public_decrypt(RSA_size(priv_rsa), signature, sig, priv_rsa, + RSA_NO_PADDING); + if (ret <= 0) { + ERR_error_string(ERR_get_error(), err_buf); + fprintf(stderr, "error: verify decrypt %s\n", err_buf); + return ret; + } + + ret = RSA_verify_PKCS1_PSS(priv_rsa, digest->digest, digest->algo, sig, 32); + if (ret <= 0) { + ERR_error_string(ERR_get_error(), err_buf); + fprintf(stderr, "error: verify %s\n", err_buf); + } + break; + default: + return -EINVAL; + } + + return ret; +} +#else +static int rimage_verify(EVP_PKEY *privkey, enum manver ver,struct hash_context *digest, + unsigned char *signature) +{ + EVP_PKEY_CTX *ctx = NULL; + size_t siglen = MAN_RSA_SIGNATURE_LEN; + char err_buf[256]; + int ret; + + ctx = EVP_PKEY_CTX_new(privkey, NULL /* no engine */); + if (!ctx) + return -ENOMEM; + + ret = EVP_PKEY_verify_init(ctx); + if (ret <= 0) + goto out; + + ret = EVP_PKEY_CTX_set_signature_md(ctx, digest->algo); + if (ret <= 0) { + ERR_error_string(ERR_get_error(), err_buf); + fprintf(stderr, "error: set signature %s\n", err_buf); + goto out; + } + + switch (ver) { + case V15: /* fallthrough */ + case V18: + break; + + case V25: /* fallthrough */ + case VACE15: + ret = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING); + if (ret <= 0) + goto out; + + ret = EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, 32); + if (ret <= 0) + goto out; + + siglen = MAN_RSA_SIGNATURE_LEN_2_5; + break; + default: + return -EINVAL; + } + + ret = EVP_PKEY_verify(ctx, signature, siglen, digest->digest, digest->digest_length); + if (ret <= 0) { + ERR_error_string(ERR_get_error(), err_buf); + fprintf(stderr, "error: verify %s\n", err_buf); + } + +out: + EVP_PKEY_CTX_free(ctx); + + return ret; +} +#endif + +#if OPENSSL_VERSION_NUMBER < 0x30000000L +static int rimage_get_key_size(EVP_PKEY *privkey) +{ + RSA *priv_rsa = NULL; + int key_length; + + priv_rsa = EVP_PKEY_get1_RSA(privkey); + key_length = RSA_size(priv_rsa); + + RSA_free(priv_rsa); + + return key_length; +} +#else +static int rimage_get_key_size(EVP_PKEY *privkey) +{ + return EVP_PKEY_get_size(privkey); +} +#endif + +/* + * RSA signature of manifest. The signature is an PKCS + * #1-v1_5 of the entire manifest structure, including all + * extensions, and excluding the last 3 fields of the + * manifest header (Public Key, Exponent and Signature). + */ + +int pkcs_v1_5_sign_man_v1_5(struct image *image, + struct fw_image_manifest_v1_5 *man, + void *ptr1, unsigned int size1) +{ + EVP_PKEY *privkey; + struct hash_context digest; + unsigned char mod[MAN_RSA_KEY_MODULUS_LEN]; + int ret = -EINVAL, i; + +#if DEBUG_PKCS + fprintf(stdout, "offsets 0x%lx size 0x%x\n", + ptr1 - (void *)man, size1); +#endif + + ret = rimage_read_key(&privkey, image); + if (ret < 0) + return ret; + + if (rimage_check_key(privkey) > 0) { + fprintf(stdout, " pkcs: RSA private key is valid.\n"); + } else { + fprintf(stderr, "error: validating RSA private key.\n"); + return -EINVAL; + } + + /* calculate the digest */ + hash_sha256_init(&digest); + hash_update(&digest, ptr1, size1); + ret = hash_finalize(&digest); + if (ret) + goto err; + + fprintf(stdout, " pkcs: digest for manifest is "); + hash_print(&digest); + + /* sign the manifest */ + ret = rimage_sign(privkey, V15, &digest, (unsigned char *)man->css_header.signature); + if (ret <= 0) { + fprintf(stderr, "error: failed to sign manifest\n"); + goto err; + } + + /* copy public key modulus and exponent to manifest */ + rimage_set_modexp(privkey, mod, (unsigned char *)man->css_header.exponent); + + /* modulus is reveresd */ + for (i = 0; i < MAN_RSA_KEY_MODULUS_LEN; i++) + man->css_header.modulus[i] + = mod[MAN_RSA_KEY_MODULUS_LEN - (1 + i)]; + + /* signature is reveresd, swap it */ + bytes_swap(man->css_header.signature, + sizeof(man->css_header.signature)); + +err: + EVP_PKEY_free(privkey); + return ret; +} + +/* + * RSA signature of manifest. The signature is an PKCS + * #1-v1_5 of the entire manifest structure, including all + * extensions, and excluding the last 3 fields of the + * manifest header (Public Key, Exponent and Signature). + */ + +int pkcs_v1_5_sign_man_v1_8(struct image *image, + struct fw_image_manifest_v1_8 *man, + void *ptr1, unsigned int size1, void *ptr2, + unsigned int size2) +{ + EVP_PKEY *privkey; + struct hash_context digest; + unsigned char mod[MAN_RSA_KEY_MODULUS_LEN]; + int ret = -EINVAL, i; + +#if DEBUG_PKCS + fprintf(stdout, "offsets 0x%lx size 0x%x offset 0x%lx size 0x%x\n", + ptr1 - (void *)man, size1, ptr2 - (void *)man, size2); +#endif + + ret = rimage_read_key(&privkey, image); + if (ret < 0) + return ret; + + /* validate RSA private key */ + if (rimage_check_key(privkey) > 0) { + fprintf(stdout, " pkcs: RSA private key is valid.\n"); + } else { + fprintf(stderr, "error: validating RSA private key.\n"); + return -EINVAL; + } + + /* calculate the digest */ + hash_sha256_init(&digest); + hash_update(&digest, ptr1, size1); + hash_update(&digest, ptr2, size2); + ret = hash_finalize(&digest); + if (ret) + goto err; + + fprintf(stdout, " pkcs: digest for manifest is "); + hash_print(&digest); + + /* sign the manifest */ + ret = rimage_sign(privkey, V18, &digest, (unsigned char *)man->css.signature); + if (ret <= 0) { + fprintf(stderr, "error: failed to sign manifest\n"); + goto err; + } + + /* copy public key modulus and exponent to manifest */ + rimage_set_modexp(privkey, mod, (unsigned char *)man->css.exponent); + + /* modulus is reveresd */ + for (i = 0; i < MAN_RSA_KEY_MODULUS_LEN; i++) + man->css.modulus[i] = mod[MAN_RSA_KEY_MODULUS_LEN - (1 + i)]; + + /* signature is reveresd, swap it */ + bytes_swap(man->css.signature, sizeof(man->css.signature)); + +err: + EVP_PKEY_free(privkey); + return ret; +} + +int pkcs_v1_5_sign_man_v2_5(struct image *image, + struct fw_image_manifest_v2_5 *man, + void *ptr1, unsigned int size1, void *ptr2, + unsigned int size2) +{ + EVP_PKEY *privkey; + struct hash_context digest; + unsigned char mod[MAN_RSA_KEY_MODULUS_LEN_2_5]; + int ret = -EINVAL, i; + +#if DEBUG_PKCS + fprintf(stdout, "offsets 0x%lx size 0x%x offset 0x%lx size 0x%x\n", + ptr1 - (void *)man, size1, ptr2 - (void *)man, size2); +#endif + + ret = rimage_read_key(&privkey, image); + if (ret < 0) + return ret; + + /* validate RSA private key */ + if (rimage_check_key(privkey) > 0) { + fprintf(stdout, " pkcs: RSA private key is valid.\n"); + } else { + fprintf(stderr, "error: validating RSA private key.\n"); + return -EINVAL; + } + + /* calculate the digest - SHA384 on CAVS2_5+ */ + hash_sha384_init(&digest); + hash_update(&digest, ptr1, size1); + hash_update(&digest, ptr2, size2); + ret = hash_finalize(&digest); + if (ret) + goto err; + + fprintf(stdout, " pkcs: digest for manifest is "); + hash_print(&digest); + + /* sign the manifest */ + ret = rimage_sign(privkey, V25, &digest, (unsigned char *)man->css.signature); + if (ret <= 0) { + fprintf(stderr, "error: failed to sign manifest\n"); + goto err; + } + + /* copy public key modulus and exponent to manifest */ + rimage_set_modexp(privkey, mod, (unsigned char *)man->css.exponent); + + /* modulus is reversed */ + for (i = 0; i < MAN_RSA_KEY_MODULUS_LEN_2_5; i++) + man->css.modulus[i] = mod[MAN_RSA_KEY_MODULUS_LEN_2_5 - (1 + i)]; + + /* signature is reversed, swap it */ + bytes_swap(man->css.signature, sizeof(man->css.signature)); + +err: + EVP_PKEY_free(privkey); + return ret; +} + +int pkcs_v1_5_sign_man_ace_v1_5(struct image *image, + struct fw_image_manifest_ace_v1_5 *man, + void *ptr1, unsigned int size1, void *ptr2, + unsigned int size2) +{ + EVP_PKEY *privkey; + struct hash_context digest; + unsigned char mod[MAN_RSA_KEY_MODULUS_LEN_2_5]; + int ret = -EINVAL, i; + +#if DEBUG_PKCS + fprintf(stdout, "offsets 0x%lx size 0x%x offset 0x%lx size 0x%x\n", + ptr1 - (void *)man, size1, ptr2 - (void *)man, size2); +#endif + + ret = rimage_read_key(&privkey, image); + if (ret < 0) + return ret; + + /* validate RSA private key */ + if (rimage_check_key(privkey) > 0) { + fprintf(stdout, " pkcs: RSA private key is valid.\n"); + } else { + fprintf(stderr, "error: validating RSA private key.\n"); + return -EINVAL; + } + + /* calculate the digest - SHA384 on CAVS2_5+ */ + hash_sha384_init(&digest); + hash_update(&digest, ptr1, size1); + hash_update(&digest, ptr2, size2); + ret = hash_finalize(&digest); + if (ret) + goto err; + + fprintf(stdout, " pkcs: digest for manifest is "); + hash_print(&digest); + + /* sign the manifest */ + ret = rimage_sign(privkey, VACE15, &digest, (unsigned char *)man->css.signature); + if (ret <= 0) { + fprintf(stderr, "error: failed to sign manifest\n"); + goto err; + } + + /* copy public key modulus and exponent to manifest */ + rimage_set_modexp(privkey, mod, (unsigned char *)man->css.exponent); + + /* modulus is reversed */ + for (i = 0; i < MAN_RSA_KEY_MODULUS_LEN_2_5; i++) + man->css.modulus[i] = mod[MAN_RSA_KEY_MODULUS_LEN_2_5 - (1 + i)]; + + /* signature is reversed, swap it */ + bytes_swap(man->css.signature, sizeof(man->css.signature)); + +err: + EVP_PKEY_free(privkey); + return ret; +} + +int ri_manifest_sign_v1_5(struct image *image) +{ + struct fw_image_manifest_v1_5 *man = image->fw_image; + + /* excluding the manifest header */ + char *const data1 = (char *)man + sizeof(struct fw_image_manifest_v1_5); + unsigned const size1 = image->image_end - sizeof(*man); + + return pkcs_v1_5_sign_man_v1_5(image, man, data1, size1); +} + +int ri_manifest_sign_v1_8(struct image *image) +{ + struct fw_image_manifest_v1_8 *man = image->fw_image; + + char *const data1 = (char *)man + MAN_CSS_HDR_OFFSET; + unsigned const size1 = + sizeof(struct css_header_v1_8) - + (MAN_RSA_KEY_MODULUS_LEN + MAN_RSA_KEY_EXPONENT_LEN + + MAN_RSA_SIGNATURE_LEN); + + char *const data2 = (char *)man + MAN_SIG_PKG_OFFSET_V1_8; + unsigned const size2 = + (man->css.size - man->css.header_len) * sizeof(uint32_t); + + return pkcs_v1_5_sign_man_v1_8(image, man, data1, size1, data2, size2); +} + +int ri_manifest_sign_v2_5(struct image *image) +{ + struct fw_image_manifest_v2_5 *man = image->fw_image; + + char *const data1 = (char *)man + MAN_CSS_HDR_OFFSET_2_5; + unsigned const size1 = + sizeof(struct css_header_v2_5) - + (MAN_RSA_KEY_MODULUS_LEN_2_5 + MAN_RSA_KEY_EXPONENT_LEN + + MAN_RSA_SIGNATURE_LEN_2_5); + + char *const data2 = (char *)man + MAN_SIG_PKG_OFFSET_V2_5; + unsigned const size2 = + (man->css.size - man->css.header_len) * sizeof(uint32_t); + + return pkcs_v1_5_sign_man_v2_5(image, man, data1, size1, data2, size2); +} + +int ri_manifest_sign_ace_v1_5(struct image *image) +{ + struct fw_image_manifest_ace_v1_5 *man = image->fw_image; + + char *const data1 = (char *)man + MAN_CSS_HDR_OFFSET_2_5; + unsigned const size1 = + sizeof(struct css_header_v2_5) - + (MAN_RSA_KEY_MODULUS_LEN_2_5 + MAN_RSA_KEY_EXPONENT_LEN + + MAN_RSA_SIGNATURE_LEN_2_5); + + char *const data2 = (char *)man + MAN_SIG_PKG_OFFSET_V2_5; + unsigned const size2 = + (man->css.size - man->css.header_len) * sizeof(uint32_t); + + return pkcs_v1_5_sign_man_ace_v1_5(image, man, data1, size1, data2, size2); +} + +/* + * RSA verify of manifest. The signature is an PKCS + * #1-v1_5 of the entire manifest structure, including all + * extensions, and excluding the last 3 fields of the + * manifest header (Public Key, Exponent and Signature). + */ + +int pkcs_v1_5_verify_man_v1_5(struct image *image, + struct fw_image_manifest_v1_5 *man, + void *ptr1, unsigned int size1) +{ + EVP_PKEY *privkey; + struct hash_context digest; + int ret = -EINVAL; + +#if DEBUG_PKCS + fprintf(stdout, "offsets 0x%lx size 0x%x\n", + ptr1 - (void *)man, size1); +#endif + + ret = rimage_read_key(&privkey, image); + if (ret < 0) + return ret; + + /* validate RSA private key */ + if (rimage_check_key(privkey) > 0) { + fprintf(stdout, " pkcs: RSA private key is valid.\n"); + } else { + fprintf(stderr, "error: validating RSA private key.\n"); + return -EINVAL; + } + + /* calculate the digest */ + hash_sha256_init(&digest); + hash_update(&digest, ptr1, size1); + ret = hash_finalize(&digest); + if (ret) + goto err; + + fprintf(stdout, " pkcs: digest for manifest is "); + hash_print(&digest); + + /* signature is reversed, swap it */ + bytes_swap(man->css_header.signature, + sizeof(man->css_header.signature)); + + /* verify */ + ret = rimage_verify(privkey, V15, &digest, (unsigned char *)man->css_header.signature); + if (ret <= 0) + fprintf(stderr, "error: failed to verify manifest\n"); + else + fprintf(stdout, "pkcs: signature is valid !\n"); + +err: + EVP_PKEY_free(privkey); + return ret; +} + +/* + * RSA verify of manifest. The signature is an PKCS + * #1-v1_5 of the entire manifest structure, including all + * extensions, and excluding the last 3 fields of the + * manifest header (Public Key, Exponent and Signature). + */ + +int pkcs_v1_5_verify_man_v1_8(struct image *image, + struct fw_image_manifest_v1_8 *man, + void *ptr1, unsigned int size1, void *ptr2, + unsigned int size2) +{ + EVP_PKEY *privkey; + struct hash_context digest; + int ret = -EINVAL; + +#if DEBUG_PKCS + fprintf(stdout, "offsets 0x%lx size 0x%x offset 0x%lx size 0x%x\n", + ptr1 - (void *)man, size1, ptr2 - (void *)man, size2); +#endif + + ret = rimage_read_key(&privkey, image); + if (ret < 0) + return ret; + + /* validate RSA private key */ + if (rimage_check_key(privkey) > 0) { + fprintf(stdout, " pkcs: RSA private key is valid.\n"); + } else { + fprintf(stderr, "error: validating RSA private key.\n"); + return -EINVAL; + } + + /* calculate the digest */ + hash_sha256_init(&digest); + hash_update(&digest, ptr1, size1); + hash_update(&digest, ptr2, size2); + ret = hash_finalize(&digest); + if (ret) + goto err; + + fprintf(stdout, " pkcs: digest for manifest is "); + hash_print(&digest); + + /* signature is reveresd, swap it */ + bytes_swap(man->css.signature, sizeof(man->css.signature)); + + /* verify */ + ret = rimage_verify(privkey, V18, &digest, (unsigned char *)man->css.signature); + if (ret <= 0) + fprintf(stderr, "error: failed to verify manifest\n"); + else + fprintf(stdout, "pkcs: signature is valid !\n"); + +err: + EVP_PKEY_free(privkey); + return ret; +} + +/* + * RSA signature of manifest. The signature is an RSA PSS + * of the entire manifest structure, including all + * extensions, and excluding the last 3 fields of the + * manifest header (Public Key, Exponent and Signature). + */ + +int pkcs_v1_5_verify_man_v2_5(struct image *image, + struct fw_image_manifest_v2_5 *man, + void *ptr1, unsigned int size1, void *ptr2, + unsigned int size2) +{ + EVP_PKEY *privkey; + struct hash_context digest; + int ret = -EINVAL; + +#if DEBUG_PKCS + fprintf(stdout, "offsets 0x%lx size 0x%x offset 0x%lx size 0x%x\n", + ptr1 - (void *)man, size1, ptr2 - (void *)man, size2); +#endif + + ret = rimage_read_key(&privkey, image); + if (ret < 0) + return ret; + + /* validate RSA private key */ + if (rimage_check_key(privkey) > 0) { + fprintf(stdout, " pkcs: RSA private key is valid.\n"); + } else { + fprintf(stderr, "error: validating RSA private key.\n"); + return -EINVAL; + } + + /* calculate the digest - SHA384 on CAVS2_5+ */ + hash_sha384_init(&digest); + hash_update(&digest, ptr1, size1); + hash_update(&digest, ptr2, size2); + ret = hash_finalize(&digest); + if (ret) + goto err; + + fprintf(stdout, " pkcs: digest for manifest is "); + hash_print(&digest); + + /* signature is reversed, swap it */ + bytes_swap(man->css.signature, sizeof(man->css.signature)); + + /* verify */ + ret = rimage_verify(privkey, V25, &digest, (unsigned char *)man->css.signature); + + if (ret <= 0) + fprintf(stderr, "error: failed to verify manifest\n"); + else + fprintf(stdout, "pkcs: signature is valid !\n"); + +err: + EVP_PKEY_free(privkey); + return ret; +} + +int pkcs_v1_5_verify_man_ace_v1_5(struct image *image, + struct fw_image_manifest_ace_v1_5 *man, + void *ptr1, unsigned int size1, void *ptr2, + unsigned int size2) +{ + EVP_PKEY *privkey; + struct hash_context digest; + int ret = -EINVAL; + +#if DEBUG_PKCS + fprintf(stdout, "offsets 0x%lx size 0x%x offset 0x%lx size 0x%x\n", + ptr1 - (void *)man, size1, ptr2 - (void *)man, size2); +#endif + + ret = rimage_read_key(&privkey, image); + if (ret < 0) + return ret; + + /* validate RSA private key */ + if (rimage_check_key(privkey) > 0) { + fprintf(stdout, " pkcs: RSA private key is valid.\n"); + } else { + fprintf(stderr, "error: validating RSA private key.\n"); + return -EINVAL; + } + + /* calculate the digest - SHA384 on CAVS2_5+ */ + hash_sha384_init(&digest); + hash_update(&digest, ptr1, size1); + hash_update(&digest, ptr2, size2); + ret = hash_finalize(&digest); + if (ret) + goto err; + + fprintf(stdout, " pkcs: digest for manifest is "); + hash_print(&digest); + + /* signature is reversed, swap it */ + bytes_swap(man->css.signature, sizeof(man->css.signature)); + + /* verify */ + ret = rimage_verify(privkey, VACE15, &digest, (unsigned char *)man->css.signature); + if (ret <= 0) + fprintf(stderr, "error: failed to verify manifest\n"); + else + fprintf(stdout, "pkcs: signature is valid !\n"); + +err: + EVP_PKEY_free(privkey); + return ret; +} + +int ri_manifest_verify_v1_5(struct image *image) +{ + struct fw_image_manifest_v1_5 *man = image->fw_image; + + char *const data1 = (char *)man + MAN_CSS_MAN_SIZE_V1_5; + unsigned const size1 = image->image_end - sizeof(*man); + + return pkcs_v1_5_verify_man_v1_5(image, man, data1, size1); +} + +int ri_manifest_verify_v1_8(struct image *image) +{ + struct fw_image_manifest_v1_8 *man = image->fw_image; + + char *const data1 = (char *)man + MAN_CSS_HDR_OFFSET; + unsigned const size1 = + sizeof(struct css_header_v1_8) - + (MAN_RSA_KEY_MODULUS_LEN + MAN_RSA_KEY_EXPONENT_LEN + + MAN_RSA_SIGNATURE_LEN); + + char *const data2 = (char *)man + MAN_SIG_PKG_OFFSET_V1_8; + unsigned const size2 = + (man->css.size - man->css.header_len) * sizeof(uint32_t); + + return pkcs_v1_5_verify_man_v1_8(image, man, data1, size1, data2, size2); +} + +int ri_manifest_verify_v2_5(struct image *image) +{ + struct fw_image_manifest_v2_5 *man = image->fw_image; + + char *const data1 = (char *)man + MAN_CSS_HDR_OFFSET_2_5; + unsigned const size1 = + sizeof(struct css_header_v2_5) - + (MAN_RSA_KEY_MODULUS_LEN_2_5 + MAN_RSA_KEY_EXPONENT_LEN + + MAN_RSA_SIGNATURE_LEN_2_5); + + char *const data2 = (char *)man + MAN_SIG_PKG_OFFSET_V2_5; + unsigned const size2 = + (man->css.size - man->css.header_len) * sizeof(uint32_t); + + return pkcs_v1_5_verify_man_v2_5(image, man, data1, size1, data2, size2); +} + +int get_key_size(struct image *image) +{ + EVP_PKEY *privkey; + int key_len; + int ret; + + ret = rimage_read_key(&privkey, image); + if (ret < 0) + return ret; + + key_len = rimage_get_key_size(privkey); + + EVP_PKEY_free(privkey); + + return key_len; +} diff --git a/tools/rimage/src/plat_auth.c b/tools/rimage/src/plat_auth.c new file mode 100644 index 000000000000..321d1712d0e4 --- /dev/null +++ b/tools/rimage/src/plat_auth.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2017 Intel Corporation. All rights reserved. +// +// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> +// Keyon Jie <yang.jie@linux.intel.com> + +#include <rimage/rimage.h> +#include <rimage/manifest.h> +#include <rimage/plat_auth.h> + +void ri_adsp_meta_data_create_v1_8(struct image *image, int meta_start_offset, + int meta_end_offset) +{ + struct sof_man_adsp_meta_file_ext_v1_8 *meta = + image->fw_image + meta_start_offset; + + fprintf(stdout, " meta: completing ADSP manifest\n"); + + meta->comp_desc[0].limit_offset = MAN_DESC_OFFSET_V1_8 + + image->image_end - meta_end_offset; + + fprintf(stdout, " meta: limit is 0x%x\n", + meta->comp_desc[0].limit_offset); + /* now hash the AdspFwBinaryDesc -> EOF */ +} + +void ri_adsp_meta_data_create_v2_5(struct image *image, int meta_start_offset, + int meta_end_offset) +{ + struct sof_man_adsp_meta_file_ext_v2_5 *meta = + image->fw_image + meta_start_offset; + + fprintf(stdout, " meta: completing ADSP manifest\n"); + + meta->comp_desc[0].limit_offset = MAN_DESC_OFFSET_V1_8 + + image->image_end - meta_end_offset; + + fprintf(stdout, " meta: limit is 0x%x\n", + meta->comp_desc[0].limit_offset); + /* now hash the AdspFwBinaryDesc -> EOF */ +} + +void ri_plat_ext_data_create(struct image *image) +{ + struct partition_info_ext *part = image->fw_image + + MAN_PART_INFO_OFFSET_V1_8; + struct sof_man_adsp_meta_file_ext_v1_8 *meta = + image->fw_image + MAN_META_EXT_OFFSET_V1_8; + struct sof_man_fw_desc *desc = image->fw_image + MAN_DESC_OFFSET_V1_8; + + fprintf(stdout, " auth: completing authentication manifest\n"); + + part->length = meta->comp_desc[0].limit_offset - MAN_DESC_OFFSET_V1_8; + part->length += MAN_PAGE_SIZE - (part->length % MAN_PAGE_SIZE); + + /* do this here atm */ + desc->header.preload_page_count = part->length / MAN_PAGE_SIZE; +} + +void ri_plat_ext_data_create_v2_5(struct image *image) +{ + struct sof_man_adsp_meta_file_ext_v2_5 *meta = + image->fw_image + MAN_META_EXT_OFFSET_V2_5; + struct sof_man_fw_desc *desc = image->fw_image + MAN_DESC_OFFSET_V1_8; + struct info_ext_0x16 *ext = image->fw_image + MAN_PART_INFO_OFFSET_V2_5; + uint32_t size; + + fprintf(stdout, " auth: completing authentication manifest\n"); + + size = meta->comp_desc[0].limit_offset - MAN_DESC_OFFSET_V1_8; + size += MAN_PAGE_SIZE - (size % MAN_PAGE_SIZE); + + /* do this here atm */ + desc->header.preload_page_count = size / MAN_PAGE_SIZE; + ext->size = image->image_end; +} + +void ri_plat_ext_data_create_ace_v1_5(struct image *image) +{ + struct sof_man_adsp_meta_file_ext_v2_5 *meta = + image->fw_image + MAN_META_EXT_OFFSET_ACE_V1_5; + struct sof_man_fw_desc *desc = image->fw_image + MAN_DESC_OFFSET_V1_8; + struct info_ext_0x16 *ext = image->fw_image + MAN_PART_INFO_OFFSET_ACE_V1_5; + uint32_t size; + + fprintf(stdout, " auth: completing authentication manifest\n"); + + size = meta->comp_desc[0].limit_offset - MAN_DESC_OFFSET_V1_8; + size += MAN_PAGE_SIZE - (size % MAN_PAGE_SIZE); + + desc->header.preload_page_count = size / MAN_PAGE_SIZE; + ext->size = image->image_end; +} diff --git a/tools/rimage/src/rimage.c b/tools/rimage/src/rimage.c new file mode 100644 index 000000000000..887dd85ed755 --- /dev/null +++ b/tools/rimage/src/rimage.c @@ -0,0 +1,282 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2015 Intel Corporation. All rights reserved. + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> +#include <stdbool.h> + +#include <rimage/adsp_config.h> +#include <rimage/ext_manifest_gen.h> +#include <rimage/rimage.h> +#include <rimage/manifest.h> +#include <rimage/file_utils.h> + + +static void usage(char *name) +{ + fprintf(stdout, "%s:\t -c adsp_desc -o outfile -k [key] ELF files\n", + name); + fprintf(stdout, "%s:\t -c adsp_desc -y infile -k [key]\n", + name); + fprintf(stdout, "\t -v enable verbose output\n"); + fprintf(stdout, "\t -r enable relocatable ELF files\n"); + fprintf(stdout, "\t -s MEU signing offset, disables rimage signing\n"); + fprintf(stdout, "\t -i set IMR type\n"); + fprintf(stdout, "\t -f firmware version = major.minor.micro\n"); + fprintf(stdout, "\t -b build version\n"); + fprintf(stdout, "\t -e build extended manifest\n"); + fprintf(stdout, "\t -l build loadable modules image (don't treat the first module as a bootloader)\n"); + fprintf(stdout, "\t -y verify signed file\n"); + fprintf(stdout, "\t -q resign binary\n"); + fprintf(stdout, "\t -p set PV bit\n"); +} + +int main(int argc, char *argv[]) +{ + struct image image; + struct adsp *heap_adsp; + const char *adsp_config = NULL; + int opt, ret, i, first_non_opt; + int use_ext_man = 0; + unsigned int pv_bit = 0; + bool imr_type_override = false; + + memset(&image, 0, sizeof(image)); + + image.imr_type = MAN_DEFAULT_IMR_TYPE; + + while ((opt = getopt(argc, argv, "ho:va:s:k:ri:f:b:ec:y:q:pl")) != -1) { + switch (opt) { + case 'o': + image.out_file = optarg; + break; + case 'v': + image.verbose = 1; + break; + case 's': + image.meu_offset = atoi(optarg); + break; + case 'a': + image.abi = atoi(optarg); + break; + case 'k': + image.key_name = optarg; + break; + case 'r': + image.reloc = 1; + break; + case 'i': + image.imr_type = atoi(optarg); + imr_type_override = true; + break; + case 'f': + image.fw_ver_string = optarg; + break; + case 'b': + image.fw_ver_build_string = optarg; + break; + case 'e': + use_ext_man = 1; + break; + case 'c': + adsp_config = optarg; + break; + case 'y': + image.verify_file = optarg; + break; + case 'h': + usage(argv[0]); + return 0; + case 'q': + image.in_file = optarg; + break; + case 'p': + pv_bit = 1; + break; + case 'l': + image.loadable_module = true; + break; + default: + /* getopt's default error message is good enough */ + return 1; + } + } + + first_non_opt = optind; + + /* we must have config */ + if (!adsp_config) { + usage(argv[0]); + fprintf(stderr, "error: must have adsp desc\n"); + return -EINVAL; + } + + /* requires private key */ + if (!image.key_name) { + fprintf(stderr, "error: requires private key\n"); + return -EINVAL; + } + + /* make sure we have an outfile if not verifying */ + if ((!image.out_file && !image.verify_file)) { + usage(argv[0]); + return -EINVAL; + } + + /* firmware version: major.minor.micro */ + if (image.fw_ver_string) { + ret = sscanf(image.fw_ver_string, "%hu.%hu.%hu", + &image.fw_ver_major, + &image.fw_ver_minor, + &image.fw_ver_micro); + + if (ret != 3) { + fprintf(stderr, + "error: cannot parse firmware version major.minor.micro\n"); + return -EINVAL; + } + } + + /* firmware build id */ + if (image.fw_ver_build_string) { + ret = sscanf(image.fw_ver_build_string, "%hu", + &image.fw_ver_build); + + if (ret != 1) { + fprintf(stderr, + "error: cannot parse build version\n"); + return -EINVAL; + } + } + /* find machine */ + heap_adsp = malloc(sizeof(struct adsp)); + if (!heap_adsp) { + fprintf(stderr, "error: memory allocation for adsp struct failed\n"); + return -ENOMEM; + } + image.adsp = heap_adsp; + memset(heap_adsp, 0, sizeof(*heap_adsp)); + ret = adsp_parse_config(adsp_config, &image); + if (ret < 0) + goto out; + + /* verify mode ? */ + if (image.verify_file) { + ret = verify_image(&image); + goto out; + } + + if (image.in_file) { + fprintf(stdout, "going to re-sign\n"); + ret = resign_image(&image); + goto out; + } + + /* set IMR Type and the PV bit in found machine definition */ + if (image.adsp->man_v1_8) { + if (imr_type_override) + image.adsp->man_v1_8->adsp_file_ext.imr_type = image.imr_type; + image.adsp->man_v1_8->css.reserved0 = pv_bit; + } + + if (image.adsp->man_v2_5) { + if (imr_type_override) + image.adsp->man_v2_5->adsp_file_ext.imr_type = image.imr_type; + image.adsp->man_v2_5->css.reserved0 = pv_bit; + } + + if (image.adsp->man_ace_v1_5) { + image.adsp->man_ace_v1_5->css.reserved0 = pv_bit; + } + + /* parse input ELF files */ + image.num_modules = argc - first_non_opt; + + if (image.num_modules <= 0) { + fprintf(stderr, + "error: requires at least one ELF input module\n"); + ret = -EINVAL; + goto out; + } + + /* Some platforms dont have modules configuration in toml file */ + if (image.adsp->modules && image.num_modules > image.adsp->modules->mod_man_count) { + fprintf(stderr, "error: Each ELF input module requires entry in toml file.\n"); + ret = -EINVAL; + goto out; + } + + /* getopt reorders argv[] */ + for (opt = first_non_opt; opt < argc; opt++) { + i = opt - first_non_opt; + fprintf(stdout, "\nModule Reading %s\n", argv[opt]); + ret = module_open(&image.module[i].file, argv[opt], image.verbose); + if (ret < 0) + goto out; + + module_parse_sections(&image.module[i].file, &image.adsp->mem, image.verbose); + + /* When there is more than one module, then first one is bootloader. + * Does not apply to building a image of a loadable module. */ + image.module[i].is_bootloader = image.num_modules > 1 && i == 0 && + !image.loadable_module; + } + + /* validate all modules */ + ret = modules_validate(&image); + if (ret < 0) + goto out; + + /* open outfile for writing */ + unlink(image.out_file); + image.out_fd = fopen(image.out_file, "wb"); + if (!image.out_fd) { + ret = file_error("unable to open file for writing", image.out_file); + goto out; + } + + /* process and write output */ + if (image.meu_offset) { + assert(image.adsp->write_firmware_meu); + ret = image.adsp->write_firmware_meu(&image); + } else { + assert(image.adsp->write_firmware); + ret = image.adsp->write_firmware(&image); + } + if (ret) + goto out; + + /* build extended manifest */ + if (use_ext_man) { + if (image.adsp->write_firmware_ext_man) + ret = image.adsp->write_firmware_ext_man(&image); + else + ret = ext_man_write(&image); + + if (ret < 0) { + fprintf(stderr, "error: unable to write extended manifest, %d\n", + ret); + goto out; + } + } + +out: + /* free memory */ + adsp_free(heap_adsp); + + /* close files */ + if (image.out_fd) + fclose(image.out_fd); + + /* Free loaded modules */ + for (i = 0; i < image.num_modules; i++) { + module_close(&image.module[i].file); + } + + return ret; +} diff --git a/tools/rimage/src/toml_utils.c b/tools/rimage/src/toml_utils.c new file mode 100644 index 000000000000..7570c5b1f7bb --- /dev/null +++ b/tools/rimage/src/toml_utils.c @@ -0,0 +1,347 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + * Author: Karol Trzcinski <karolx.trzcinski@linux.intel.com> + * Marc Herbert <marc.herbert@intel.com> + */ + +#include "toml.h" +#include <rimage/toml_utils.h> +#include <rimage/cavs/cavs_ext_manifest.h> + +#include <assert.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <stdarg.h> + +void print_bytes(FILE *out, const uint8_t *arr, size_t len) +{ + for (const uint8_t *pos = arr; pos < arr + len; pos++) { + char c = *pos; + + if (isprint(c)) + fputc(c, out); + else + fprintf(out, "\\x%.2x", c); + } +} + +#define DUMP_PRINTABLE_BYTES(name, var) _dump_printable_bytes(name, var, sizeof(var)) + +void _dump_printable_bytes(const char *name, const uint8_t *arr, size_t len) +{ + printf(DUMP_KEY_FMT, name); + print_bytes(stdout, arr, len); + printf("\n"); +} + +/** private parser error trace function */ +void vlog_err(const char *msg, va_list vl) +{ + vfprintf(stderr, msg, vl); +} + +/** parser error trace function, error code is returned to shorten client code */ +int log_err(int err_code, const char *msg, ...) +{ + va_list vl; + + va_start(vl, msg); + vlog_err(msg, vl); + va_end(vl); + return err_code; +} + +/** log malloc error message for given key */ +int err_malloc(const char *key) +{ + return log_err(-ENOMEM, "error: malloc failed during parsing key '%s'\n", key); +} + +/** log key not found error */ +int err_key_not_found(const char *key) +{ + return log_err(-EINVAL, "error: '%s' not found\n", key); +} + +/** error during parsing key value, possible detailed message */ +int err_key_parse(const char *key, const char *extra_msg, ...) +{ + int ret = -EINVAL; + va_list vl; + + if (extra_msg) { + log_err(ret, "error: key '%s' parsing error, ", key); + va_start(vl, extra_msg); + vlog_err(extra_msg, vl); + va_end(vl); + return log_err(ret, "\n"); + } else { + return log_err(ret, "error: key '%s' parsing error\n", key); + } +} + +/** initialize parser context before parsing */ +void parse_ctx_init(struct parse_ctx *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); +} + +/** check nothing left unparsed in given parsing context */ +int assert_everything_parsed(const toml_table_t *table, struct parse_ctx *ctx) +{ + const char *key = toml_table_key(table); + int ret = 0; + + /* toml_table_key returns NULL for global context */ + if (!key) + key = "toml"; + + /* from number of parsed fields subtract fields count in given table */ + ctx->key_cnt = toml_table_nkval(table) - ctx->key_cnt; + ctx->array_cnt = toml_table_narr(table) - ctx->array_cnt; + ctx->table_cnt = toml_table_ntab(table) - ctx->table_cnt; + + /* when any field left unparsed, then raise error */ + if (ctx->key_cnt != 0) + ret = log_err(-EINVAL, "error: %d unparsed keys left in '%s'\n", ctx->key_cnt, key); + if (ctx->array_cnt != 0) + ret = log_err(-EINVAL, "error: %d unparsed arrays left in '%s'\n", ctx->array_cnt, + key); + if (ctx->table_cnt != 0) + ret = log_err(-EINVAL, "error: %d unparsed tables left in '%s'\n", ctx->table_cnt, + key); + return ret; +} + +/** + * Parse hex value from key in given toml table + * @param table toml table where key is specified + * @param ctx parsing context, key counter will be incremented after successful key parse + * @param key field name + * @param def is default value or -1 when value don't have default value + * @param error code, 0 when success + * @return default, parsed, or UINT32_MAX value for error cases + */ +uint32_t parse_uint32_hex_key(const toml_table_t *table, struct parse_ctx *ctx, + const char *key, int64_t def, int *error) +{ + toml_raw_t raw; + char *temp_s; + uint32_t val; + int ret; + + /* look for key in given table, assign def value when key not found */ + raw = toml_raw_in(table, key); + if (!raw) { + if (def < 0 || def > UINT32_MAX) { + *error = err_key_not_found(key); + return UINT32_MAX; + } else { + *error = 0; + return (uint32_t)def; + } + } + /* there is not build-in support for hex numbers in toml, so read then as string */ + ret = toml_rtos(raw, &temp_s); + if (ret < 0) { + *error = err_key_parse(key, NULL); + return UINT32_MAX; + } + val = strtoul(temp_s, 0, 0); + + free(temp_s); + /* assert parsing success and value is within uint32_t range */ + if (errno < 0) { + *error = err_key_parse(key, "can't convert hex value"); + return UINT32_MAX; + } + + /* set success error code and increment parsed key counter */ + *error = 0; + ++ctx->key_cnt; + return (uint32_t)val; +} + +/** + * Parse integer value from key in given toml table + * @param table toml table where key is specified + * @param ctx parsing context, key counter will be incremented after successful key parse + * @param key field name + * @param def is default value or -1 when value don't have default value + * @param error code, 0 when success + * @return default, parsed, or UINT32_MAX value for error cases + */ +uint32_t parse_uint32_key(const toml_table_t *table, struct parse_ctx *ctx, const char *key, + int64_t def, int *error) +{ + toml_raw_t raw; + int64_t val; + int ret; + + /* look for key in given table, assign def value when key not found */ + raw = toml_raw_in(table, key); + if (!raw) { + if (def < 0 || def > UINT32_MAX) { + *error = err_key_not_found(key); + return UINT32_MAX; + } else { + *error = 0; + return (uint32_t)def; + } + } + /* there is build-in support for integer numbers in toml, so use lib function */ + ret = toml_rtoi(raw, &val); + if (ret < 0) { + *error = err_key_parse(key, "can't convert to integer value"); + return UINT32_MAX; + } + /* assert value is within uint32_t range */ + if (val < 0 || val > UINT32_MAX) { + *error = log_err(-ERANGE, "key %s out of uint32_t range", key); + return UINT32_MAX; + } + /* set success error code and increment parsed key counter */ + *error = 0; + ++ctx->key_cnt; + return (uint32_t)val; +} + +/** + * Parse string value from key in given toml table to uint8_t array. The + * destination is NOT a string because it is padded with zeros if and + * only if there is some capacity left. For string destinations use + * parse_str_key(). + * + * @param table toml table where key is specified + * @param ctx parsing context, key counter will be incremented after successful key parse + * @param key field name + * @param dst uint8_t[] destination + * @param capacity dst array size + * @param error code, 0 when success + */ +void parse_printable_key(const toml_table_t *table, struct parse_ctx *ctx, const char *key, + uint8_t *dst, int capacity, int *error) +{ + toml_raw_t raw; + char *temp_s; + int len; + int ret; + + /* look for key in given table */ + raw = toml_raw_in(table, key); + if (!raw) { + *error = err_key_not_found(key); + return; + } + /* read string from toml, theres malloc inside toml_rtos() */ + ret = toml_rtos(raw, &temp_s); + if (ret < 0) { + *error = err_key_parse(key, NULL); + return; + } + + len = strlen(temp_s); + if (len > capacity) { + if (len > 20) { + static const char ellipsis[] = "..."; + const size_t el_len = sizeof(ellipsis); + + strncpy(temp_s + 20 - el_len, ellipsis, el_len); + } + + *error = log_err(-EINVAL, "Too long input '%s' for key '%s' (%d > %d) characters\n", + temp_s, key, len, capacity); + free(temp_s); + return; + } + + /* copy string to dst, pad with zeros the space left if any */ + strncpy((char *)dst, temp_s, capacity); + free(temp_s); + /* update parsing context */ + ++ctx->key_cnt; + *error = 0; +} + +/** + * Parse string value from key in given toml table to given + * char[]. Destination is padded with zeros. As the only difference with + * parse_printable_key(), dst is guaranteed to be null-terminated when + * there is no error because the last destination byte is reserved for + * that. + * + * @param table toml table where key is specified + * @param ctx parsing context, key counter will be incremented after successful key parse + * @param key field name + * @param dst char[] destination + * @param capacity dst array size including null termination. + * @param error code, 0 when success + */ +void parse_str_key(const toml_table_t *table, struct parse_ctx *ctx, const char *key, + char *dst, int capacity, int *error) +{ + parse_printable_key(table, ctx, key, (uint8_t *)dst, capacity - 1, error); + if (*error) /* return immediately to help forensics */ + return; + dst[capacity - 1] = 0; +} + +void parse_uuid(const char *buf, uint8_t *uuid) +{ + struct uuid_t id; + uint32_t d[11]; + + const int parsed_uuid_fields = + sscanf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", &d[0], + &d[1], &d[2], &d[3], &d[4], &d[5], &d[6], &d[7], &d[8], &d[9], &d[10]); + + assert(parsed_uuid_fields == 11); + + id.d0 = d[0]; + id.d1 = (uint16_t)d[1]; + id.d2 = (uint16_t)d[2]; + id.d3 = (uint8_t)d[3]; + id.d4 = (uint8_t)d[4]; + id.d5 = (uint8_t)d[5]; + id.d6 = (uint8_t)d[6]; + id.d7 = (uint8_t)d[7]; + id.d8 = (uint8_t)d[8]; + id.d9 = (uint8_t)d[9]; + id.d10 = (uint8_t)d[10]; + + memcpy(uuid, &id, sizeof(id)); +} + +/** version is stored as toml array with integer number, something like: + * "version = [1, 8]" + */ +int parse_version(toml_table_t *toml, int64_t version[2]) +{ + toml_array_t *arr; + toml_raw_t raw; + int ret; + int i; + + /* check "version" key */ + arr = toml_array_in(toml, "version"); + if (!arr) + return err_key_not_found("version"); + if (toml_array_type(arr) != 'i' || toml_array_nelem(arr) != 2 || + toml_array_kind(arr) != 'v') + return err_key_parse("version", "wrong array type or length != 2"); + + /* parse "version" array elements */ + for (i = 0; i < 2; ++i) { + raw = toml_raw_at(arr, i); + if (raw == 0) + return err_key_parse("version", NULL); + ret = toml_rtoi(raw, &version[i]); + if (ret < 0) + return err_key_parse("version", "can't convert element to integer"); + } + return 0; +} diff --git a/tools/rimage/tomlc99 b/tools/rimage/tomlc99 new file mode 160000 index 000000000000..e3a03f5ec7d8 --- /dev/null +++ b/tools/rimage/tomlc99 @@ -0,0 +1 @@ +Subproject commit e3a03f5ec7d8d33be705c5ce8a632d998ce9b4d1 diff --git a/tools/sof_ri_info/sof_ri_info.py b/tools/sof_ri_info/sof_ri_info.py index 8aa5dbbcf56e..126a35e234a3 100755 --- a/tools/sof_ri_info/sof_ri_info.py +++ b/tools/sof_ri_info/sof_ri_info.py @@ -800,6 +800,15 @@ def parse_mft_extension(reader, ext_id): ext.add_a(Auint('base_offset', reader.read_dw())) ext.add_a(Auint('limit_offset', reader.read_dw())) ext.add_a(Abytes('attributes', reader.read_bytes(16))) + elif ext_type == 35: + reader.info("Signed package info extension") + ext = SignedPkgInfoExtension(ext_id, reader.get_offset()-8) + ext.add_a(Astring('name', reader.read_string(4))) + ext.add_a(Auint('vcn', reader.read_dw())) + ext.add_a(Auint('svn', reader.read_dw())) + ext.add_a(Auint('partition_usage', reader.read_b(), 'red')) + read_len = reader.get_offset() - begin_off + reader.ff_data(ext_len - read_len) else: reader.info("Other extension") ext = MftExtension(ext_id, 'Other Extension', reader.get_offset()-8) @@ -1310,6 +1319,22 @@ def dump_info(self, pref, comp_filter): out += ' svn {}'.format(self.adir['svn']) print(out) +class SignedPkgInfoExtension(MftExtension): + """ Signed package info Extension + """ + def __init__(self, ext_id, offset): + super(SignedPkgInfoExtension, + self).__init__(ext_id, 'Signed package info Extension', offset) + + def dump_info(self, pref, comp_filter): + super().dump_info(pref, comp_filter) + out = '{}'.format(pref) + out += ' name {}'.format(self.adir['name']) + out += ' vcn {}'.format(self.adir['vcn']) + out += ' svn {}'.format(self.adir['svn']) + out += ' partition_usage {}'.format(self.adir['partition_usage']) + print(out) + class AdspMetadataFileExt(MftExtension): """ ADSP Metadata File Extension """ diff --git a/tools/topology/topology1/platform/intel/bxt.m4 b/tools/test/topology/platform/generic.m4 similarity index 76% rename from tools/topology/topology1/platform/intel/bxt.m4 rename to tools/test/topology/platform/generic.m4 index 20205b5fc0ed..49469d6b4b9d 100644 --- a/tools/topology/topology1/platform/intel/bxt.m4 +++ b/tools/test/topology/platform/generic.m4 @@ -1,7 +1,6 @@ # -# Broxton differentiation for pipelines and components +# Generic test platform values for pipelines and components # -include(`platform/intel/dmic.m4') undefine(`SSP_MCLK_RATE') define(`SSP_MCLK_RATE', `19200000') @@ -15,27 +14,8 @@ define(`SSP_BCLK', `1920000') undefine(`SSP_FSYNC') define(`SSP_FSYNC', `48000') -define(`DMIC_PIPE_CAPTURE', `sof/pipe-volume-capture.m4') - -define(`PIPE_VOLUME_PLAYBACK', `sof/pipe-volume-playback.m4') - -undefine(`DMIC01_FMT') -define(`DMIC01_FMT', `s16le') - -undefine(`DMIC1_FMT') -define(`DMIC1_FMT', `s16le') - define(`SSP1_VALID_BITS_STR', `s16le') -undefine(`HDMI0_INDEX') -define(`HDMI0_INDEX', `3') - -undefine(`HDMI1_INDEX') -define(`HDMI1_INDEX', `4') - -undefine(`HDMI2_INDEX') -define(`HDMI2_INDEX', `5') - undefine(`SSP_BITS_WIDTH') define(`SSP_BITS_WIDTH', `20') @@ -50,7 +30,7 @@ define(`MCLK_ID', `1') include(`memory.m4') -dnl Memory capabilities for diferent buffer types on Baytrail +dnl Memory capabilities for different buffer types define(`PLATFORM_DAI_MEM_CAP', MEMCAPS(MEM_CAP_RAM, MEM_CAP_DMA, MEM_CAP_CACHE, MEM_CAP_HP)) define(`PLATFORM_HOST_MEM_CAP', diff --git a/tools/test/topology/test-all.m4 b/tools/test/topology/test-all.m4 index 0187ba96d069..e30df5d5fe40 100644 --- a/tools/test/topology/test-all.m4 +++ b/tools/test/topology/test-all.m4 @@ -14,8 +14,8 @@ include(`common/tlv.m4') # Include Token library include(`sof/tokens.m4') -# Include Apollolake DSP configuration -include(`platform/intel/bxt.m4') +# Include generic DSP configuration +include(`platform/generic.m4') DEBUG_START diff --git a/tools/test/topology/test-capture.m4 b/tools/test/topology/test-capture.m4 index b7354544cb6b..b5a8deb7681c 100644 --- a/tools/test/topology/test-capture.m4 +++ b/tools/test/topology/test-capture.m4 @@ -6,7 +6,6 @@ include(`utils.m4') include(`dai.m4') include(`ssp.m4') -include(`dmic.m4') include(`pipeline.m4') # Include TLV library @@ -15,8 +14,8 @@ include(`common/tlv.m4') # Include Token library include(`sof/tokens.m4') -# Include Apollolake DSP configuration -include(`platform/intel/bxt.m4') +# Include generic DSP configuration +include(`platform/generic.m4') DEBUG_START diff --git a/tools/test/topology/test-playback.m4 b/tools/test/topology/test-playback.m4 index 0400583335df..48ed1f26af37 100644 --- a/tools/test/topology/test-playback.m4 +++ b/tools/test/topology/test-playback.m4 @@ -14,8 +14,8 @@ include(`common/tlv.m4') # Include Token library include(`sof/tokens.m4') -# Include Apollolake DSP configuration -include(`platform/intel/bxt.m4') +# Include generic DSP configuration +include(`platform/generic.m4') DEBUG_START diff --git a/tools/testbench/CMakeLists.txt b/tools/testbench/CMakeLists.txt index f68f6418399f..3d4e622c08bf 100644 --- a/tools/testbench/CMakeLists.txt +++ b/tools/testbench/CMakeLists.txt @@ -27,6 +27,7 @@ set(sof_binary_directory "${PROJECT_BINARY_DIR}/sof_ep/build") set(config_h ${sof_binary_directory}/library_autoconfig.h) target_include_directories(testbench PRIVATE "${sof_source_directory}/src/platform/library/include") +target_include_directories(testbench PRIVATE "${sof_source_directory}/src/audio") # Configuration time, make copy configure_file(${default_asoc_h} ${CMAKE_CURRENT_BINARY_DIR}/include/alsa/sound/asoc.h) diff --git a/tools/testbench/common_test.c b/tools/testbench/common_test.c index c80b94d503e2..87d815a5bbae 100644 --- a/tools/testbench/common_test.c +++ b/tools/testbench/common_test.c @@ -54,6 +54,7 @@ int tb_setup(struct sof *sof, struct testbench_prm *tp) sys_comp_module_drc_interface_init(); sys_comp_module_eq_fir_interface_init(); sys_comp_module_eq_iir_interface_init(); + sys_comp_module_google_rtc_audio_processing_interface_init(); sys_comp_module_multiband_drc_interface_init(); sys_comp_module_mux_interface_init(); sys_comp_module_src_interface_init(); @@ -264,15 +265,15 @@ int tb_pipeline_params(struct testbench_prm *tp, struct ipc *ipc, struct pipelin /* print debug messages */ void debug_print(char *message) { - if (debug) + if (host_trace_level >= LOG_LEVEL_DEBUG) printf("debug: %s", message); } /* enable trace in testbench */ -void tb_enable_trace(bool enable) +void tb_enable_trace(unsigned int log_level) { - test_bench_trace = enable; - if (enable) + host_trace_level = log_level; + if (host_trace_level) debug_print("trace print enabled\n"); else debug_print("trace print disabled\n"); diff --git a/tools/testbench/include/testbench/trace.h b/tools/testbench/include/testbench/trace.h index 73c50d43853d..66e63e217adf 100644 --- a/tools/testbench/include/testbench/trace.h +++ b/tools/testbench/include/testbench/trace.h @@ -11,6 +11,6 @@ #ifndef _TRACE_H #define _TRACE_H -void tb_enable_trace(bool enable); +void tb_enable_trace(unsigned int log_level); #endif diff --git a/tools/testbench/testbench.c b/tools/testbench/testbench.c index f4302765408f..889aba1c0209 100644 --- a/tools/testbench/testbench.c +++ b/tools/testbench/testbench.c @@ -317,9 +317,9 @@ static int parse_input_args(int argc, char **argv, struct testbench_prm *tp) tp->channels_out = atoi(optarg); break; - /* enable debug prints */ + /* set debug log level */ case 'd': - debug = 1; + host_trace_level = atoi(optarg); break; /* number of pipeline copy() iterations */ @@ -734,7 +734,6 @@ int main(int argc, char **argv) int i, err; /* initialize input and output sample rates, files, etc. */ - debug = 0; tp.total_cycles = 0; tp.fs_in = 0; tp.fs_out = 0; @@ -795,9 +794,10 @@ int main(int argc, char **argv) } if (tp.quiet) - tb_enable_trace(false); /* reduce trace output */ + tb_enable_trace(0); /* reduce trace output */ else - tb_enable_trace(true); + tb_enable_trace(1); + /* initialize ipc and scheduler */ if (tb_setup(sof_get(), &tp) < 0) { diff --git a/tools/topology/CMakeLists.txt b/tools/topology/CMakeLists.txt index 2ef3feb784be..33722120e41b 100644 --- a/tools/topology/CMakeLists.txt +++ b/tools/topology/CMakeLists.txt @@ -1,5 +1,49 @@ set(SOF_TOPOLOGY_BINARY_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + +function(alsatplg_version OUT_STATUS OUT_VERSION) + execute_process(COMMAND alsatplg --version + RESULT_VARIABLE status + OUTPUT_VARIABLE stdout + OUTPUT_STRIP_TRAILING_WHITESPACE) + message(DEBUG "alsatplg --version: status=${status}, output=${stdout}") + + set(${OUT_STATUS} "${status}" PARENT_SCOPE) + + # Some error messages have already been printed on stderr + if(NOT status EQUAL 0) + message(WARNING "alsatplg --version returned status: ${status}, +${stdout}") + return() + endif() + + string(REPLACE "\n" ";" ALSA_VERSION_LIST ${stdout}) + list(GET ALSA_VERSION_LIST 0 ALSATPLG_VERSION) + string(REGEX MATCH "[0-9]\.[0-9]\.*[0-9]*" ALSATPLG_VERSION_NUMBER ${ALSATPLG_VERSION}) + + set(${OUT_VERSION} "${ALSATPLG_VERSION_NUMBER}" PARENT_SCOPE) +endfunction() + + +# Being written in C, `alsatplg` silently ignores some invalid inputs +# and produces an corrupt .tplg file instead of returning an error code +# that fails the build. For instance, alsatplg versions < 1.2.5 silently +# corrupt `codec_consumer` and turn it into `codec_master` instead. +# Longer story in #5192. +alsatplg_version(STATUS ALSATPLG_VERSION_NUMBER) +if(NOT STATUS EQUAL 0) + message(WARNING "alsatplg failed: ${STATUS}; all topologies skipped") + return() +else() + if(${ALSATPLG_VERSION_NUMBER} VERSION_LESS "1.2.5") + message(WARNING "All topologies skipped: minimum alsatplg version 1.2.5,\ + found ${ALSATPLG_VERSION_NUMBER}.") + return() + endif() + # success +endif() + + # This use of VERBOSE relies on original CMake behavior. # From the add_custom_command() manual: # diff --git a/tools/topology/topology1/CMakeLists.txt b/tools/topology/topology1/CMakeLists.txt index 028c924abaad..70b0bdd260de 100644 --- a/tools/topology/topology1/CMakeLists.txt +++ b/tools/topology/topology1/CMakeLists.txt @@ -1,7 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause file(GLOB TPLG_DEPS - platform/intel/*.m4 platform/common/*.m4 common/*.m4 m4/*.m4 @@ -21,145 +20,6 @@ add_custom_command(OUTPUT abi.h ) set(TPLGS - ## HDaudio codec topologies - "sof-hda-generic\;sof-hda-generic\;-DCHANNELS=0\;-DHSPROC=volume\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-1ch\;-DCHANNELS=2\;-DHSPROC=volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-1ch-pdm1\;-DPDM1\;-DCHANNELS=2\;-DHSPROC=volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-2ch\;-DCHANNELS=2\;-DHSPROC=volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-2ch-pdm1\;-DPDM1\;-DCHANNELS=2\;-DHSPROC=volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-3ch\;-DCHANNELS=4\;-DHSPROC=volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-4ch\;-DCHANNELS=4\;-DHSPROC=volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - ## end HDaudio codec topologies - - "sof-hda-generic-idisp\;sof-hda-generic-idisp\;-DCHANNELS=0\;-DDYNAMIC=1" - "sof-hda-generic-idisp\;sof-hda-generic-idisp-2ch\;-DCHANNELS=2\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - "sof-hda-generic-idisp\;sof-hda-generic-idisp-4ch\;-DCHANNELS=4\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - "sof-cavs-nocodec\;sof-tgl-nocodec\;-DPLATFORM=tgl\;-DDMIC_48k_CORE_ID=1\;-DSSP0_CORE_ID=2\;-DSSP1_CORE_ID=3\;-DDYNAMIC=1" - "sof-cavs-nocodec\;sof-tgl-h-nocodec\;-DPLATFORM=tgl\;-DNCORES=2\;-DDYNAMIC=1" - "sof-cavs-nocodec\;sof-ehl-nocodec\;-DPLATFORM=ehl\;-DDYNAMIC=1" - "sof-cavs-nocodec\;sof-adl-nocodec\;-DPLATFORM=adl\;-DDMIC_48k_CORE_ID=1\;-DSSP0_CORE_ID=2\;-DSSP1_CORE_ID=3\;-DDYNAMIC=1" - "sof-cavs-nocodec\;sof-rpl-nocodec\;-DPLATFORM=rpl\;-DDMIC_48k_CORE_ID=1\;-DSSP0_CORE_ID=2\;-DSSP1_CORE_ID=3\;-DDYNAMIC=1" - - ## SoundWire topologies - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-tgl-rt711-rt1308-mono-rt715\;-DPLATFORM=tgl\;-DMONO\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-tgl-rt711-l0-rt1316-l1-mono-rt714-l3\;-DPLATFORM=tgl\;-DMONO\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-tgl-rt715-rt711-rt1308-mono\;-DPLATFORM=tgl\;-DMONO\;-DUAJ_LINK=1\;-DAMP_1_LINK=2\;-DMIC_LINK=0" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-tgl-rt711-rt1308-rt715\;-DPLATFORM=tgl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-tgl-rt711-rt1316-rt714\;-DPLATFORM=tgl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt711-l0-rt1308-l12-rt715-l3\;-DPLATFORM=adl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt711-l0-rt1316-l12-rt714-l3\;-DPLATFORM=adl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt711-l0-rt1316-l13-rt714-l2\;-DPLATFORM=adl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=3\;-DEXT_AMP_REF\;-DMIC_LINK=2" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt711-l2-rt1316-l01-rt714-l3\;-DPLATFORM=adl\;-DUAJ_LINK=2\;-DAMP_1_LINK=0\;-DAMP_2_LINK=1\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt711-l2-rt1316-l01\;-DPLATFORM=adl\;-DUAJ_LINK=2\;-DAMP_1_LINK=0\;-DAMP_2_LINK=1\;-DEXT_AMP_REF\;-DNO_LOCAL_MIC" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-rpl-rt711-l2\;-DPLATFORM=rpl\;-DUAJ_LINK=2\;-DNOAMP\;-DNO_LOCAL_MIC" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-rpl-rt711-l0\;-DPLATFORM=rpl\;-DUAJ_LINK=0\;-DNOAMP\;-DNO_LOCAL_MIC" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-rpl-rt711-l2-rt1316-l01-rt714-l3\;-DPLATFORM=rpl\;-DUAJ_LINK=2\;-DAMP_1_LINK=0\;-DAMP_2_LINK=1\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-rpl-rt711-l2-rt1316-l01\;-DPLATFORM=rpl\;-DUAJ_LINK=2\;-DAMP_1_LINK=0\;-DAMP_2_LINK=1\;-DEXT_AMP_REF\;-DNO_LOCAL_MIC" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-rpl-rt711-l0-rt1316-l12-rt714-l3\;-DPLATFORM=rpl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-rpl-rt711-l0-rt1318-l12-rt714-l3\;-DPLATFORM=rpl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-rpl-rt711-l0-rt1318-l12\;-DPLATFORM=rpl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DEXT_AMP_REF\;-DNO_LOCAL_MIC" - "sof-tgl-rt711-rt1308\;sof-tgl-rt711-rt1308-2ch\;-DCHANNELS=2\;-DEXT_AMP\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=tgl" - "sof-tgl-rt711-rt1308\;sof-tgl-rt711-rt1308-4ch\;-DCHANNELS=4\;-DEXT_AMP\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=tgl" - "sof-tgl-rt711-rt1308\;sof-tgl-rt711-4ch\;-DCHANNELS=4\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=tgl" - "sof-tgl-rt711-rt1308\;sof-adl-rt711-4ch\;-DCHANNELS=4\;-DBT_OFFLOAD\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=adl" - "sof-tgl-rt711-rt1308\;sof-adl-rt711\;-DCHANNELS=0\;-DBT_OFFLOAD\;-DPLATFORM=adl" - "sof-tgl-rt711-rt1308\;sof-adl-rt711-l0-rt1316-l3-2ch\;-DCHANNELS=2\;-DEXT_AMP\;-DEXT_AMP_REF\;-DAMP_1_LINK=3\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=adl" - "sof-tgl-rt711-rt1308\;sof-adl-rt711-l0-rt1316-l2-2ch\;-DCHANNELS=2\;-DEXT_AMP\;-DEXT_AMP_REF\;-DAMP_1_LINK=2\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=adl" - "sof-tgl-rt711-rt1308\;sof-adl-rt711-l0-rt1316-l2-4ch\;-DCHANNELS=4\;-DEXT_AMP\;-DEXT_AMP_REF\;-DAMP_1_LINK=2\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=adl" - "sof-tgl-rt711-rt1308\;sof-rpl-rt711-4ch\;-DCHANNELS=4\;-DBT_OFFLOAD\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=rpl" - "sof-tgl-rt711-rt1308\;sof-rpl-rt711\;-DCHANNELS=0\;-DBT_OFFLOAD\;-DPLATFORM=rpl" - ## end SoundWire topologies - - ## SoundWire NOJACK topologies - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt1316-l1-mono-rt714-l0\;-DPLATFORM=adl\;-DMONO\;-DNOJACK\;-DAMP_1_LINK=1\;-DEXT_AMP_REF\;-DMIC_LINK=0" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt1316-l2-mono-rt714-l0\;-DPLATFORM=adl\;-DMONO\;-DNOJACK\;-DAMP_1_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=0" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt1316-l12-rt714-l0\;-DPLATFORM=adl\;-DNOJACK\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=0" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt1316-l2-mono-rt714-l3\;-DPLATFORM=adl\;-DMONO\;-DNOJACK\;-DAMP_1_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-rpl-rt1316-l12-rt714-l0\;-DPLATFORM=rpl\;-DNOJACK\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=0" - ## end SoundWire NOJACK topologies - - "sof-ehl-rt5660\;sof-ehl-rt5660\;-DHDMI=1" - "sof-ehl-rt5660\;sof-ehl-rt5660-nohdmi" - "sof-tgl-max98357a-rt5682\;sof-tgl-max98357a-rt5682\;-DCODEC=MAX98357A\;-DFMT=s16le\;-DPLATFORM=tgl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1" - "sof-tgl-max98357a-rt5682\;sof-adl-max98357a-rt5682\;-DCODEC=MAX98357A\;-DFMT=s16le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=2" - "sof-tgl-max98357a-rt5682\;sof-adl-max98357a-rt5682-rtnr\;-DCODEC=MAX98357A\;-DFMT=s16le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=2\;-DCHANNELS=2\;-DRTNR" - "sof-tgl-max98357a-rt5682\;sof-adl-max98357a-rt5682-waves\;-DCODEC=MAX98357A\;-DFMT=s16le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=2\;-DWAVES" - "sof-tgl-max98357a-rt5682\;sof-adl-max98357a-rt5682-2way\;-DCODEC=MAX98360A_TDM\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=2\;-D2CH_2WAY" - "sof-tgl-max98357a-rt5682\;sof-adl-max98357a-rt5682-waves-2way\;-DCODEC=MAX98360A_TDM\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=2\;-D2CH_2WAY\;-DWAVES" - "sof-tgl-max98357a-rt5682\;sof-adl-max98357a-rt5682-4ch\;-DCODEC=MAX98360A_TDM\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=2\;-D4CH_PASSTHROUGH" - "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-rt5682\;-DCODEC=MAX98360A\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DBT_OFFLOAD\;-DSPK_MIC_PERIOD_US=10000" - "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-rt5682-waves\;-DCODEC=MAX98360A\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DWAVES" - "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-rt5682-waves-spk-only\;-DCODEC=MAX98360A\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DWAVES\;-DWAVES_SPK_ONLY" - "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-rt5682-2way\;-DCODEC=MAX98360A_TDM\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-D2CH_2WAY\;-DBT_OFFLOAD" - "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-rt5682-2way-pdm1\;-DCODEC=MAX98360A_TDM\;-DFMT=s32le\;-DDMIC_DAI_LINK_16k_PDM=STEREO_PDM1\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-D2CH_2WAY\;-DBT_OFFLOAD" - "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-rt5682-4ch\;-DCODEC=MAX98360A_TDM\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-D4CH_PASSTHROUGH\;-DBT_OFFLOAD" - "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-rt5682-rtnr\;-DCODEC=MAX98360A\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DCHANNELS=2\;-DRTNR" - "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-rt5682-rtnr-google-aec\;-DCODEC=MAX98360A\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DCHANNELS=2\;-DGOOGLE_RTC_AUDIO_PROCESSING\;-DRTNR\;-DNOHOTWORD\;-DNO16KDMIC" - "sof-tgl-max98357a-rt5682\;sof-tgl-max98357a-rt5682-pdm1\;-DCODEC=MAX98357A\;-DFMT=s16le\;-DDMIC_DAI_LINK_16k_PDM=STEREO_PDM1\;-DPLATFORM=tgl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1" - "sof-tgl-max98357a-rt5682\;sof-tgl-max98357a-rt5682-pdm1-google-aec\;-DCODEC=MAX98357A\;-DFMT=s16le\;-DDMIC_DAI_LINK_16k_PDM=STEREO_PDM1\;-DPLATFORM=tgl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DCHANNELS=2\;-DGOOGLE_RTC_AUDIO_PROCESSING" - "sof-tgl-max98357a-rt5682\;sof-tgl-max98357a-rt5682-pdm1-drceq\;-DCODEC=MAX98357A\;-DFMT=s16le\;-DDMIC_DAI_LINK_16k_PDM=STEREO_PDM1\;-DPLATFORM=tgl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DDRC_EQ" - "sof-tgl-max98357a-rt5682\;sof-tgl-rt1011-rt5682\;-DCODEC=RT1011\;-DFMT=s24le\;-DPLATFORM=tgl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1" - "sof-tgl-max98357a-rt5682\;sof-tgl-max98357a-rt5682-rtnr\;-DCODEC=MAX98357A\;-DFMT=s16le\;-DPLATFORM=tgl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DCHANNELS=2\;-DRTNR" - "sof-tgl-max98357a-rt5682\;sof-adl-max98390-rt5682\;-DCODEC=MAX98390\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DBT_OFFLOAD" - "sof-tgl-max98357a-rt5682\;sof-adl-max98390-rt5682-rtnr\;-DCODEC=MAX98390\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DBT_OFFLOAD\;-DCHANNELS=2\;-DRTNR\;-DNOHOTWORD\;-DDMICPROC=rtnr\;-DNO16KDMIC\;-DDMIC_48k_CORE_ID=1" - "sof-tgl-max98357a-rt5682\;sof-adl-max98390-rt5682-google-aec\;-DCODEC=MAX98390\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DBT_OFFLOAD\;-DCHANNELS=2\;-DGOOGLE_RTC_AUDIO_PROCESSING\;-DNOHOTWORD\;-DNO16KDMIC" - "sof-tgl-max98357a-rt5682\;sof-adl-max98390-rt5682-rtnr-google-aec\;-DCODEC=MAX98390\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DBT_OFFLOAD\;-DCHANNELS=2\;-DGOOGLE_RTC_AUDIO_PROCESSING\;-DRTNR\;-DNOHOTWORD\;-DNO16KDMIC\;-DSPK_MIC_PERIOD_US=10000" - "sof-tgl-max98357a-rt5682\;sof-adl-max98390-ssp2-rt5682-ssp0\;-DCODEC=MAX98390\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=2" - "sof-tgl-max98357a-rt5682\;sof-adl-rt5682\;-DNO_AMP\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682" - "sof-tgl-max98357a-rt5682\;sof-adl-rt1019-rt5682\;-DCODEC=RT1019\;-DFMT=s24le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DSPK_MIC_PERIOD_US=10000\;-DBT_OFFLOAD" - "sof-tgl-max98357a-rt5682\;sof-adl-rt1019-rt5682-waves\;-DCODEC=RT1019\;-DFMT=s24le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DWAVES\;-DBT_OFFLOAD" - "sof-tgl-max98357a-rt5682\;sof-adl-cs35l41\;-DCODEC=CS35L41\;-DFMT=s24le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_ssp_amp\;-DAMP_SSP=1\;-DBT_OFFLOAD\;-DNO_HEADPHONE" - "sof-tgl-max98357a-rt5682\;sof-adl-cs35l41-waves\;-DCODEC=CS35L41\;-DFMT=s24le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_ssp_amp\;-DAMP_SSP=1\;-DBT_OFFLOAD\;-DNO_HEADPHONE\;-DWAVES\;-DNOHOTWORD\;-DNO16KDMIC" - "sof-tgl-max98357a-rt5682\;sof-adl-cs35l41-google-aec-waves\;-DCODEC=CS35L41\;-DFMT=s24le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_ssp_amp\;-DAMP_SSP=1\;-DBT_OFFLOAD\;-DNO_HEADPHONE\;-DGOOGLE_RTC_AUDIO_PROCESSING\;-DWAVES\;-DNOHOTWORD\;-DNO16KDMIC\;-DSPK_MIC_PERIOD_US=10000" - "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-da7219\;-DUSE_DA7219\;-DCODEC=MAX98360A\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DBT_OFFLOAD\;-DSPK_MIC_PERIOD_US=10000\;-DNOHOTWORD\;-DNO16KDMIC" - "sof-tgl-max98357a-rt5682\;sof-adl-rt5650\;-DUSE_RT5650\;-DFMT=s24le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DSPK_MIC_PERIOD_US=10000\;-DBT_OFFLOAD\;-DNOHOTWORD\;-DNO16KDMIC" - "sof-tgl-max98373-rt5682\;sof-tgl-max98373-rt5682\;-DAMP_SSP=1" - "sof-tgl-max98373-rt5682\;sof-tgl-max98373-rt5682-igonr\;-DAMP_SSP=1\;-DIGO" - "sof-tgl-max98373-rt5682\;sof-tgl-max98373-rt5682-xperi\;-DAMP_SSP=1\;-DINCLUDE_IIR_EQ=1" - "sof-tgl-max98373-rt5682\;sof-tgl-rt5682-ssp0-max98373-ssp2\;-DAMP_SSP=2" - "sof-tgl-max98373-rt5682\;sof-tgl-rt5682-ssp0-max98373-ssp2-xperi\;-DAMP_SSP=2\;-DINCLUDE_IIR_EQ=1" - "sof-adl-nau8825\;sof-adl-nau8825\;-DNO_AMP\;-DBT_OFFLOAD" - "sof-adl-nau8825\;sof-adl-max98373-nau8825\;-DAMP_SSP=1\;-DSMART_AMP\;-DBT_OFFLOAD\;-DNOHOTWORD\;-DNO16KDMIC" - "sof-adl-nau8825\;sof-adl-max98373-nau8825-dts\;-DAMP_SSP=1\;-DSMART_AMP\;-DBT_OFFLOAD\;-DNOHOTWORD\;-DNO16KDMIC\;-DDTS=`DTS'" - "sof-adl-nau8825\;sof-adl-max98360a-nau8825\;-DCODEC=MAX98360A\;-DFMT=s16le\;-DAMP_SSP=1\;-DBT_OFFLOAD\;-DSPK_MIC_PERIOD_US=10000" - "sof-adl-nau8825\;sof-adl-rt1019-nau8825\;-DCODEC=RT1019P\;-DFMT=s16le\;-DAMP_SSP=2\;-DSPK_MIC_PERIOD_US=10000" - "sof-adl-nau8825\;sof-adl-rt1015-nau8825\;-DCODEC=RT1015P\;-DFMT=s32le\;-DAMP_SSP=1\;-DBT_OFFLOAD\;-DSPK_MIC_PERIOD_US=10000" - "sof-adl-nau8825\;sof-adl-nau8318-nau8825\;-DCODEC=NAU8318\;-DFMT=s16le\;-DAMP_SSP=1\;-DBT_OFFLOAD\;-DSPK_MIC_PERIOD_US=10000" - "sof-tgl-sdw-max98373-rt5682\;sof-tgl-sdw-max98373-rt5682\;-DCHANNELS=4\;-DPLATFORM=tgl" - "sof-tgl-sdw-max98373-rt5682\;sof-adl-sdw-max98373-rt5682\;-DCHANNELS=4\;-DPLATFORM=adl" - "sof-smart-amplifier-nocodec\;sof-smart-amplifier-nocodec" - - "sof-glk-es8336\;sof-tgl-es8336\;-DPLATFORM=tgl\;-DSSP_NUM=0\;-DCHANNELS=2" - "sof-glk-es8336\;sof-tgl-es8336-ssp0\;-DPLATFORM=tgl\;-DSSP_NUM=0\;-DCHANNELS=0" - "sof-glk-es8336\;sof-tgl-es8336-ssp1\;-DPLATFORM=tgl\;-DSSP_NUM=1\;-DCHANNELS=0" - "sof-glk-es8336\;sof-tgl-es8336-ssp2\;-DPLATFORM=tgl\;-DSSP_NUM=2\;-DCHANNELS=0" - "sof-glk-es8336\;sof-tgl-es8336-dmic2ch-ssp0\;-DPLATFORM=tgl\;-DSSP_NUM=0\;-DCHANNELS=2" - "sof-glk-es8336\;sof-tgl-es8336-dmic2ch-ssp1\;-DPLATFORM=tgl\;-DSSP_NUM=1\;-DCHANNELS=2" - "sof-glk-es8336\;sof-tgl-es8336-dmic2ch-ssp2\;-DPLATFORM=tgl\;-DSSP_NUM=2\;-DCHANNELS=2" - "sof-glk-es8336\;sof-tgl-es8336-dmic4ch-ssp0\;-DPLATFORM=tgl\;-DSSP_NUM=0\;-DCHANNELS=4" - "sof-glk-es8336\;sof-tgl-es8336-dmic4ch-ssp1\;-DPLATFORM=tgl\;-DSSP_NUM=1\;-DCHANNELS=4" - "sof-glk-es8336\;sof-tgl-es8336-dmic4ch-ssp2\;-DPLATFORM=tgl\;-DSSP_NUM=2\;-DCHANNELS=4" - - "sof-glk-es8336\;sof-adl-es8336\;-DPLATFORM=adl\;-DSSP_NUM=0\;-DCHANNELS=2" - "sof-glk-es8336\;sof-adl-es8336-ssp0\;-DPLATFORM=adl\;-DSSP_NUM=0\;-DCHANNELS=0" - "sof-glk-es8336\;sof-adl-es8336-ssp1\;-DPLATFORM=adl\;-DSSP_NUM=1\;-DCHANNELS=0" - "sof-glk-es8336\;sof-adl-es8336-ssp2\;-DPLATFORM=adl\;-DSSP_NUM=2\;-DCHANNELS=0" - "sof-glk-es8336\;sof-adl-es8336-dmic2ch-ssp0\;-DPLATFORM=adl\;-DSSP_NUM=0\;-DCHANNELS=2" - "sof-glk-es8336\;sof-adl-es8336-dmic2ch-ssp1\;-DPLATFORM=adl\;-DSSP_NUM=1\;-DCHANNELS=2" - "sof-glk-es8336\;sof-adl-es8336-dmic2ch-ssp2\;-DPLATFORM=adl\;-DSSP_NUM=2\;-DCHANNELS=2" - "sof-glk-es8336\;sof-adl-es8336-dmic4ch-ssp0\;-DPLATFORM=adl\;-DSSP_NUM=0\;-DCHANNELS=4" - "sof-glk-es8336\;sof-adl-es8336-dmic4ch-ssp1\;-DPLATFORM=adl\;-DSSP_NUM=1\;-DCHANNELS=4" - "sof-glk-es8336\;sof-adl-es8336-dmic4ch-ssp2\;-DPLATFORM=adl\;-DSSP_NUM=2\;-DCHANNELS=4" - - #sof-adl-es8336-ssp1-hdmi-ssp02 supports es8336 codec along with 2xHDMI_over_SSP Capture's. - "sof-glk-es8336\;sof-adl-es8336-ssp1-hdmi-ssp02\;-DPLATFORM=adl\;-DSSP_NUM=1\;-DCHANNELS=0\;-DHDMI_1_SSP_NUM=0\;-DHDMI_2_SSP_NUM=2" - - #To support HDMI-in capture with RT1308 ssp-amplifier products. - "sof-tgl-rt1308-hdmi-ssp\;sof-tgl-rt1308-ssp2-hdmi-ssp15\;-DAMP_SSP_NUM=2\;-DHDMI_1_SSP_NUM=1\;-DHDMI_2_SSP_NUM=5\;-DPLATFORM=tgl" - #Topologies for No SSP-amp or codec+HDMI-IN capture support. - "sof-tgl-rt1308-hdmi-ssp\;sof-tgl-nocodec-hdmi-ssp15\;-DNO_AMP\;-DHDMI_1_SSP_NUM=1\;-DHDMI_2_SSP_NUM=5\;-DPLATFORM=tgl" - "sof-tgl-rt1308-hdmi-ssp\;sof-adl-nocodec-hdmi-ssp02\;-DNO_AMP\;-DHDMI_1_SSP_NUM=0\;-DHDMI_2_SSP_NUM=2\;-DPLATFORM=adl" - ## i.MX8 (i.MX8QM and i.MX8QXP) topologies "sof-imx8-nocodec\;sof-imx8-nocodec" "sof-imx8-wm8960-cs42888\;sof-imx8-wm8960-cs42888" @@ -186,6 +46,7 @@ set(TPLGS "sof-imx8-wm8960-mixer\;sof-imx8mp-wm8960-mixer\;-DCODEC=wm8960\;-DRATE=48000\;-DSAI_INDEX=3" "sof-imx8-wm8960-mixer\;sof-imx8mp-wm8962-mixer\;-DCODEC=wm8962\;-DRATE=48000\;-DSAI_INDEX=3" "sof-imx8mp-wm8960-kwd\;sof-imx8mp-wm8960-kwd" + "sof-imx8mp-micfil\;sof-imx8mp-micfil" "sof-imx8mp-btsco-dual-8ch\;sof-imx8mp-btsco-dual-8ch" "sof-imx8-wm8960\;sof-imx8mp-wm8960\;-DCODEC=wm8960\;-DRATE=48000\;-DPPROC=volume\;-DSAI_INDEX=3" "sof-imx8-wm8960\;sof-imx8mp-wm8904\;-DCODEC=wm8904\;-DRATE=44100\;-DPPROC=volume\;-DSAI_INDEX=3" @@ -222,13 +83,14 @@ set(TPLGS "sof-rn-rt5682-rt1019\;sof-rn-rt5682-rt1019" "sof-rn-rt5682-rt1019\;sof-rn-rt5682-rt1019-dts\;-DDTS=`DTS'" "sof-rn-rt5682-max98360\;sof-rn-rt5682-max98360" - "sof-acp-rmb\;sof-acp-rmb" "sof-acp-vangogh\;sof-vangogh-nau8821-max" + "sof-acp-rmb\;sof-acp-rmb" "sof-acp-rmb-dmic4ch\;sof-acp-rmb-dmic4ch" "sof-acp-rmb-tdm8ch-dmic4ch-rt5682-rt1019\;sof-acp-rmb-tdm8ch-dmic4ch-rt5682-rt1019" "sof-acp-rmb-tdm8ch-dmic2ch-nau8825-max98360\;sof-acp-rmb-tdm8ch-dmic2ch-nau8825-max98360" "sof-acp-rmb\;sof-rmb-rt5682s-rt1019" "sof-acp-rmb\;sof-rmb-nau8825-max98360" + "sof-acp_6_3\;sof-acp_6_3" ) # This empty 'production/' source subdirectory exists only to create the @@ -288,5 +150,3 @@ foreach(tplg ${TPLGS}) endforeach() add_subdirectory(development) -add_subdirectory(dsp_enhancement) -add_subdirectory(kernel_dependent) diff --git a/tools/topology/topology1/development/CMakeLists.txt b/tools/topology/topology1/development/CMakeLists.txt index 37b4b956afbc..288820b73d94 100644 --- a/tools/topology/topology1/development/CMakeLists.txt +++ b/tools/topology/topology1/development/CMakeLists.txt @@ -19,40 +19,9 @@ set(TPLGS "sof-imx8mp-compr-wm8960\;sof-imx8mp-compr-wm8960\;-DCODEC=wm8960\;-DRATE=48000" "sof-imx8mp-compr-wm8960\;sof-imx8mp-compr-wm8962\;-DCODEC=wm8962\;-DRATE=48000" ## end i.MX8MP topologies - - "sof-hda-asrc\;sof-hda-asrc-2ch\;-DCHANNELS=2" - "sof-tgl-nocodec-ci\;sof-tgl-nocodec-ci" - "sof-tgl-nocodec-ci\;sof-adl-nocodec-ci" - "sof-tgl-nocodec-mux\;sof-tgl-nocodec-mux" - "sof-tgl-nocodec-crossover-4way\;sof-tgl-nocodec-crossover-4way" - "sof-tgl-nocodec-crossover-2way\;sof-tgl-nocodec-crossover-2way" - "sof-hda-generic-kwd\;sof-hda-generic-2ch-kwd\;-DCHANNELS=2\;-DDYNAMIC=1" - "sof-hda-generic-kwd\;sof-hda-generic-4ch-kwd\;-DCHANNELS=4\;-DDYNAMIC=1" ) -# The topologies those are built from topology in the parent directory -set(TPLGS_UP - "sof-hda-generic\;sof-hda-generic-tdfb_50mm-2ch\;-DCHANNELS=2\;-DHSPROC=volume\;-DDMIC16KPROC=tdfb-eq-iir-volume\;-DDMIC16KPROC_FILTER1=tdfb/coef_line2_50mm_azm90_90_13el0_0_13deg_16khz.m4\;-DDMICPROC=tdfb-eq-iir-volume\;-DDMICPROC_FILTER1=tdfb/coef_line2_50mm_azm90_90_13el0_0_13deg_48khz.m4\;-DDMICPROC_FILTER2=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER2=eq_iir_coef_highpass_40hz_20db_16khz.m4" - "sof-hda-generic\;sof-hda-generic-tdfb_68mm-2ch\;-DCHANNELS=2\;-DHSPROC=volume\;-DDMIC16KPROC=tdfb-eq-iir-volume\;-DDMIC16KPROC_FILTER1=tdfb/coef_line2_68mm_azm90_90_13el0_0_13deg_16khz.m4\;-DDMICPROC=tdfb-eq-iir-volume\;-DDMICPROC_FILTER1=tdfb/coef_line2_68mm_azm90_90_13el0_0_13deg_48khz.m4\;-DDMICPROC_FILTER2=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER2=eq_iir_coef_highpass_40hz_20db_16khz.m4" - "sof-hda-generic\;sof-hda-generic-tdfb_0mm36mm146mm182mm-4ch\;-DCHANNELS=2\;-DHSPROC=volume\;-DDMIC16KPROC=tdfb-eq-iir-volume\;-DDMIC16KPROC_FILTER1=tdfb/coef_line4_0mm36mm146mm182mm_azm90_90_13el0_0_13deg_16khz.m4\;-DDMICPROC=tdfb-eq-iir-volume\;-DDMICPROC_FILTER1=tdfb/coef_line4_0mm36mm146mm182mm_azm90_90_13el0_0_13deg_48khz.m4\;-DDMICPROC_FILTER2=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER2=eq_iir_coef_highpass_40hz_20db_16khz.m4" - "sof-hda-generic\;sof-hda-generic-iir\;-DCHANNELS=0\;-DHSPROC=eq-iir-volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DHSPROC_FILTER1=eq_iir_coef_pass.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-iir-2ch\;-DCHANNELS=2\;-DHSPROC=eq-iir-volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DHSPROC_FILTER1=eq_iir_coef_pass.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-iir-4ch\;-DCHANNELS=4\;-DHSPROC=eq-iir-volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DHSPROC_FILTER1=eq_iir_coef_pass.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-iir-fir\;-DCHANNELS=0\;-DHSPROC=eq-iir-eq-fir-volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DHSPROC_FILTER1=eq_iir_coef_pass.m4\;-DHSPROC_FILTER2=eq_fir_coef_pass.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-iir-fir-2ch\;-DCHANNELS=2\;-DHSPROC=eq-iir-eq-fir-volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DHSPROC_FILTER1=eq_iir_coef_pass.m4\;-DHSPROC_FILTER2=eq_fir_coef_pass.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-iir-fir-4ch\;-DCHANNELS=4\;-DHSPROC=eq-iir-eq-fir-volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DHSPROC_FILTER1=eq_iir_coef_pass.m4\;-DHSPROC_FILTER2=eq_fir_coef_pass.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-multiband-drc\;-DCHANNELS=0\;-DHSPROC=multiband-drc\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-2ch-multiband-drc\;-DCHANNELS=2\;-DHSPROC=multiband-drc\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-drc\;-DCHANNELS=0\;-DHSPROC=drc\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-2ch-drc\;-DCHANNELS=2\;-DHSPROC=drc\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-2ch-mfcc\;-DCHANNELS=2\;-DHSPROC=volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1\;-DDMIC16KPROC=eq-iir-mfcc" - "sof-tgl-rt711-rt1308\;sof-tgl-sdw-max98373-rt5682-dmic4ch-ampref\;-DCHANNELS=4\;-DEXT_AMP\;-DEXT_AMP_REF\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=tgl" - "sof-hda-generic\;sof-hda-generic-src\;-DCHANNELS=0\;-DHSSFX=src-volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4" - "sof-hda-generic\;sof-hda-generic-2ch-src\;-DCHANNELS=2\;-DHSSFX=src-volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4" - "sof-hda-generic\;sof-hda-generic-4ch-src\;-DCHANNELS=4\;-DHSSFX=src-volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4" -) - add_custom_target(dev_topologies1 ALL) foreach(tplg ${TPLGS}) @@ -90,38 +59,3 @@ foreach(tplg ${TPLGS}) add_custom_target(dev_topology_${output} DEPENDS ${output}.tplg) add_dependencies(dev_topologies1 dev_topology_${output}) endforeach() - -# Duplicate of above to handle topologies in parent directory -foreach(tplg ${TPLGS_UP}) - list(GET tplg 0 input) - list(GET tplg 1 output) - list(LENGTH tplg tplg_len) - math(EXPR num_args "${tplg_len} - 1") - set(DEFINES "") - if (${num_args} GREATER 1) - foreach(index RANGE 2 ${num_args}) - list(GET tplg ${index} custom_define) - list(APPEND DEFINES ${custom_define}) - endforeach() - endif() - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${output}.conf - COMMAND m4 --fatal-warnings - ${DEFINES} - -I ${CMAKE_CURRENT_SOURCE_DIR}/../m4 - -I ${CMAKE_CURRENT_SOURCE_DIR}/../common - -I ${CMAKE_CURRENT_SOURCE_DIR}/../platform/common - -I ${CMAKE_CURRENT_SOURCE_DIR}/../ - -I ${CMAKE_CURRENT_BINARY_DIR}/../ - ${CMAKE_CURRENT_SOURCE_DIR}/../common/abi.m4 - ${CMAKE_CURRENT_SOURCE_DIR}/../${input}.m4 - > ${output}.conf - DEPENDS abi_v1 ${CMAKE_BINARY_DIR}/topology/topology1/abi.h - VERBATIM - USES_TERMINAL - ) - add_alsatplg_command(${output}.conf ${output}.tplg) - - add_custom_target(topology_${output} DEPENDS ${output}.tplg) - add_dependencies(dev_topologies1 topology_${output}) -endforeach() diff --git a/tools/topology/topology1/development/sof-hda-asrc.m4 b/tools/topology/topology1/development/sof-hda-asrc.m4 deleted file mode 100644 index d91fb862c3ad..000000000000 --- a/tools/topology/topology1/development/sof-hda-asrc.m4 +++ /dev/null @@ -1,202 +0,0 @@ -# -# Topology for SKL+ HDA for testing ASRC -# - -# if XPROC is not defined, define with default pipe -ifdef(`DMICPROC', , `define(DMICPROC, eq-iir-volume)') -ifdef(`DMIC16KPROC', , `define(DMIC16KPROC, eq-iir-volume)') - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`hda.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include bxt DSP configuration -include(`platform/intel/bxt.m4') - -DEBUG_START - -# Define pipeline id for intel-generic-dmic.m4 -# to generate dmic setting - -ifelse(CHANNELS, `0', , -` -define(DMIC_PCM_48k_ID, `6') -define(DMIC_PCM_16k_ID, `7') -define(DMIC_DAI_LINK_48k_ID, `6') -define(DMIC_DAI_LINK_16k_ID, `7') -define(DMIC_PIPELINE_48k_ID, `10') -define(DMIC_PIPELINE_16k_ID, `11') - -include(`platform/intel/intel-generic-dmic.m4') -' -) - -# -# Define the pipelines -# -# PCM0 <---> volume (pipe 1,2) <----> HDA Analog (HDA Analog playback/capture) -# PCM1 <---> volume (pipe 3,4) <----> HDA Digital (HDA Digital playback/capture) -# PCM3 ----> volume (pipe 7) -----> iDisp1 (HDMI/DP playback, BE link 3) -# PCM4 ----> Volume (pipe 8) -----> iDisp2 (HDMI/DP playback, BE link 4) -# PCM5 ----> volume (pipe 9) -----> iDisp3 (HDMI/DP playback, BE link 5) -# - -# Low Latency playback pipeline 1 on PCM 0 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-asrc-volume-playback.m4, - 1, 0, 2, s24le, - 1000, 0, 0, - 8000, 48000, 48000) - -# Low Latency capture pipeline 2 on PCM 0 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-asrc-volume-capture.m4, - 2, 0, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 3 on PCM 1 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 3, 1, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency capture pipeline 4 on PCM 1 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, - 4, 1, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 7 on PCM 3 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 7, 3, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 8 on PCM 4 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 8, 4, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 9 on PCM 5 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 9, 5, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# -# DAIs configuration -# - -# playback DAI is HDA Analog using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 1, HDA, 0, Analog Playback and Capture, - PIPELINE_SOURCE_1, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is HDA Analog using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 2, HDA, 1, Analog Playback and Capture, - PIPELINE_SINK_2, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is HDA Digital using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 3, HDA, 2, Digital Playback and Capture, - PIPELINE_SOURCE_3, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is HDA Digital using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 4, HDA, 3, Digital Playback and Capture, - PIPELINE_SINK_4, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp1 using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 7, HDA, 4, iDisp1, - PIPELINE_SOURCE_7, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 8, HDA, 5, iDisp2, - PIPELINE_SOURCE_8, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 9, HDA, 6, iDisp3, - PIPELINE_SOURCE_9, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -PCM_DUPLEX_ADD(HDA Analog, 0, PIPELINE_PCM_1, PIPELINE_PCM_2) -PCM_DUPLEX_ADD(HDA Digital, 1, PIPELINE_PCM_3, PIPELINE_PCM_4) -PCM_PLAYBACK_ADD(HDMI1, 3, PIPELINE_PCM_7) -PCM_PLAYBACK_ADD(HDMI2, 4, PIPELINE_PCM_8) -PCM_PLAYBACK_ADD(HDMI3, 5, PIPELINE_PCM_9) - -# -# BE configurations - overrides config in ACPI if present -# - -# HDA outputs -DAI_CONFIG(HDA, 0, 4, Analog Playback and Capture, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 0, 48000, 2))) -DAI_CONFIG(HDA, 1, 5, Digital Playback and Capture, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 1, 48000, 2))) -# 3 HDMI/DP outputs (ID: 3,4,5) -DAI_CONFIG(HDA, 4, 1, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 4, 48000, 2))) -DAI_CONFIG(HDA, 5, 2, iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 5, 48000, 2))) -DAI_CONFIG(HDA, 6, 3, iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 6, 48000, 2))) - - -VIRTUAL_DAPM_ROUTE_IN(codec0_in, HDA, 1, IN, 1) -VIRTUAL_DAPM_ROUTE_IN(codec1_in, HDA, 3, IN, 2) -VIRTUAL_DAPM_ROUTE_OUT(codec0_out, HDA, 0, OUT, 3) -VIRTUAL_DAPM_ROUTE_OUT(codec1_out, HDA, 2, OUT, 4) - -# codec2 is not supported in dai links but it exists -# in dapm routes, so hack this one to HDA1 -VIRTUAL_DAPM_ROUTE_IN(codec2_in, HDA, 3, IN, 5) -VIRTUAL_DAPM_ROUTE_OUT(codec2_out, HDA, 2, OUT, 6) - -VIRTUAL_DAPM_ROUTE_OUT(iDisp1_out, HDA, 4, OUT, 7) -VIRTUAL_DAPM_ROUTE_OUT(iDisp2_out, HDA, 5, OUT, 8) -VIRTUAL_DAPM_ROUTE_OUT(iDisp3_out, HDA, 6, OUT, 9) - -VIRTUAL_WIDGET(iDisp3 Tx, out_drv, 0) -VIRTUAL_WIDGET(iDisp2 Tx, out_drv, 1) -VIRTUAL_WIDGET(iDisp1 Tx, out_drv, 2) -VIRTUAL_WIDGET(Analog CPU Playback, out_drv, 3) -VIRTUAL_WIDGET(Digital CPU Playback, out_drv, 4) -VIRTUAL_WIDGET(Alt Analog CPU Playback, out_drv, 5) -VIRTUAL_WIDGET(Analog CPU Capture, input, 6) -VIRTUAL_WIDGET(Digital CPU Capture, input, 7) -VIRTUAL_WIDGET(Alt Analog CPU Capture, input, 8) - -DEBUG_END diff --git a/tools/topology/topology1/development/sof-hda-generic-kwd.m4 b/tools/topology/topology1/development/sof-hda-generic-kwd.m4 deleted file mode 100644 index 284aa7a6f37d..000000000000 --- a/tools/topology/topology1/development/sof-hda-generic-kwd.m4 +++ /dev/null @@ -1,203 +0,0 @@ -# Topology for SKL+ HDA Generic machine -# - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`hda.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include bxt DSP configuration -include(`platform/intel/bxt.m4') - - - - - -# -# Define the pipelines -# -# PCM0 <---> volume (pipe 1,2) <----> HDA Analog (HDA Analog playback/capture) -# PCM1 <---> volume (pipe 3,4) <----> HDA Digital (HDA Digital playback/capture) -# PCM3 ----> volume (pipe 7) -----> iDisp1 (HDMI/DP playback, BE link 3) -# PCM4 ----> Volume (pipe 8) -----> iDisp2 (HDMI/DP playback, BE link 4) -# PCM5 ----> volume (pipe 9) -----> iDisp3 (HDMI/DP playback, BE link 5) -# PCM6 <---- Volume (pipe 10) <----- DMIC01 -# PCM7 <---- KWD (pipe 11/12) <----- DMIC16K (KWD) -# - -# Define pipeline id for intel-generic-dmic-kwd.m4 -# to generate dmic setting with kwd when we have dmic -# define kfbm without volume -# define pcm to 6,7, pipeline to 10,11,12 and dai id to 6,7 -ifelse(CHANNELS, `0', , -` -define(KFBM_TYPE, `vol-kfbm') -define(DMIC_PCM_48k_ID, `6') -define(DMIC_PCM_16k_ID, `7') -define(DMIC_PIPELINE_48k_ID, `10') -define(DMIC_PIPELINE_16k_ID, `11') -define(DMIC_PIPELINE_KWD_ID, `12') -define(DMIC_DAI_LINK_48k_ID, `6') -define(DMIC_DAI_LINK_16k_ID, `7') -define(KWD_PIPE_SCH_DEADLINE_US, 20000) - -include(`platform/intel/intel-generic-dmic-kwd.m4') -' -) - -# Low Latency playback pipeline 1 on PCM 0 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 1, 0, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency capture pipeline 2 on PCM 0 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, - 2, 0, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 3 on PCM 1 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 3, 1, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency capture pipeline 4 on PCM 1 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, - 4, 1, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 7 on PCM 3 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 7, 3, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 8 on PCM 4 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 8, 4, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 9 on PCM 5 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 9, 5, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# -# DAIs configuration -# - -# playback DAI is HDA Analog using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 1, HDA, 0, Analog Playback and Capture, - PIPELINE_SOURCE_1, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is HDA Analog using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 2, HDA, 1, Analog Playback and Capture, - PIPELINE_SINK_2, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is HDA Digital using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 3, HDA, 2, Digital Playback and Capture, - PIPELINE_SOURCE_3, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is HDA Digital using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 4, HDA, 3, Digital Playback and Capture, - PIPELINE_SINK_4, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp1 using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 7, HDA, 4, iDisp1, - PIPELINE_SOURCE_7, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 8, HDA, 5, iDisp2, - PIPELINE_SOURCE_8, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 9, HDA, 6, iDisp3, - PIPELINE_SOURCE_9, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -PCM_DUPLEX_ADD(HDA Analog, 0, PIPELINE_PCM_1, PIPELINE_PCM_2) -PCM_DUPLEX_ADD(HDA Digital, 1, PIPELINE_PCM_3, PIPELINE_PCM_4) -PCM_PLAYBACK_ADD(HDMI1, 3, PIPELINE_PCM_7) -PCM_PLAYBACK_ADD(HDMI2, 4, PIPELINE_PCM_8) -PCM_PLAYBACK_ADD(HDMI3, 5, PIPELINE_PCM_9) - -# -# BE configurations - overrides config in ACPI if present -# - -# HDA outputs -DAI_CONFIG(HDA, 0, 4, Analog Playback and Capture, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 0, 48000, 2))) -DAI_CONFIG(HDA, 1, 5, Digital Playback and Capture, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 1, 48000, 2))) -# 3 HDMI/DP outputs (ID: 3,4,5) -DAI_CONFIG(HDA, 4, 1, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 4, 48000, 2))) -DAI_CONFIG(HDA, 5, 2, iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 5, 48000, 2))) -DAI_CONFIG(HDA, 6, 3, iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 6, 48000, 2))) - - -VIRTUAL_DAPM_ROUTE_IN(codec0_in, HDA, 1, IN, 1) -VIRTUAL_DAPM_ROUTE_IN(codec1_in, HDA, 3, IN, 2) -VIRTUAL_DAPM_ROUTE_OUT(codec0_out, HDA, 0, OUT, 3) -VIRTUAL_DAPM_ROUTE_OUT(codec1_out, HDA, 2, OUT, 4) - -# codec2 is not supported in dai links but it exists -# in dapm routes, so hack this one to HDA1 -VIRTUAL_DAPM_ROUTE_IN(codec2_in, HDA, 3, IN, 5) -VIRTUAL_DAPM_ROUTE_OUT(codec2_out, HDA, 2, OUT, 6) - -VIRTUAL_DAPM_ROUTE_OUT(iDisp1_out, HDA, 4, OUT, 7) -VIRTUAL_DAPM_ROUTE_OUT(iDisp2_out, HDA, 5, OUT, 8) -VIRTUAL_DAPM_ROUTE_OUT(iDisp3_out, HDA, 6, OUT, 9) - -VIRTUAL_WIDGET(iDisp3 Tx, out_drv, 0) -VIRTUAL_WIDGET(iDisp2 Tx, out_drv, 1) -VIRTUAL_WIDGET(iDisp1 Tx, out_drv, 2) -VIRTUAL_WIDGET(Analog CPU Playback, out_drv, 3) -VIRTUAL_WIDGET(Digital CPU Playback, out_drv, 4) -VIRTUAL_WIDGET(Alt Analog CPU Playback, out_drv, 5) -VIRTUAL_WIDGET(Analog CPU Capture, input, 6) -VIRTUAL_WIDGET(Digital CPU Capture, input, 7) -VIRTUAL_WIDGET(Alt Analog CPU Capture, input, 8) diff --git a/tools/topology/topology1/development/sof-tgl-nocodec-ci.m4 b/tools/topology/topology1/development/sof-tgl-nocodec-ci.m4 deleted file mode 100644 index c53242f9a73d..000000000000 --- a/tools/topology/topology1/development/sof-tgl-nocodec-ci.m4 +++ /dev/null @@ -1,280 +0,0 @@ -# -# Topology for Tigerlake RVP board CI testing, with covering as more -# features as possible running with no codec machine. -# -# TGL Host GW DMAC support max 6 playback and max 6 capture channels so some -# pipelines/PCMs/DAIs are commented out to keep within HW bounds. If these -# are needed then they can be used provided other PCMs/pipelines/SSPs are -# commented out in their place. - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`ssp.m4') -include(`muxdemux.m4') -include(`pipeline.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include Tigerlake DSP configuration -include(`platform/intel/tgl.m4') -include(`platform/intel/dmic.m4') - - -# -# Define the demux configure -# -dnl Configure demux -dnl name, pipeline_id, routing_matrix_rows -dnl Diagonal 1's in routing matrix mean that every input channel is -dnl copied to corresponding output channels in all output streams. -dnl I.e. row index is the input channel, 1 means it is copied to -dnl corresponding output channel (column index), 0 means it is discarded. -dnl There's a separate matrix for all outputs. -define(matrix1, `ROUTE_MATRIX(1, - `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 1 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,1 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,1 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,1 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,1 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,1)')') - -define(matrix2, `ROUTE_MATRIX(7, - `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 1 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,1 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,1 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,1 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,1 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,1)')') - -dnl name, num_streams, route_matrix list -MUXDEMUX_CONFIG(demux_priv_1, 2, LIST_NONEWLINE(`', `matrix1,', `matrix2')) - -# -# Define the pipelines -# -# PCM0 --> volume --> demux --> SSP0 -# | | -# PCM3 <----------------+ | -# PCM0 <-------------------------+ -# PCM1 <---> Volume <----> SSP1 -# PCM2 ----> smart_amp ----> SSP(SSP_INDEX) -# ^ -# | -# | -# PCM2 <---- demux <----- SSP(SSP_INDEX) -# PCM4 <---- volume <---- DMIC01 (dmic 48k capture) -# PCM5 <---- volume <---- DMIC16k (dmic 16k capture) -# - -# Smart amplifier related -# SSP related -#define smart amplifier SSP index -define(`SMART_SSP_INDEX', 2) -#define SSP BE dai_link name -define(`SMART_SSP_NAME', `NoCodec-2') -#define BE dai_link ID -define(`SMART_BE_ID', 2) -#define SSP QUIRK -define(`SMART_SSP_QUIRK', `SSP_QUIRK_LBM') -#define SSP_MCLK -define(`SSP_MCLK', 38400000) - -# Playback related -define(`SMART_PB_PPL_ID', 5) -define(`SMART_PB_CH_NUM', 2) -define(`SMART_TX_CHANNELS', 4) -define(`SMART_RX_CHANNELS', 8) -define(`SMART_FB_CHANNELS', 8) -# Ref capture related -define(`SMART_REF_PPL_ID', 6) -define(`SMART_REF_CH_NUM', 4) -# PCM related -define(`SMART_PCM_ID', 2) -define(`SMART_PCM_NAME', `smart-nocodec') - -# run smart amp pipelines on DSP core 1 -define(`SMART_AMP_CORE', 1) - -# Include Smart Amplifier support -include(`sof-smart-amplifier.m4') - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp) - -# Low Latency playback pipeline 1 on PCM 0 using max 2 channels of s16le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-demux-playback.m4, - 1, 0, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Volume-switch capture pipeline 2 on PCM 0 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-switch-capture.m4, - 2, 0, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 3 on PCM 1 using max 2 channels of s16le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 3, 1, 2, s16le, - 1000, 0, 3, - 48000, 48000, 48000) - -# Low Latency capture pipeline 4 on PCM 1 using max 2 channels of s16le. -# Schedule 48 frames per 1000us deadline on core 3 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, - 4, 1, 2, s16le, - 1000, 0, 3, - 48000, 48000, 48000) - -# Capture pipeline 7 from demux on PCM 6 using max 2 channels of s32le. -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture-sched.m4, - 7, 3, 2, s32le, - 1000, 1, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) - -# Passthrough capture pipeline 8 on PCM 4 using max 2 channels. -# 1000us deadline on core 2 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, - 8, 4, 2, s32le, - 1000, 0, 2, - 48000, 48000, 48000) - -# Passthrough capture pipeline 9 on PCM 5 using max 2 channels. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, - 9, 5, 2, s32le, - 1000, 0, 0, - 16000, 16000, 16000) - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl deadline, priority, core, time_domain) - -# playback DAI is SSP0 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 1, SSP, 0, NoCodec-0, - PIPELINE_SOURCE_1, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is SSP0 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 2, SSP, 0, NoCodec-0, - PIPELINE_SINK_2, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# Connect demux to capture -SectionGraph."PIPE_CAP" { - index "0" - - lines [ - # mux to capture - dapm(PIPELINE_SINK_7, PIPELINE_DEMUX_1) - ] -} - -# Connect virtual capture to dai -SectionGraph."PIPE_CAP_VIRT" { - index "7" - - lines [ - # mux to capture - dapm(ECHO REF 7, SSP0.IN) - ] -} - -# playback DAI is SSP1 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 3 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 3, SSP, 1, NoCodec-1, - PIPELINE_SOURCE_3, 2, s16le, - 1000, 0, 3, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is SSP1 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 3 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 4, SSP, 1, NoCodec-1, - PIPELINE_SINK_4, 2, s16le, - 1000, 0, 3, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is DMIC 0 using 2 periods -# Buffers use s32le format, 1000us deadline on core 2 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 8, DMIC, 0, NoCodec-6, - PIPELINE_SINK_8, 2, s32le, - 1000, 0, 2, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is DMIC 1 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 9, DMIC, 1, NoCodec-7, - PIPELINE_SINK_9, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -dnl PCM_DUPLEX_ADD(name, pcm_id, playback, capture) -PCM_DUPLEX_ADD(Port0, 0, PIPELINE_PCM_1, PIPELINE_PCM_2) -PCM_DUPLEX_ADD(Port1, 1, PIPELINE_PCM_3, PIPELINE_PCM_4) -PCM_CAPTURE_ADD(FWEchoRef, 3, PIPELINE_PCM_7) -PCM_CAPTURE_ADD(DMIC, 4, PIPELINE_PCM_8) -PCM_CAPTURE_ADD(DMIC16kHz, 5, PIPELINE_PCM_9) - -# -# BE configurations - overrides config in ACPI if present -# - -DAI_CONFIG(SSP, 0, 0, NoCodec-0, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, 38400000, codec_mclk_in), - SSP_CLOCK(bclk, 2400000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 25, 3, 3), - SSP_CONFIG_DATA(SSP, 0, 24, 0, SSP_QUIRK_LBM))) - -DAI_CONFIG(SSP, 1, 1, NoCodec-1, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, 38400000, codec_mclk_in), - SSP_CLOCK(bclk, 2400000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 25, 3, 3), - SSP_CONFIG_DATA(SSP, 1, 24, 0, SSP_QUIRK_LBM))) - -DAI_CONFIG(DMIC, 0, 6, NoCodec-6, - dnl DMIC_CONFIG(driver_version, clk_min, clk_mac, duty_min, duty_max, - dnl sample_rate, fifo word length, unmute time, type, - dnl dai_index, pdm controller config) - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, - DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, - dnl PDM_CONFIG(type, dai_index, num pdm active, pdm tuples list) - dnl STEREO_PDM0 is a pre-defined pdm config for stereo capture - PDM_CONFIG(DMIC, 0, STEREO_PDM0))) - -DAI_CONFIG(DMIC, 1, 7, NoCodec-7, - dnl DMIC_CONFIG(driver_version, clk_min, clk_mac, duty_min, duty_max, - dnl sample_rate, fifo word length, unmute time, type, - dnl dai_index, pdm controller config) - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, - DMIC_WORD_LENGTH(s32le), 400, DMIC, 1, - dnl PDM_CONFIG(type, dai_index, num pdm active, pdm tuples list) - dnl STEREO_PDM0 is a pre-defined pdm config for stereo capture - PDM_CONFIG(DMIC, 1, STEREO_PDM0))) diff --git a/tools/topology/topology1/development/sof-tgl-nocodec-crossover-2way.m4 b/tools/topology/topology1/development/sof-tgl-nocodec-crossover-2way.m4 deleted file mode 100644 index 77e9cd99e832..000000000000 --- a/tools/topology/topology1/development/sof-tgl-nocodec-crossover-2way.m4 +++ /dev/null @@ -1,158 +0,0 @@ -# -# Topology for Tigerlake RVP board CI testing, with covering as more -# features as possible running with no codec machine. -# -# TGL Host GW DMAC support max 6 playback and max 6 capture channels so some -# pipelines/PCMs/DAIs are commented out to keep within HW bounds. If these -# are needed then they can be used provided other PCMs/pipelines/SSPs are -# commented out in their place. - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`ssp.m4') -include(`crossover.m4') -include(`bytecontrol.m4') -include(`pipeline.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include Tigerlake DSP configuration -include(`platform/intel/tgl.m4') - -#define SSP_MCLK -define(`SSP_MCLK', 38400000) - -# -# Topology -# -# pcm0p --> buf1.0 --> crossover1.0 --> buf1.1 --> ssp0.out -# | -# +----------> buf2.0 --> ssp2.out -# -# -# pcm0c <-- buf5.0 <-- ssp0.in -# pcm1c <-- buf6.0 <-- ssp2.in -# - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp, dynamic) - -define(PIPELINE_FILTER1, crossover/coef_2way_48000_200_1_2.m4) - -# Low Latency playback pipeline 1 on PCM 0 using max 2 channels of s16le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-crossover-playback.m4, - 1, 0, 2, s16le, - 1000, 0, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) - -undefine(`PIPELINE_FILTER1') - -# Playback pipeline 2 on PCM 1 using max 2 channels of s16le. -# Set 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-dai-endpoint.m4, - 2, 1, 2, s16le, - 1000, 0, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER) - -# connect pipelines together -SectionGraph."pipe-sof-2-pipe" { - index "2" - - lines [ - # connect the second sink buffer - dapm(PIPELINE_SOURCE_2, PIPELINE_CROSSOVER_1) - ] -} - -# Pass-through capture pipeline 5 on PCM 0 using max 2 channels of s16le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, - 5, 0, 2, s16le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Pass-throug capture pipeline 6 on PCM 1 using max 2 channels of s16le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, - 6, 1, 2, s16le, - 1000, 0, 0, - 48000, 48000, 48000) - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl period , priority, core, time_domain, -dnl channels, rate, dynamic_pipe) - -# playback DAI is SSP0 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 1, SSP, 0, NoCodec-0, - PIPELINE_SOURCE_1, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER, - 2, 48000) - -dnl DAI_ADD_SCHED(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl period , priority, core, time_domain, sched_comp) - -# playback DAI is SSP2 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD_SCHED(sof/pipe-dai-sched-playback.m4, - 2, SSP, 2, NoCodec-2, - PIPELINE_SOURCE_2, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) - -# capture DAI is SSP0 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 5, SSP, 0, NoCodec-0, - PIPELINE_SINK_5, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is SSP2 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 6, SSP, 2, NoCodec-2, - PIPELINE_SINK_6, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -dnl PCM_DUPLEX_ADD(name, pcm_id, playback, capture) -PCM_DUPLEX_ADD(Port0, 0, PIPELINE_PCM_1, PIPELINE_PCM_5) - -dnl PCM_CAPTURE_ADD(name, pcm_id, capture) -PCM_CAPTURE_ADD(Port1, 1, PIPELINE_PCM_6) - -# -# BE configurations - overrides config in ACPI if present -# - -dnl DAI_CONFIG(type, idx, link_id, name, ssp_config/dmic_config) -DAI_CONFIG(SSP, 0, 0, NoCodec-0, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, 38400000, codec_mclk_in), - SSP_CLOCK(bclk, 2400000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 25, 3, 3), - SSP_CONFIG_DATA(SSP, 0, 24, 0, SSP_QUIRK_LBM))) - -DAI_CONFIG(SSP, 2, 2, NoCodec-2, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, 38400000, codec_mclk_in), - SSP_CLOCK(bclk, 2400000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 25, 3, 3), - SSP_CONFIG_DATA(SSP, 2, 24, 0, SSP_QUIRK_LBM))) diff --git a/tools/topology/topology1/development/sof-tgl-nocodec-crossover-4way.m4 b/tools/topology/topology1/development/sof-tgl-nocodec-crossover-4way.m4 deleted file mode 100644 index e3d73ec59c90..000000000000 --- a/tools/topology/topology1/development/sof-tgl-nocodec-crossover-4way.m4 +++ /dev/null @@ -1,264 +0,0 @@ -# -# Topology for Tigerlake RVP board CI testing, with covering as more -# features as possible running with no codec machine. -# -# TGL Host GW DMAC support max 6 playback and max 6 capture channels so some -# pipelines/PCMs/DAIs are commented out to keep within HW bounds. If these -# are needed then they can be used provided other PCMs/pipelines/SSPs are -# commented out in their place. - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`ssp.m4') -include(`crossover.m4') -include(`bytecontrol.m4') -include(`pipeline.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include Tigerlake DSP configuration -include(`platform/intel/tgl.m4') - -#define SSP_MCLK -define(`SSP_MCLK', 38400000) - -# -# Topology -# -# pcm0p --> buf1.0 --> crossover1.0 --> buf1.1 --> ssp0.out -# | -# +----------> buf2.0 --> ssp1.out -# | -# +----------> buf3.0 --> ssp2.out -# | -# +----------> buf4.0 --> ssp3.out -# -# pcm0c <-- buf5.0 <-- ssp0.in -# pcm1c <-- buf6.0 <-- ssp1.in -# pcm2c <-- buf7.0 <-- ssp2.in -# pcm3c <-- buf8.0 <-- ssp3.in -# - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp, dynamic) - -define(PIPELINE_FILTER1, crossover/coef_4way_48000_200_1000_3000_1_2_3_4.m4) - -# Low Latency playback pipeline 1 on PCM 0 using max 2 channels of s16le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-crossover-playback.m4, - 1, 0, 2, s16le, - 1000, 0, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) - -undefine(`PIPELINE_FILTER1') - -# Playback pipeline 2 on PCM 1 using max 2 channels of s16le. -# Set 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-dai-endpoint.m4, - 2, 1, 2, s16le, - 1000, 0, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER) - -# Playback pipeline 3 on PCM 2 using max 2 channels of s16le. -# Set 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-dai-endpoint.m4, - 3, 2, 2, s16le, - 1000, 0, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER) - -# Playback pipeline 4 on PCM 3 using max 2 channels of s16le. -# Set 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-dai-endpoint.m4, - 4, 3, 2, s16le, - 1000, 0, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER) - -# connect pipelines together -SectionGraph."pipe-sof-2-pipe" { - index "2" - - lines [ - # connect the second sink buffer - dapm(PIPELINE_SOURCE_2, PIPELINE_CROSSOVER_1) - ] -} - -# connect pipelines together -SectionGraph."pipe-sof-3-pipe" { - index "3" - - lines [ - # connect the second sink buffer - dapm(PIPELINE_SOURCE_3, PIPELINE_CROSSOVER_1) - ] -} - -# connect pipelines together -SectionGraph."pipe-sof-4-pipe" { - index "4" - - lines [ - # connect the second sink buffer - dapm(PIPELINE_SOURCE_4, PIPELINE_CROSSOVER_1) - ] -} - -# Pass-through capture pipeline 5 on PCM 0 using max 2 channels of s16le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, - 5, 0, 2, s16le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Pass-throug capture pipeline 6 on PCM 1 using max 2 channels of s16le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, - 6, 1, 2, s16le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Pass-throug capture pipeline 7 on PCM 2 using max 2 channels of s16le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, - 7, 2, 2, s16le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Pass-throug capture pipeline 6 on PCM 3 using max 2 channels of s16le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, - 8, 3, 2, s16le, - 1000, 0, 0, - 48000, 48000, 48000) - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl period , priority, core, time_domain, -dnl channels, rate, dynamic_pipe) - -# playback DAI is SSP0 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 1, SSP, 0, NoCodec-0, - PIPELINE_SOURCE_1, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER, - 2, 48000) - - - -dnl DAI_ADD_SCHED(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl period , priority, core, time_domain, sched_comp) - -# playback DAI is SSP1 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD_SCHED(sof/pipe-dai-sched-playback.m4, - 2, SSP, 1, NoCodec-1, - PIPELINE_SOURCE_2, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) - -# playback DAI is SSP2 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD_SCHED(sof/pipe-dai-sched-playback.m4, - 3, SSP, 2, NoCodec-2, - PIPELINE_SOURCE_3, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) - -# playback DAI is SSP3 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD_SCHED(sof/pipe-dai-sched-playback.m4, - 4, SSP, 3, NoCodec-3, - PIPELINE_SOURCE_4, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) - - - -# capture DAI is SSP0 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 5, SSP, 0, NoCodec-0, - PIPELINE_SINK_5, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is SSP1 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 6, SSP, 1, NoCodec-1, - PIPELINE_SINK_6, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is SSP2 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 7, SSP, 2, NoCodec-2, - PIPELINE_SINK_7, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is SSP3 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 8, SSP, 3, NoCodec-3, - PIPELINE_SINK_8, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - - -dnl PCM_DUPLEX_ADD(name, pcm_id, playback, capture) -PCM_DUPLEX_ADD(Port0, 0, PIPELINE_PCM_1, PIPELINE_PCM_5) - -dnl PCM_CAPTURE_ADD(name, pcm_id, capture) -PCM_CAPTURE_ADD(Port1, 1, PIPELINE_PCM_6) -PCM_CAPTURE_ADD(Port2, 2, PIPELINE_PCM_7) -PCM_CAPTURE_ADD(Port3, 3, PIPELINE_PCM_8) - -# -# BE configurations - overrides config in ACPI if present -# - -dnl DAI_CONFIG(type, idx, link_id, name, ssp_config/dmic_config) -DAI_CONFIG(SSP, 0, 0, NoCodec-0, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, 38400000, codec_mclk_in), - SSP_CLOCK(bclk, 2400000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 25, 3, 3), - SSP_CONFIG_DATA(SSP, 0, 24, 0, SSP_QUIRK_LBM))) - -DAI_CONFIG(SSP, 1, 1, NoCodec-1, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, 38400000, codec_mclk_in), - SSP_CLOCK(bclk, 2400000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 25, 3, 3), - SSP_CONFIG_DATA(SSP, 1, 24, 0, SSP_QUIRK_LBM))) - -DAI_CONFIG(SSP, 2, 2, NoCodec-2, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, 38400000, codec_mclk_in), - SSP_CLOCK(bclk, 2400000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 25, 3, 3), - SSP_CONFIG_DATA(SSP, 2, 24, 0, SSP_QUIRK_LBM))) - -DAI_CONFIG(SSP, 3, 3, NoCodec-3, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, 38400000, codec_mclk_in), - SSP_CLOCK(bclk, 2400000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 25, 3, 3), - SSP_CONFIG_DATA(SSP, 3, 24, 0, SSP_QUIRK_LBM))) diff --git a/tools/topology/topology1/development/sof-tgl-nocodec-mux.m4 b/tools/topology/topology1/development/sof-tgl-nocodec-mux.m4 deleted file mode 100644 index 8121c6a78db4..000000000000 --- a/tools/topology/topology1/development/sof-tgl-nocodec-mux.m4 +++ /dev/null @@ -1,143 +0,0 @@ -# -# Topology for Tigerlake RVP board CI testing, with covering as more -# features as possible running with no codec machine. -# -# TGL Host GW DMAC support max 6 playback and max 6 capture channels so some -# pipelines/PCMs/DAIs are commented out to keep within HW bounds. If these -# are needed then they can be used provided other PCMs/pipelines/SSPs are -# commented out in their place. - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`ssp.m4') -include(`muxdemux.m4') -include(`bytecontrol.m4') -include(`pipeline.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include Tigerlake DSP configuration -include(`platform/intel/tgl.m4') - -define(PIPE_NAME, pipe-tgl-mux) - -# -# Define the demux configure -# -dnl Configure demux -dnl name, pipeline_id, routing_matrix_rows -dnl Diagonal 1's in routing matrix mean that every input channel is -dnl copied to corresponding output channels in all output streams. -dnl I.e. row index is the input channel, 1 means it is copied to -dnl corresponding output channel (column index), 0 means it is discarded. -dnl There's a separate matrix for all outputs. -define(matrix1, `ROUTE_MATRIX(2, - `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)')') - -define(matrix2, `ROUTE_MATRIX(3, - `BITS_TO_BYTE(0, 0, 1 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,1 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)')') - -dnl name, num_streams, route_matrix list -MUXDEMUX_CONFIG(demux_priv_1, 2, LIST_NONEWLINE(`', `matrix1,', `matrix2')) - -#define SSP_MCLK -define(`SSP_MCLK', 38400000) - -# playback DAI is SSP0 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-mux-dai-playback.m4, - 1, SSP, 0, NoCodec-0, - NOT_USED_IGNORED, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER, - 4, 48000) - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp) - -# Low Latency playback pipeline 1 on PCM 0 using max 2 channels of s16le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-host-playback.m4, - 2, 0, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) - -# Low Latency playback pipeline 3 on PCM 1 using max 2 channels of s16le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-host-playback.m4, - 3, 1, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) - -# Volume-switch capture pipeline 2 on PCM 0 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, - 4, 0, 4, s32le, - 1000, 0, 0, - 48000, 48000, 48000) -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl deadline, priority, core, time_domain) - -# capture DAI is SSP0 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 4, SSP, 0, NoCodec-0, - PIPELINE_SINK_4, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# Connect pipelines together -SectionGraph."PIPE_NAME" { - index "0" - lines [ - # PCM pipeline 3 to DAI pipeline 1 - dapm(PIPELINE_MUX_1, PIPELINE_SOURCE_2) - # PCM pipeline 4 to DAI pipeline 1 - dapm(PIPELINE_MUX_1, PIPELINE_SOURCE_3) - ] -} - -dnl PCM_DUPLEX_ADD(name, pcm_id, playback, capture) -PCM_DUPLEX_ADD(Port0, 0, PIPELINE_PCM_2, PIPELINE_PCM_4) -PCM_PLAYBACK_ADD(Media Playback MUX 1, 1, PIPELINE_PCM_3) - -# -# BE configurations - overrides config in ACPI if present -# - -DAI_CONFIG(SSP, 0, 0, NoCodec-0, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, 38400000, codec_mclk_in), - SSP_CLOCK(bclk, 4800000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(4, 25, 15, 15), - SSP_CONFIG_DATA(SSP, 0, 24, 0, SSP_QUIRK_LBM))) diff --git a/tools/topology/topology1/dsp_enhancement/CMakeLists.txt b/tools/topology/topology1/dsp_enhancement/CMakeLists.txt deleted file mode 100644 index bdb655dd7800..000000000000 --- a/tools/topology/topology1/dsp_enhancement/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause - -# The topologies are defined in parent directory and enhanced with end-point specific processing -set(TPLGS_UP - "sof-hda-generic\;sof-hda-generic-eq\;-DCHANNELS=0\;-DHSPROC=eq-iir-eq-fir-volume\;-DHSPROC_FILTER1=eq_iir_coef_pass.m4\;-DHSPROC_FILTER2=eq_fir_coef_pass.m4" - "sof-hda-generic\;sof-hda-generic-eq-2ch\;-DCHANNELS=2\;-DHSPROC=eq-iir-eq-fir-volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4" - "sof-hda-generic\;sof-hda-generic-eq-4ch\;-DCHANNELS=4\;-DHSPROC=eq-iir-eq-fir-volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4" -) - -add_custom_target(dsp_topologies1 ALL) - -foreach(tplg ${TPLGS_UP}) - list(GET tplg 0 input) - list(GET tplg 1 output) - list(LENGTH tplg tplg_len) - math(EXPR num_args "${tplg_len} - 1") - set(DEFINES "") - if (${num_args} GREATER 1) - foreach(index RANGE 2 ${num_args}) - list(GET tplg ${index} custom_define) - list(APPEND DEFINES ${custom_define}) - endforeach() - endif() - - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${output}.conf - COMMAND m4 --fatal-warnings - ${DEFINES} - -I ${CMAKE_CURRENT_SOURCE_DIR}/../m4 - -I ${CMAKE_CURRENT_SOURCE_DIR}/../common - -I ${CMAKE_CURRENT_SOURCE_DIR}/../platform/common - -I ${CMAKE_CURRENT_SOURCE_DIR}/../ - -I ${CMAKE_CURRENT_BINARY_DIR}/../ - ${CMAKE_CURRENT_SOURCE_DIR}/../common/abi.m4 - ${CMAKE_CURRENT_SOURCE_DIR}/../${input}.m4 - > ${output}.conf - DEPENDS abi_v1 ${CMAKE_BINARY_DIR}/topology/topology1/abi.h - VERBATIM - USES_TERMINAL - ) - - add_alsatplg_command(${output}.conf ${output}.tplg) - - add_custom_target(dsp_topology_${output} DEPENDS ${output}.tplg) - add_dependencies(dsp_topologies1 dsp_topology_${output}) -endforeach() diff --git a/tools/topology/topology1/kernel_dependent/CMakeLists.txt b/tools/topology/topology1/kernel_dependent/CMakeLists.txt deleted file mode 100644 index 5b81d374b6a7..000000000000 --- a/tools/topology/topology1/kernel_dependent/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause - -add_subdirectory(v5.19) diff --git a/tools/topology/topology1/kernel_dependent/v5.19/CMakeLists.txt b/tools/topology/topology1/kernel_dependent/v5.19/CMakeLists.txt deleted file mode 100644 index 2556c26914e9..000000000000 --- a/tools/topology/topology1/kernel_dependent/v5.19/CMakeLists.txt +++ /dev/null @@ -1,89 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause - -# Those topologies are built from topology in the parent directory -set(TPLGS_UP - ## HDaudio codec topologies - "sof-hda-generic\;sof-hda-generic\;-DDEEP_BUFFER\;-DCHANNELS=0\;-DHSPROC=volume\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-1ch\;-DDEEP_BUFFER\;-DCHANNELS=2\;-DHSPROC=volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-1ch-pdm1\;-DPDM1\;-DDEEP_BUFFER\;-DCHANNELS=2\;-DHSPROC=volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-2ch\;-DDEEP_BUFFER\;-DCHANNELS=2\;-DHSPROC=volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-2ch-pdm1\;-DPDM1\;-DDEEP_BUFFER\;-DCHANNELS=2\;-DHSPROC=volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-3ch\;-DDEEP_BUFFER\;-DCHANNELS=4\;-DHSPROC=volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - "sof-hda-generic\;sof-hda-generic-4ch\;-DDEEP_BUFFER\;-DCHANNELS=4\;-DHSPROC=volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" - ## end HDaudio codec topologies - - ## SoundWire topologies - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-tgl-rt711-rt1308-mono-rt715\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DPLATFORM=tgl\;-DMONO\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-tgl-rt711-l0-rt1316-l1-mono-rt714-l3\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DPLATFORM=tgl\;-DMONO\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-tgl-rt715-rt711-rt1308-mono\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DPLATFORM=tgl\;-DMONO\;-DUAJ_LINK=1\;-DAMP_1_LINK=2\;-DMIC_LINK=0" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-tgl-rt711-rt1308-rt715\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DPLATFORM=tgl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-tgl-rt711-rt1316-rt714\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DPLATFORM=tgl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt711-l0-rt1308-l12-rt715-l3\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DPLATFORM=adl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt711-l0-rt1316-l12-rt714-l3\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DPLATFORM=adl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt711-l0-rt1316-l13-rt714-l2\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DPLATFORM=adl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=3\;-DEXT_AMP_REF\;-DMIC_LINK=2" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt711-l2-rt1316-l01-rt714-l3\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DPLATFORM=adl\;-DUAJ_LINK=2\;-DAMP_1_LINK=0\;-DAMP_2_LINK=1\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt711-l2-rt1316-l01\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DPLATFORM=adl\;-DUAJ_LINK=2\;-DAMP_1_LINK=0\;-DAMP_2_LINK=1\;-DEXT_AMP_REF\;-DNO_LOCAL_MIC" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-rpl-rt711-l2-rt1316-l01-rt714-l3\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DPLATFORM=rpl\;-DUAJ_LINK=2\;-DAMP_1_LINK=0\;-DAMP_2_LINK=1\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-rpl-rt711-l2-rt1316-l01\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DPLATFORM=rpl\;-DUAJ_LINK=2\;-DAMP_1_LINK=0\;-DAMP_2_LINK=1\;-DEXT_AMP_REF\;-DNO_LOCAL_MIC" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-rpl-rt711-l0-rt1316-l12-rt714-l3\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DPLATFORM=rpl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-rpl-rt711-l0-rt1318-l12-rt714-l3\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DPLATFORM=rpl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-rpl-rt711-l0-rt1318-l12\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DPLATFORM=rpl\;-DUAJ_LINK=0\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DEXT_AMP_REF\;-DNO_LOCAL_MIC" - "sof-tgl-rt711-rt1308\;sof-tgl-rt711-rt1308-2ch\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DCHANNELS=2\;-DEXT_AMP\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=tgl" - "sof-tgl-rt711-rt1308\;sof-tgl-rt711-rt1308-4ch\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DCHANNELS=4\;-DEXT_AMP\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=tgl" - "sof-tgl-rt711-rt1308\;sof-tgl-rt711-4ch\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DCHANNELS=4\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=tgl" - "sof-tgl-rt711-rt1308\;sof-adl-rt711-4ch\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DCHANNELS=4\;-DBT_OFFLOAD\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=adl" - "sof-tgl-rt711-rt1308\;sof-adl-rt711\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DCHANNELS=0\;-DBT_OFFLOAD\;-DPLATFORM=adl" - "sof-tgl-rt711-rt1308\;sof-adl-rt711-l0-rt1316-l3-2ch\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DCHANNELS=2\;-DEXT_AMP\;-DEXT_AMP_REF\;-DAMP_1_LINK=3\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=adl" - "sof-tgl-rt711-rt1308\;sof-adl-rt711-l0-rt1316-l2-2ch\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DCHANNELS=2\;-DEXT_AMP\;-DEXT_AMP_REF\;-DAMP_1_LINK=2\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=adl" - "sof-tgl-rt711-rt1308\;sof-adl-rt711-l0-rt1316-l2-4ch\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DCHANNELS=4\;-DEXT_AMP\;-DEXT_AMP_REF\;-DAMP_1_LINK=2\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=adl" - - "sof-tgl-rt711-rt1308\;sof-rpl-rt711-4ch\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DCHANNELS=4\;-DBT_OFFLOAD\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=rpl" - "sof-tgl-rt711-rt1308\;sof-rpl-rt711\;-DHEADSET_DEEP_BUFFER\;-DDYNAMIC=1\;-DCHANNELS=0\;-DBT_OFFLOAD\;-DPLATFORM=rpl" - ## end SoundWire topologies - - ## SoundWire NOJACK topologies - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt1316-l1-mono-rt714-l0\;-DDYNAMIC=1\;-DPLATFORM=adl\;-DMONO\;-DNOJACK\;-DAMP_1_LINK=1\;-DEXT_AMP_REF\;-DMIC_LINK=0" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt1316-l2-mono-rt714-l0\;-DDYNAMIC=1\;-DPLATFORM=adl\;-DMONO\;-DNOJACK\;-DAMP_1_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=0" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt1316-l12-rt714-l0\;-DDYNAMIC=1\;-DPLATFORM=adl\;-DNOJACK\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=0" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-adl-rt1316-l2-mono-rt714-l3\;-DDYNAMIC=1\;-DPLATFORM=adl\;-DMONO\;-DNOJACK\;-DAMP_1_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=3" - "sof-icl-rt711-rt1308-rt715-hdmi\;sof-rpl-rt1316-l12-rt714-l0\;-DDYNAMIC=1\;-DPLATFORM=rpl\;-DNOJACK\;-DAMP_1_LINK=1\;-DAMP_2_LINK=2\;-DEXT_AMP_REF\;-DMIC_LINK=0" - ## end SoundWire NOJACK topologies -) - -add_custom_target(kernel_dependent_v5_19_topologies1) -add_dependencies(topologies1 kernel_dependent_v5_19_topologies1) - -# handle topologies in parent directory -foreach(tplg ${TPLGS_UP}) - list(GET tplg 0 input) - list(GET tplg 1 output) - list(LENGTH tplg tplg_len) - math(EXPR num_args "${tplg_len} - 1") - set(DEFINES "") - if (${num_args} GREATER 1) - foreach(index RANGE 2 ${num_args}) - list(GET tplg ${index} custom_define) - list(APPEND DEFINES ${custom_define}) - endforeach() - endif() - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${output}.conf - COMMAND m4 --fatal-warnings - ${DEFINES} - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../m4 - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../common - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../platform/common - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ - -I ${CMAKE_CURRENT_BINARY_DIR}/../../ - ${CMAKE_CURRENT_SOURCE_DIR}/../../common/abi.m4 - ${CMAKE_CURRENT_SOURCE_DIR}/../../${input}.m4 - > ${output}.conf - DEPENDS abi_v1 ${CMAKE_BINARY_DIR}/topology/topology1/abi.h - VERBATIM - USES_TERMINAL - ) - add_alsatplg_command(${output}.conf ${output}.tplg) - - add_custom_target(k519_topology_${output} DEPENDS ${output}.tplg) - add_dependencies(kernel_dependent_v5_19_topologies1 k519_topology_${output}) -endforeach() diff --git a/tools/topology/topology1/m4/dai.m4 b/tools/topology/topology1/m4/dai.m4 index 8f13db1504af..e4452c7376f0 100644 --- a/tools/topology/topology1/m4/dai.m4 +++ b/tools/topology/topology1/m4/dai.m4 @@ -155,7 +155,7 @@ define(`DO_DAI_CONFIG', `' ` id "'$3`"' `' -` ifelse($1, `SSP', $5, $1, `HDA', $5, $1, `ALH', $5, $1, `ESAI', $5, $1, `SAI', $5, $1, `AFE', $5, $1, `ACP', $5, $1, `ACPSP', $5, $1,`ACPSP_VIRTUAL', $5, $1, `ACPHS', $5, $1, `ACPHS_VIRTUAL', $5, $1, `ACPDMIC', $5, `}')' +` ifelse($1, `SSP', $5, $1, `HDA', $5, $1, `ALH', $5, $1, `ESAI', $5, $1, `SAI', $5, $1, `MICFIL', $5, $1, `AFE', $5, $1, `ACP', $5, $1, `ACPSP', $5, $1,`ACPSP_VIRTUAL', $5, $1, `ACPHS', $5, $1, `ACPHS_VIRTUAL', $5, $1, `ACPDMIC', $5, `}')' `ifelse($1, `DMIC', $5, `')' `SectionVendorTuples."'N_DAI_CONFIG($1$2)`_tuples_common" {' ` tokens "sof_dai_tokens"' diff --git a/tools/topology/topology1/platform/common/micfil.m4 b/tools/topology/topology1/platform/common/micfil.m4 new file mode 100644 index 000000000000..0adad8446afb --- /dev/null +++ b/tools/topology/topology1/platform/common/micfil.m4 @@ -0,0 +1,24 @@ +divert(-1) + +dnl MICFIL related macros + +define(`MICFIL_CONFIG', +`}' +$1 +) +dnl MICFIL_CONFIG_DATA(type, idx, rate, channel) +define(`MICFIL_CONFIG_DATA', +`SectionVendorTuples."'N_DAI_CONFIG($1$2)`_tuples" {' +` tokens "sof_micfil_tokens"' +` tuples."word" {' +` SOF_TKN_IMX_MICFIL_RATE' STR($3) +` SOF_TKN_IMX_MICFIL_CH' STR($4) +` }' +`}' +`SectionData."'N_DAI_CONFIG($1$2)`_data" {' +` tuples "'N_DAI_CONFIG($1$2)`_tuples"' +`}' +) + +divert(0)dnl + diff --git a/tools/topology/topology1/platform/intel/adl.m4 b/tools/topology/topology1/platform/intel/adl.m4 deleted file mode 100644 index f058b2025bbb..000000000000 --- a/tools/topology/topology1/platform/intel/adl.m4 +++ /dev/null @@ -1,38 +0,0 @@ -# -# Tigerlake differentiation for pipelines and components -# - -include(`memory.m4') - -dnl Memory capabilities for different buffer types on Tigerlake -define(`PLATFORM_DAI_MEM_CAP', - MEMCAPS(MEM_CAP_RAM, MEM_CAP_DMA, MEM_CAP_CACHE, MEM_CAP_HP)) -define(`PLATFORM_HOST_MEM_CAP', - MEMCAPS(MEM_CAP_RAM, MEM_CAP_DMA, MEM_CAP_CACHE, MEM_CAP_HP)) -define(`PLATFORM_PASS_MEM_CAP', - MEMCAPS(MEM_CAP_RAM, MEM_CAP_DMA, MEM_CAP_CACHE, MEM_CAP_HP)) -define(`PLATFORM_COMP_MEM_CAP', MEMCAPS(MEM_CAP_RAM, MEM_CAP_CACHE)) - -# Low Latency PCM Configuration -W_VENDORTUPLES(pipe_ll_schedule_plat_tokens, sof_sched_tokens, - LIST(` ', `SOF_TKN_SCHED_MIPS "50000"')) - -W_DATA(pipe_ll_schedule_plat, pipe_ll_schedule_plat_tokens) - -# Media PCM Configuration -W_VENDORTUPLES(pipe_media_schedule_plat_tokens, sof_sched_tokens, - LIST(` ', `SOF_TKN_SCHED_MIPS "100000"')) - -W_DATA(pipe_media_schedule_plat, pipe_media_schedule_plat_tokens) - -# Tone Signal Generator Configuration -W_VENDORTUPLES(pipe_tone_schedule_plat_tokens, sof_sched_tokens, - LIST(` ', `SOF_TKN_SCHED_MIPS "200000"')) - -W_DATA(pipe_tone_schedule_plat, pipe_tone_schedule_plat_tokens) - -# DAI schedule Configuration - scheduled by IRQ -W_VENDORTUPLES(pipe_dai_schedule_plat_tokens, sof_sched_tokens, - LIST(` ', `SOF_TKN_SCHED_MIPS "5000"')) - -W_DATA(pipe_dai_schedule_plat, pipe_dai_schedule_plat_tokens) diff --git a/tools/topology/topology1/platform/intel/dmic.m4 b/tools/topology/topology1/platform/intel/dmic.m4 deleted file mode 100644 index 4291543159bc..000000000000 --- a/tools/topology/topology1/platform/intel/dmic.m4 +++ /dev/null @@ -1,71 +0,0 @@ -divert(-1) - -dnl DMIC related macros - -dnl PDM_TUPLES(pdm ctrl id, mic_a_enable, mic_b_enable, polarity_a, polarity_b, -dnl clk_egde, skew) -define(`PDM_TUPLES', -` tuples."short.pdm$1" {' -` SOF_TKN_INTEL_DMIC_PDM_CTRL_ID' STR($1) -` SOF_TKN_INTEL_DMIC_PDM_MIC_A_Enable' STR($2) -` SOF_TKN_INTEL_DMIC_PDM_MIC_B_Enable' STR($3) -` SOF_TKN_INTEL_DMIC_PDM_POLARITY_A' STR($4) -` SOF_TKN_INTEL_DMIC_PDM_POLARITY_B' STR($5) -` SOF_TKN_INTEL_DMIC_PDM_CLK_EDGE' STR($6) -` SOF_TKN_INTEL_DMIC_PDM_SKEW' STR($7) -` }' -) - -dnl PDM_CONFIG(type, idx, num pdm active, pdm tuples list) -define(`PDM_CONFIG', -` SOF_TKN_INTEL_DMIC_NUM_PDM_ACTIVE' STR($3) -` }' -`}' -`SectionVendorTuples."'N_DAI_CONFIG($1$2)`_pdm_tuples" {' -` tokens "sof_dmic_pdm_tokens"' -$4 -`}' -) - -dnl DMIC currently only supports 16 bit or 32-bit word length -dnl DMIC_WORD_LENGTH(frame format) -define(`DMIC_WORD_LENGTH', -`ifelse($1, `s16le', 16, $1, `s32le', 32, `')') - -dnl DMIC_CONFIG(driver_version, clk_min, clk_mac, duty_min, duty_max, -dnl sample_rate, fifo word length, ramp_time, -dnl type, idx, pdm controller config) -define(`DMIC_CONFIG', -`SectionVendorTuples."'N_DAI_CONFIG($9$10)`_dmic_tuples" {' -` tokens "sof_dmic_tokens"' -` tuples."word" {' -` SOF_TKN_INTEL_DMIC_DRIVER_VERSION' STR($1) -` SOF_TKN_INTEL_DMIC_CLK_MIN' STR($2) -` SOF_TKN_INTEL_DMIC_CLK_MAX' STR($3) -` SOF_TKN_INTEL_DMIC_DUTY_MIN' STR($4) -` SOF_TKN_INTEL_DMIC_DUTY_MAX' STR($5) -` SOF_TKN_INTEL_DMIC_SAMPLE_RATE' STR($6) -` SOF_TKN_INTEL_DMIC_FIFO_WORD_LENGTH' STR($7) -` SOF_TKN_INTEL_DMIC_UNMUTE_RAMP_TIME_MS' STR($8) - -dnl PDM config for the number of active PDM controllers -$11 -`SectionData."'N_DAI_CONFIG($9$10)`_pdm_data" {' -` tuples "'N_DAI_CONFIG($9$10)`_pdm_tuples"' -`}' -`SectionData."'N_DAI_CONFIG($9$10)`_data" {' -` tuples "'N_DAI_CONFIG($9$10)`_dmic_tuples"' - -`}' -) - -dnl DMIC PDM configurations -dnl macros to get the number of active pdm's and their config -define(`MONO_PDM0_MICA', `1, LIST(`', PDM_TUPLES(0, 1, 0, 0, 0, 0, 0))') -define(`MONO_PDM0_MICB', `1, LIST(`', PDM_TUPLES(0, 0, 1, 0, 0, 0, 0))') -define(`STEREO_PDM0', `1, LIST(`', PDM_TUPLES(0, 1, 1, 0, 0, 0, 0))') -define(`STEREO_PDM1', `1, LIST(`', PDM_TUPLES(1, 1, 1, 0, 0, 0, 0))') -define(`FOUR_CH_PDM0_PDM1', - `2, LIST(`', PDM_TUPLES(0, 1, 1, 0, 0, 0, 0), PDM_TUPLES(1, 1, 1, 0, 0, 0, 0))') - -divert(0)dnl diff --git a/tools/topology/topology1/platform/intel/ehl.m4 b/tools/topology/topology1/platform/intel/ehl.m4 deleted file mode 100644 index e914bbbaa323..000000000000 --- a/tools/topology/topology1/platform/intel/ehl.m4 +++ /dev/null @@ -1,38 +0,0 @@ -# -# ElkhartLake differentiation for pipelines and components -# - -include(`memory.m4') - -dnl Memory capabilities for different buffer types on ElkhartLake -define(`PLATFORM_DAI_MEM_CAP', - MEMCAPS(MEM_CAP_RAM, MEM_CAP_DMA, MEM_CAP_CACHE, MEM_CAP_HP)) -define(`PLATFORM_HOST_MEM_CAP', - MEMCAPS(MEM_CAP_RAM, MEM_CAP_DMA, MEM_CAP_CACHE, MEM_CAP_HP)) -define(`PLATFORM_PASS_MEM_CAP', - MEMCAPS(MEM_CAP_RAM, MEM_CAP_DMA, MEM_CAP_CACHE, MEM_CAP_HP)) -define(`PLATFORM_COMP_MEM_CAP', MEMCAPS(MEM_CAP_RAM, MEM_CAP_CACHE)) - -# Low Latency PCM Configuration -W_VENDORTUPLES(pipe_ll_schedule_plat_tokens, sof_sched_tokens, - LIST(` ', `SOF_TKN_SCHED_MIPS "50000"')) - -W_DATA(pipe_ll_schedule_plat, pipe_ll_schedule_plat_tokens) - -# Media PCM Configuration -W_VENDORTUPLES(pipe_media_schedule_plat_tokens, sof_sched_tokens, - LIST(` ', `SOF_TKN_SCHED_MIPS "100000"')) - -W_DATA(pipe_media_schedule_plat, pipe_media_schedule_plat_tokens) - -# Tone Signal Generator Configuration -W_VENDORTUPLES(pipe_tone_schedule_plat_tokens, sof_sched_tokens, - LIST(` ', `SOF_TKN_SCHED_MIPS "200000"')) - -W_DATA(pipe_tone_schedule_plat, pipe_tone_schedule_plat_tokens) - -# DAI schedule Configuration - scheduled by IRQ -W_VENDORTUPLES(pipe_dai_schedule_plat_tokens, sof_sched_tokens, - LIST(` ', `SOF_TKN_SCHED_MIPS "5000"')) - -W_DATA(pipe_dai_schedule_plat, pipe_dai_schedule_plat_tokens) diff --git a/tools/topology/topology1/platform/intel/intel-boards.m4 b/tools/topology/topology1/platform/intel/intel-boards.m4 deleted file mode 100644 index 8b415a777df8..000000000000 --- a/tools/topology/topology1/platform/intel/intel-boards.m4 +++ /dev/null @@ -1,32 +0,0 @@ -# -# Machine driver differentiation for dai link ID -# - -# variable that need to be defined in upper m4 -ifdef(`PLATFORM',`',`fatal_error(note: Need to define platform identifier for intel-boards)') -ifdef(`LINUX_MACHINE_DRIVER',`',`fatal_error(note: Need to define linux machine driver identifier for intel-boards)') - -define(`NUM_DMIC_BE_LINK', `2') - -ifelse( - PLATFORM, `tgl', `define(`NUM_HDMI_BE_LINK', 4)', - PLATFORM, `adl', `define(`NUM_HDMI_BE_LINK', 4)', - `fatal_error(note: Unknown platform to intel-boards)') - -# define the ID base for backend DAI Links -ifelse( - LINUX_MACHINE_DRIVER, `sof_rt5682', ` - define(`BOARD_HP_BE_ID', `0') - define(`BOARD_DMIC_BE_ID_BASE', eval(BOARD_HP_BE_ID + 1)) - define(`BOARD_HDMI_BE_ID_BASE', eval(BOARD_DMIC_BE_ID_BASE + NUM_DMIC_BE_LINK)) - ifdef(`NO_AMP', `', `define(`BOARD_SPK_BE_ID', eval(BOARD_HDMI_BE_ID_BASE + NUM_HDMI_BE_LINK))') - ifdef(`NO_AMP', `define(`BOARD_BT_BE_ID', eval(BOARD_HDMI_BE_ID_BASE + NUM_HDMI_BE_LINK))', `define(`BOARD_BT_BE_ID', eval(BOARD_SPK_BE_ID + 1))')', - LINUX_MACHINE_DRIVER, `sof_ssp_amp', ` - define(`BOARD_SPK_BE_ID', `0') - ifdef(`NO_DMICS', `', `define(`BOARD_DMIC_BE_ID_BASE', eval(BOARD_SPK_BE_ID + 1))') - ifdef(`NO_DMICS', `define(`BOARD_HDMI_BE_ID_BASE', eval(BOARD_SPK_BE_ID + 1))', `define(`BOARD_HDMI_BE_ID_BASE', eval(BOARD_DMIC_BE_ID_BASE + NUM_DMIC_BE_LINK))') - define(`BOARD_BT_BE_ID', eval(BOARD_HDMI_BE_ID_BASE + NUM_HDMI_BE_LINK))', - `fatal_error(note: Unknown linux machine driver to intel-boards)') - -undefine(`NUM_DMIC_BE_LINK') -undefine(`NUM_HDMI_BE_LINK') diff --git a/tools/topology/topology1/platform/intel/intel-generic-bt.m4 b/tools/topology/topology1/platform/intel/intel-generic-bt.m4 deleted file mode 100644 index 48c9456da71b..000000000000 --- a/tools/topology/topology1/platform/intel/intel-generic-bt.m4 +++ /dev/null @@ -1,80 +0,0 @@ -# -# Bluetooth Audio Offload support -# - -include(`ssp.m4') - -# define default SSP port -ifdef(`SSP_INDEX',`', -`define(SSP_INDEX, `2')') - -define(`BT_MCLK', 38400000) -define(`SSP_NAME', concat(concat(`SSP', SSP_INDEX),`-BT')) - -# variable that need to be defined in upper m4 -ifdef(`BT_PIPELINE_PB_ID',`',`fatal_error(note: Need to define playback pcm id for intel-generic-bt -)') -ifdef(`BT_PIPELINE_CP_ID',`',`fatal_error(note: Need to define capture pcm id for intel-generic-bt -)') -ifdef(`BT_DAI_LINK_ID',`',`fatal_error(note: Need to define DAI link id for intel-generic-bt -)') -ifdef(`BT_PCM_ID',`',`fatal_error(note: Need to define pipeline PCM dev id for intel-generic-bt -)') -ifdef(`HW_CONFIG_ID',`',`fatal_error(note: Need to define hw_conf_id for intel-generic-bt -)') - -define(`CHANNELS_MIN', 1) - -# Support 8K/16K mono and 48K stereo playback -PIPELINE_PCM_ADD(sof/pipe-passthrough-playback.m4, - BT_PIPELINE_PB_ID, BT_PCM_ID, 2, s16le, - 1000, 0, 0, - 8000, 48000, 48000) - -# We are done -undefine(`CHANNELS_MIN') - -# Support 8K/16K mono capture only -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, - BT_PIPELINE_CP_ID, BT_PCM_ID, 1, s16le, - 1000, 0, 0, - 8000, 16000, 48000) - -# playback DAI is SSP2 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - BT_PIPELINE_PB_ID, SSP, SSP_INDEX, SSP_NAME, - concat(`PIPELINE_SOURCE_', BT_PIPELINE_PB_ID), 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is SSP2 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - BT_PIPELINE_CP_ID, SSP, SSP_INDEX, SSP_NAME, - concat(`PIPELINE_SINK_', BT_PIPELINE_CP_ID), 1, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -PCM_DUPLEX_ADD(Bluetooth, BT_PCM_ID, concat(`PIPELINE_PCM_', BT_PIPELINE_PB_ID), concat(`PIPELINE_PCM_', BT_PIPELINE_CP_ID)) - -define(`hwconfig_names', HW_CONFIG_NAMES(LIST(` ', "hw_config1", "hw_config2", "hw_config3"))) -define(`data_names', DAI_DATA_NAMES(LIST(` ', "ssp_data1", "ssp_data2", "ssp_data3"))) - -# Note WB is put as default in the list -define(`ssp_config_list_1', LIST(`', - `MULTI_SSP_CONFIG(hw_config1, HW_CONFIG_ID, DSP_A, SSP_CLOCK(mclk, BT_MCLK, codec_mclk_in),' - `SSP_CLOCK(bclk, 256000, codec_master, inverted),' - `SSP_CLOCK(fsync, 16000, codec_master),' - `SSP_TDM(1, 16, 1, 1),' - `SSP_MULTI_CONFIG_DATA(ssp_data1, 16))', - `MULTI_SSP_CONFIG(hw_config2, eval(HW_CONFIG_ID + 1), DSP_A, SSP_CLOCK(mclk, BT_MCLK, codec_mclk_in),' - `SSP_CLOCK(bclk, 128000, codec_master, inverted),' - `SSP_CLOCK(fsync, 8000, codec_master),' - `SSP_TDM(1, 16, 1, 1),' - `SSP_MULTI_CONFIG_DATA(ssp_data2, 16))', - `MULTI_SSP_CONFIG(hw_config3, eval(HW_CONFIG_ID + 2), DSP_A, SSP_CLOCK(mclk, BT_MCLK, codec_mclk_in),' - `SSP_CLOCK(bclk, 1536000, codec_slave),' - `SSP_CLOCK(fsync, 48000, codec_slave),' - `SSP_TDM(2, 16, 3, 0),' - `SSP_MULTI_CONFIG_DATA(ssp_data3, 16))')) - -MULTI_DAI_CONFIG(SSP, SSP_INDEX, BT_DAI_LINK_ID, SSP_NAME, ssp_config_list_1, hwconfig_names, data_names) diff --git a/tools/topology/topology1/platform/intel/intel-generic-dmic-kwd.m4 b/tools/topology/topology1/platform/intel/intel-generic-dmic-kwd.m4 deleted file mode 100644 index cbcb11e6a7e3..000000000000 --- a/tools/topology/topology1/platform/intel/intel-generic-dmic-kwd.m4 +++ /dev/null @@ -1,167 +0,0 @@ -# -# Topology for digital microphones array -# - -include(`platform/intel/dmic.m4') - -# define default PCM names -ifdef(`DMIC_48k_PCM_NAME',`', -`define(DMIC_48k_PCM_NAME, `DMIC')') -ifdef(`DMIC_16k_PCM_NAME',`', -`define(DMIC_16k_PCM_NAME, `DMIC16kHz')') - -# variable that need to be defined in upper m4 -ifdef(`CHANNELS',`',`fatal_error(note: Need to define channel number for intel-generic-dmic-kwd -)') -ifdef(`KFBM_TYPE',`',`fatal_error(note: Need to define kfbm type for intel-generic-dmic-kwd, available type: vol-kfbm/kfbm -)') -ifdef(`DMIC_PCM_48k_ID',`',`fatal_error(note: Need to define dmic48k pcm id for intel-generic-dmic-kwd -)') -ifdef(`DMIC_PIPELINE_48k_ID',`',`fatal_error(note: Need to define dmic48k pipeline id for intel-generic-dmic-kwd -)') -ifdef(`DMIC_DAI_LINK_48k_ID',`',`fatal_error(note: Need to define dmic48k dai id for intel-generic-dmic-kwd -)') - -ifdef(`DMIC_PCM_16k_ID',`',`fatal_error(note: Need to define dmic16k pcm id for intel-generic-dmic-kwd -)') -ifdef(`DMIC_PIPELINE_16k_ID',`',`fatal_error(note: Need to define dmic16k pipeline id for intel-generic-dmic-kwd -)') -ifdef(`DMIC_PIPELINE_KWD_ID',`',`fatal_error(note: Need to define kwd pipeline id for intel-generic-dmic-kwd -)') -ifdef(`DMIC_DAI_LINK_16k_ID',`',`fatal_error(note: Need to define dmic16k dai id for intel-generic-dmic-kwd -)') - -# define(KWD_PIPE_SCH_DEADLINE_US, 20000) -ifdef(`KWD_PIPE_SCH_DEADLINE_US',`',`fatal_error(note: Need to define schedule for intel-generic-dmic-kwd -)') - -# define(DMIC_DAI_LINK_48k_NAME, `dmic01') -ifdef(`DMIC_DAI_LINK_48k_NAME',`',define(DMIC_DAI_LINK_48k_NAME, `dmic01')) - -# define(DMIC_PIPELINE_48k_CORE_ID, 0) -ifdef(`DMIC_PIPELINE_48k_CORE_ID',`',define(DMIC_PIPELINE_48k_CORE_ID, 0)) - -# define(DMIC_DAI_LINK_16k_NAME, `dmic16k') -ifdef(`DMIC_DAI_LINK_16k_NAME',`',define(DMIC_DAI_LINK_16k_NAME, `dmic16k')) - -# DMICPROC is set by makefile, available type: passthrough/eq-iir-volume -ifdef(`DMICPROC', `', `define(DMICPROC, passthrough)') - -dnl Unless explicitly specified, dmic period at 48k is 1ms -ifdef(`DMIC_48k_PERIOD_US', `', `define(`DMIC_48k_PERIOD_US', 1000)') - -# define(DMIC_DAI_LINK_16k_PDM, `STEREO_PDM0') define the PDM port, default is STEREO_PDM0 -ifdef(`DMIC_DAI_LINK_16k_PDM',`',`define(DMIC_DAI_LINK_16k_PDM, `STEREO_PDM0')') - -# define(DETECTOR_TYPE, `google-hotword-detect') define the detector type, default is the test detector -ifdef(`DETECTOR_TYPE',`',define(DETECTOR_TYPE, `detect')) - -# -# Define the pipelines -# - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp) - -# Passthrough capture pipeline using max channels defined by CHANNELS. - -# Set 1000us deadline with priority 0 on core 0 -ifdef(`DMICPROC_FILTER1', `define(PIPELINE_FILTER1, DMICPROC_FILTER1)', `undefine(`PIPELINE_FILTER1')') -ifdef(`DMICPROC_FILTER2', `define(PIPELINE_FILTER2, DMICPROC_FILTER2)', `undefine(`PIPELINE_FILTER2')') -define(`PGA_NAME', Dmic0) - -PIPELINE_PCM_ADD(sof/pipe-`DMICPROC'-capture.m4, - DMIC_PIPELINE_48k_ID, DMIC_PCM_48k_ID, CHANNELS, s32le, - DMIC_48k_PERIOD_US, 0, DMIC_PIPELINE_48k_CORE_ID, 48000, 48000, 48000) -undefine(`PGA_NAME') -undefine(`PIPELINE_FILTER1') -undefine(`PIPELINE_FILTER2') -undefine(`DMICPROC') - -# -# KWD configuration -# - -# Passthrough capture pipeline 7 on PCM 7 using max 2 channels. -# Schedule 20000us deadline with priority 0 on core 0 -PIPELINE_PCM_DAI_ADD(sof/pipe-KFBM_TYPE-capture.m4, - DMIC_PIPELINE_16k_ID, DMIC_PCM_16k_ID, 2, s32le, - KWD_PIPE_SCH_DEADLINE_US, 0, 0, DMIC, 1, s32le, 3, - 16000, 16000, 16000) - - - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl deadline, priority, core, time_domain) - -# capture DAI is DMIC 0 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-capture.m4, - DMIC_PIPELINE_48k_ID, DMIC, 0, DMIC_DAI_LINK_48k_NAME, - concat(`PIPELINE_SINK_', DMIC_PIPELINE_48k_ID), 2, s32le, - DMIC_48k_PERIOD_US, 0, DMIC_PIPELINE_48k_CORE_ID, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is DMIC 1 using 3 periods -# Buffers use s32le format, with 320 frame per 20000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - DMIC_PIPELINE_16k_ID, DMIC, 1, DMIC_DAI_LINK_16k_NAME, - `PIPELINE_SINK_'DMIC_PIPELINE_16k_ID, 3, s32le, - KWD_PIPE_SCH_DEADLINE_US, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -dnl PCM_DUPLEX_ADD(name, pcm_id, playback, capture) -dnl PCM_CAPTURE_ADD(name, pipeline, capture) -PCM_CAPTURE_ADD(DMIC_48k_PCM_NAME, DMIC_PCM_48k_ID, concat(`PIPELINE_PCM_', DMIC_PIPELINE_48k_ID)) - -# keyword detector pipe -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp, dynamic) -PIPELINE_PCM_ADD(sof/pipe-DETECTOR_TYPE.m4, - DMIC_PIPELINE_KWD_ID, DMIC_PCM_16k_ID, 2, s24le, - KWD_PIPE_SCH_DEADLINE_US, 1, 0, - 16000, 16000, 16000, - SCHEDULE_TIME_DOMAIN_TIMER, - `PIPELINE_SCHED_COMP_'DMIC_PIPELINE_16k_ID) - -# Connect pipelines together -SectionGraph."pipe-sof-generic-keyword-detect" { - index "0" - - lines [ - # keyword detect - dapm(`PIPELINE_SINK_'DMIC_PIPELINE_KWD_ID, `PIPELINE_SOURCE_'DMIC_PIPELINE_16k_ID) - dapm(`PIPELINE_PCM_'DMIC_PIPELINE_16k_ID, `PIPELINE_DETECT_'DMIC_PIPELINE_KWD_ID) - ] -} - -# -# BE configurations - overrides config in ACPI if present -# - -dnl DAI_CONFIG(type, dai_index, link_id, name, ssp_config/dmic_config) -ifelse(CHANNELS, 4, -`DAI_CONFIG(DMIC, 0, DMIC_DAI_LINK_48k_ID, DMIC_DAI_LINK_48k_NAME, - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, - DMIC_WORD_LENGTH(s32le), 200, DMIC, 0, - PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1)))', -`DAI_CONFIG(DMIC, 0, DMIC_DAI_LINK_48k_ID, DMIC_DAI_LINK_48k_NAME, - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, - DMIC_WORD_LENGTH(s32le), 200, DMIC, 0, - PDM_CONFIG(DMIC, 0, STEREO_PDM0)))') - -# dmic16k (ID: 2) -DAI_CONFIG(DMIC, 1, DMIC_DAI_LINK_16k_ID, DMIC_DAI_LINK_16k_NAME, - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, - DMIC_WORD_LENGTH(s32le), 400, DMIC, 1, - PDM_CONFIG(DMIC, 1, DMIC_DAI_LINK_16k_PDM))) diff --git a/tools/topology/topology1/platform/intel/intel-generic-dmic.m4 b/tools/topology/topology1/platform/intel/intel-generic-dmic.m4 deleted file mode 100644 index 63be50e05b93..000000000000 --- a/tools/topology/topology1/platform/intel/intel-generic-dmic.m4 +++ /dev/null @@ -1,178 +0,0 @@ -# -# Topology for digital microphones array -# - -include(`platform/intel/dmic.m4') - -# define default PCM names -ifdef(`DMIC_48k_PCM_NAME',`', -`define(DMIC_48k_PCM_NAME, `DMIC')') -ifdef(`DMIC_16k_PCM_NAME',`', -`define(DMIC_16k_PCM_NAME, `DMIC16kHz')') - -ifdef(`DMIC_48k_PRIORITY', `', -`define(DMIC_48k_PRIORITY, 0)') - -# variable that need to be defined in upper m4 -ifdef(`DMICPROC',`',`fatal_error(note: Need to define dmic processing for intel-generic-dmic -)') -ifdef(`CHANNELS',`',`fatal_error(note: Need to define channel number for intel-generic-dmic -)') -ifdef(`DMIC_PCM_48k_ID',`',`fatal_error(note: Need to define dmic48k pcm id for intel-generic-dmic -)') -ifdef(`DMIC_PIPELINE_48k_ID',`',`fatal_error(note: Need to define dmic48k pipeline id for intel-generic-dmic -)') -ifdef(`DMIC_DAI_LINK_48k_ID',`',`fatal_error(note: Need to define dmic48k dai id for intel-generic-dmic -)') - -ifdef(`DMIC_PCM_16k_ID',`',`fatal_error(note: Need to define dmic16k pcm id for intel-generic-dmic -)') -ifdef(`DMIC_PIPELINE_16k_ID',`',`fatal_error(note: Need to define dmic16k pipeline id for intel-generic-dmic -)') -ifdef(`DMIC_DAI_LINK_16k_ID',`',`fatal_error(note: Need to define dmic16k dai id for intel-generic-dmic -)') - -# define(DMIC_DAI_LINK_48k_NAME, `dmic01') -ifdef(`DMIC_DAI_LINK_48k_NAME',`',define(DMIC_DAI_LINK_48k_NAME, `dmic01')) - -# define(DMIC_DAI_LINK_16k_NAME, `dmic16k') -ifdef(`DMIC_DAI_LINK_16k_NAME',`',define(DMIC_DAI_LINK_16k_NAME, `dmic16k')) - -ifdef(`DMIC_48k_CORE_ID',`', define(DMIC_48k_CORE_ID, `0')) -ifdef(`DMIC_16k_CORE_ID',`', define(DMIC_16k_CORE_ID, `0')) - -# Handle possible different channels count for PCM and DAI -ifdef(`DMIC_DAI_CHANNELS', `', `define(DMIC_DAI_CHANNELS, CHANNELS)') -ifdef(`DMIC_PCM_CHANNELS', `', `define(DMIC_PCM_CHANNELS, CHANNELS)') -ifdef(`DMIC16K_DAI_CHANNELS', `', `define(DMIC16K_DAI_CHANNELS, CHANNELS)') -ifdef(`DMIC16K_PCM_CHANNELS', `', `define(DMIC16K_PCM_CHANNELS, CHANNELS)') - -dnl Unless explicitly specified, dmic period at 48k is 1ms -ifdef(`DMIC_48k_PERIOD_US', `', `define(DMIC_48k_PERIOD_US, 1000)') - -define(`INTEL_GENERIC_DMIC_PERIOD', 1000) - -ifelse(CHANNELS, 1, `define(`VOLUME_CHANNEL_MAP', LIST(` ', KCONTROL_CHANNEL(FL, 1, 0)))') -ifelse(CHANNELS, 2, `define(`VOLUME_CHANNEL_MAP', LIST(` ', KCONTROL_CHANNEL(FL, 1, 0), - KCONTROL_CHANNEL(FR, 1, 1)))') -ifelse(CHANNELS, 3, `define(`VOLUME_CHANNEL_MAP', LIST(` ', KCONTROL_CHANNEL(FL, 1, 0), - KCONTROL_CHANNEL(FC, 1, 1), - KCONTROL_CHANNEL(FR, 1, 2)))') -ifelse(CHANNELS, 4, `define(`VOLUME_CHANNEL_MAP', LIST(` ', KCONTROL_CHANNEL(FLW, 1, 0), - KCONTROL_CHANNEL(FL, 1, 1), - KCONTROL_CHANNEL(FR, 1, 2), - KCONTROL_CHANNEL(FRW, 1, 3)))') - -ifelse(CHANNELS, 1, `define(`SWITCH_CHANNEL_MAP', LIST(` ', KCONTROL_CHANNEL(FL, 2, 0)))') -ifelse(CHANNELS, 2, `define(`SWITCH_CHANNEL_MAP', LIST(` ', KCONTROL_CHANNEL(FL, 2, 0), - KCONTROL_CHANNEL(FR, 2, 1)))') -ifelse(CHANNELS, 3, `define(`SWITCH_CHANNEL_MAP', LIST(` ', KCONTROL_CHANNEL(FL, 2, 0), - KCONTROL_CHANNEL(FC, 2, 1), - KCONTROL_CHANNEL(FR, 2, 2)))') -ifelse(CHANNELS, 4, `define(`SWITCH_CHANNEL_MAP', LIST(` ', KCONTROL_CHANNEL(FLW, 2, 0), - KCONTROL_CHANNEL(FL, 2, 1), - KCONTROL_CHANNEL(FR, 2, 2), - KCONTROL_CHANNEL(FRW, 2, 3)))') -# -# Define the pipelines -# - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp) - -# Passthrough capture pipeline using max channels defined by DMIC_PCM_CHANNELS. - -# Set 1000us deadline with priority 0 on core 0 -ifdef(`DMICPROC_FILTER1', `define(PIPELINE_FILTER1, DMICPROC_FILTER1)', `undefine(`PIPELINE_FILTER1')') -ifdef(`DMICPROC_FILTER2', `define(PIPELINE_FILTER2, DMICPROC_FILTER2)', `undefine(`PIPELINE_FILTER2')') -define(`PGA_NAME', Dmic0) - -PIPELINE_PCM_ADD(sof/pipe-DMICPROC-capture.m4, - DMIC_PIPELINE_48k_ID, DMIC_PCM_48k_ID, DMIC_PCM_CHANNELS, s32le, - DMIC_48k_PERIOD_US, 0, DMIC_48k_CORE_ID, 48000, 48000, 48000) - -undefine(`PGA_NAME') -undefine(`PIPELINE_FILTER1') -undefine(`PIPELINE_FILTER2') - -# Passthrough capture pipeline using max channels defined by CHANNELS. - -# Schedule with 1000us deadline with priority 0 on core 0 -ifdef(`DMIC16KPROC_FILTER1', `define(PIPELINE_FILTER1, DMIC16KPROC_FILTER1)', `undefine(`PIPELINE_FILTER1')') -ifdef(`DMIC16KPROC_FILTER2', `define(PIPELINE_FILTER2, DMIC16KPROC_FILTER2)', `undefine(`PIPELINE_FILTER2')') -define(`PGA_NAME', Dmic1) - -ifdef(NO16KDMIC, `', -`PIPELINE_PCM_ADD(sof/pipe-DMIC16KPROC-capture-16khz.m4, - DMIC_PIPELINE_16k_ID, DMIC_PCM_16k_ID, DMIC16K_PCM_CHANNELS, s32le, - INTEL_GENERIC_DMIC_PERIOD, 0, DMIC_16k_CORE_ID, 16000, 16000, 16000)') - -undefine(`PGA_NAME') -undefine(`PIPELINE_FILTER1') -undefine(`PIPELINE_FILTER2') -undefine(`VOLUME_CHANNEL_MAP') -undefine(`SWITCH_CHANNEL_MAP') - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl deadline, priority, core, time_domain) - -# capture DAI is DMIC 0 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-capture.m4, - DMIC_PIPELINE_48k_ID, DMIC, 0, DMIC_DAI_LINK_48k_NAME, - concat(`PIPELINE_SINK_', DMIC_PIPELINE_48k_ID), 2, s32le, - DMIC_48k_PERIOD_US, DMIC_48k_PRIORITY, DMIC_48k_CORE_ID, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is DMIC 1 using 2 periods -# Buffers use s32le format, with 16 frame per 1000us on core 0 with priority 0 -ifdef(NO16KDMIC, `', -`DAI_ADD(sof/pipe-dai-capture.m4, - DMIC_PIPELINE_16k_ID, DMIC, 1, DMIC_DAI_LINK_16k_NAME, - concat(`PIPELINE_SINK_', DMIC_PIPELINE_16k_ID), 2, s32le, - INTEL_GENERIC_DMIC_PERIOD, 0, DMIC_16k_CORE_ID, SCHEDULE_TIME_DOMAIN_TIMER)') - -dnl PCM_DUPLEX_ADD(name, pcm_id, playback, capture) -dnl PCM_CAPTURE_ADD(name, pipeline, capture) -PCM_CAPTURE_ADD(DMIC_48k_PCM_NAME, DMIC_PCM_48k_ID, concat(`PIPELINE_PCM_', DMIC_PIPELINE_48k_ID)) - -ifdef(NO16KDMIC, `', -`PCM_CAPTURE_ADD(DMIC_16k_PCM_NAME, DMIC_PCM_16k_ID, concat(`PIPELINE_PCM_', DMIC_PIPELINE_16k_ID))') - -ifdef(`PDM1',`define(DEF_STEREO_PDM, `STEREO_PDM1')',`define(DEF_STEREO_PDM, `STEREO_PDM0')') - -# -# BE configurations - overrides config in ACPI if present -# - -dnl DAI_CONFIG(type, dai_index, link_id, name, ssp_config/dmic_config) -ifelse(DMIC_DAI_CHANNELS, 4, -`DAI_CONFIG(DMIC, 0, DMIC_DAI_LINK_48k_ID, DMIC_DAI_LINK_48k_NAME, - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, - DMIC_WORD_LENGTH(s32le), 200, DMIC, 0, - PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1)))', -`DAI_CONFIG(DMIC, 0, DMIC_DAI_LINK_48k_ID, DMIC_DAI_LINK_48k_NAME, - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, - DMIC_WORD_LENGTH(s32le), 200, DMIC, 0, - PDM_CONFIG(DMIC, 0, DEF_STEREO_PDM)))') - -ifdef(NO16KDMIC, `', -`ifelse(DMIC16K_DAI_CHANNELS, 4, -`DAI_CONFIG(DMIC, 1, DMIC_DAI_LINK_16k_ID, DMIC_DAI_LINK_16k_NAME, - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, - DMIC_WORD_LENGTH(s32le), 400, DMIC, 1, - PDM_CONFIG(DMIC, 1, FOUR_CH_PDM0_PDM1)))', -`DAI_CONFIG(DMIC, 1, DMIC_DAI_LINK_16k_ID, DMIC_DAI_LINK_16k_NAME, - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, - DMIC_WORD_LENGTH(s32le), 400, DMIC, 1, - PDM_CONFIG(DMIC, 1, DEF_STEREO_PDM)))')') - -undefine(DEF_STEREO_PDM) diff --git a/tools/topology/topology1/platform/intel/intel-hdmi-ssp.m4 b/tools/topology/topology1/platform/intel/intel-hdmi-ssp.m4 deleted file mode 100644 index afe48b4adad3..000000000000 --- a/tools/topology/topology1/platform/intel/intel-hdmi-ssp.m4 +++ /dev/null @@ -1,53 +0,0 @@ -# -# HDMI-SSP Audio Offload support -# - -include(`ssp.m4') - -define(`HDMI_SSP_NAME', concat(concat(`SSP', HDMI_SSP_NUM),`-HDMI')) -define(`HDMI_SSP_PCM_NAME', concat(concat(`HDMI-', HDMI_SSP_NUM),`-In')) - -# variable that need to be defined in upper m4 -ifdef(`HDMI_SSP_PIPELINE_CP_ID',`',`fatal_error(note: Need to define capture pcm id for ssp intel-hdmi-in -)') -ifdef(`HDMI_SSP_DAI_LINK_ID',`',`fatal_error(note: Need to define DAI link id for ssp intel-hdmi-in -)') -ifdef(`HDMI_SSP_PCM_ID',`',`fatal_error(note: Need to define pipeline PCM dev id for ssp intel-hdmi-in -)') - - -# Low Latency capture pipeline 4 on PCM HDMI_SSP_PCM_ID using max 2 channels of s32le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-low-latency-capture.m4, - HDMI_SSP_PIPELINE_CP_ID, HDMI_SSP_PCM_ID, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - - -# capture DAI is SSP using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-capture.m4, - HDMI_SSP_PIPELINE_CP_ID, SSP, HDMI_SSP_NUM, HDMI_SSP_NAME, - concat(`PIPELINE_SINK_', HDMI_SSP_PIPELINE_CP_ID), 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_DMA) - - -PCM_CAPTURE_ADD(HDMI_SSP_PCM_NAME, HDMI_SSP_PCM_ID, concat(`PIPELINE_PCM_', HDMI_SSP_PIPELINE_CP_ID)) - - -#BE configuration in slave mode -DAI_CONFIG(SSP, HDMI_SSP_NUM, HDMI_SSP_DAI_LINK_ID, HDMI_SSP_NAME, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, 24576000, codec_mclk_in), - SSP_CLOCK(bclk, 3072000, codec_provider), - SSP_CLOCK(fsync, 48000, codec_provider), - SSP_TDM(2, 32, 3, 3), - SSP_CONFIG_DATA(SSP, HDMI_SSP_NUM, 32, 0))) - - -undefine(`HDMI_SSP_PIPELINE_CP_ID') -undefine(`HDMI_SSP_DAI_LINK_ID') -undefine(`HDMI_SSP_PCM_ID') dnl use fixed PCM_ID -undefine(`HDMI_SSP_NUM') -undefine(`HDMI_SSP_NAME') -undefine(`HDMI_SSP_PCM_NAME') - diff --git a/tools/topology/topology1/platform/intel/rpl.m4 b/tools/topology/topology1/platform/intel/rpl.m4 deleted file mode 100644 index a36e847e9bad..000000000000 --- a/tools/topology/topology1/platform/intel/rpl.m4 +++ /dev/null @@ -1,6 +0,0 @@ -# -# Raptor Lake differentiation for pipelines and components -# - -# no difference yet, use Alder Lake definitions -include(`platform/intel/adl.m4') diff --git a/tools/topology/topology1/platform/intel/tgl.m4 b/tools/topology/topology1/platform/intel/tgl.m4 deleted file mode 100644 index f058b2025bbb..000000000000 --- a/tools/topology/topology1/platform/intel/tgl.m4 +++ /dev/null @@ -1,38 +0,0 @@ -# -# Tigerlake differentiation for pipelines and components -# - -include(`memory.m4') - -dnl Memory capabilities for different buffer types on Tigerlake -define(`PLATFORM_DAI_MEM_CAP', - MEMCAPS(MEM_CAP_RAM, MEM_CAP_DMA, MEM_CAP_CACHE, MEM_CAP_HP)) -define(`PLATFORM_HOST_MEM_CAP', - MEMCAPS(MEM_CAP_RAM, MEM_CAP_DMA, MEM_CAP_CACHE, MEM_CAP_HP)) -define(`PLATFORM_PASS_MEM_CAP', - MEMCAPS(MEM_CAP_RAM, MEM_CAP_DMA, MEM_CAP_CACHE, MEM_CAP_HP)) -define(`PLATFORM_COMP_MEM_CAP', MEMCAPS(MEM_CAP_RAM, MEM_CAP_CACHE)) - -# Low Latency PCM Configuration -W_VENDORTUPLES(pipe_ll_schedule_plat_tokens, sof_sched_tokens, - LIST(` ', `SOF_TKN_SCHED_MIPS "50000"')) - -W_DATA(pipe_ll_schedule_plat, pipe_ll_schedule_plat_tokens) - -# Media PCM Configuration -W_VENDORTUPLES(pipe_media_schedule_plat_tokens, sof_sched_tokens, - LIST(` ', `SOF_TKN_SCHED_MIPS "100000"')) - -W_DATA(pipe_media_schedule_plat, pipe_media_schedule_plat_tokens) - -# Tone Signal Generator Configuration -W_VENDORTUPLES(pipe_tone_schedule_plat_tokens, sof_sched_tokens, - LIST(` ', `SOF_TKN_SCHED_MIPS "200000"')) - -W_DATA(pipe_tone_schedule_plat, pipe_tone_schedule_plat_tokens) - -# DAI schedule Configuration - scheduled by IRQ -W_VENDORTUPLES(pipe_dai_schedule_plat_tokens, sof_sched_tokens, - LIST(` ', `SOF_TKN_SCHED_MIPS "5000"')) - -W_DATA(pipe_dai_schedule_plat, pipe_dai_schedule_plat_tokens) diff --git a/tools/topology/topology1/sof-acp_6_3.m4 b/tools/topology/topology1/sof-acp_6_3.m4 new file mode 100644 index 000000000000..88204638d9ac --- /dev/null +++ b/tools/topology/topology1/sof-acp_6_3.m4 @@ -0,0 +1,98 @@ +# +# Topology for ACP_6_3 with I2SHS and DMIC. +# + +# Include topology builder +include(`utils.m4') +include(`dai.m4') +include(`pipeline.m4') +include(`acp-hs.m4') +include(`acp-dmic.m4') + +# Include TLV library +include(`common/tlv.m4') + +# Include Token library +include(`sof/tokens.m4') + +# Include ACP DSP configuration +include(`platform/amd/acp.m4') + +DEBUG_START +#====================================================================== +# Playback pipeline 1 on PCM 0 using max 2 channels of s16le. + +dnl PIPELINE_PCM_ADD(pipeline, +dnl pipe id, pcm, max channels, format, +dnl period, priority, core, +dnl pcm_min_rate, pcm_max_rate, pipeline_rate) + +# Schedule 96 frames per 2000us deadline on core 0 with priority 0 +PIPELINE_PCM_ADD(sof/pipe-passthrough-playback.m4, + 1, 0, 2, s16le, + 2000, 0, 0, + 48000, 48000, 48000) + +dnl DAI_ADD(pipeline, +dnl pipe id, dai type, dai_index, dai_be, +dnl buffer, periods, format, +dnl deadline, priority, core, time_domain) + +# playback DAI is ACPHS using 2 periods +DAI_ADD(sof/pipe-dai-playback.m4, + 1, ACPHS, 0, acp-headset-codec, + PIPELINE_SOURCE_1, 2, s16le, + 2000, 0, 0, SCHEDULE_TIME_DOMAIN_DMA) + +dnl DAI_CONFIG(type, dai_index, link_id, name, acphs_config/acpdmic_config) +dnl ACPHS_CONFIG(format, mclk, bclk, fsync, tdm, acphs_config_data) +dnl ACP_CLOCK(clock, freq, codec_master, polarity) +dnl ACPHS_CONFIG_DATA(type, idx, valid bits, mclk_id) +dnl mclk_id is optional + +DAI_CONFIG(ACPHS, 0, 0, acp-headset-codec, + ACPHS_CONFIG(I2S, ACP_CLOCK(mclk, 49152000, codec_mclk_in), + ACP_CLOCK(bclk, 3072000, codec_slave), + ACP_CLOCK(fsync, 48000, codec_slave), + ACP_TDM(2, 32, 3, 3),ACPHS_CONFIG_DATA(ACPHS, 0, 48000, 2, 0))) + +#=========================================================================== +# Capture pipeline 2 on PCM 0 using max 2 channels of s16le. +PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, + 2, 0, 2, s16le, + 2000, 0, 0, + 48000, 48000, 48000) + +# Capture DAI is ACPHS using 2 periods +DAI_ADD(sof/pipe-dai-capture.m4, + 2, ACPHS, 0, acp-headset-codec, + PIPELINE_SINK_2, 2, s16le, + 2000, 0, 0, SCHEDULE_TIME_DOMAIN_DMA) + +#=========================================================================== +# PCM id 0 +PCM_DUPLEX_ADD(I2SHS, 0, PIPELINE_PCM_1, PIPELINE_PCM_2) + +#========================================================================== +# Capture pipeline 3 on PCM 1 using max 2 channels of s32le. +PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, + 4, 2, 2, s32le, + 2000, 0, 0, + 48000, 48000, 48000) + +DAI_ADD(sof/pipe-dai-capture.m4, + 4, ACPDMIC, 0, acp-dmic-codec, + PIPELINE_SINK_4, 2, s32le, + 2000, 0, 0, SCHEDULE_TIME_DOMAIN_DMA) + +#dnl DAI_CONFIG(type, dai_index, link_id, name, acpdmic_config) +DAI_CONFIG(ACPDMIC, 3, 2, acp-dmic-codec, + ACPDMIC_CONFIG(ACPDMIC_CONFIG_DATA(ACPDMIC, 3, 48000, 2))) + +#========================================================================== +# PCM id 2 +PCM_CAPTURE_ADD(DMIC, 2, PIPELINE_PCM_4) + +#========================================================================== + +DEBUG_END diff --git a/tools/topology/topology1/sof-adl-nau8825.m4 b/tools/topology/topology1/sof-adl-nau8825.m4 deleted file mode 100644 index d2feb681197d..000000000000 --- a/tools/topology/topology1/sof-adl-nau8825.m4 +++ /dev/null @@ -1,400 +0,0 @@ -# -# Topology for Alderlake with headphone, DMIC, HDMI with/without speaker. -# - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`ssp.m4') -include(`hda.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include Alderlake DSP configuration -include(`platform/intel/adl.m4') -include(`platform/intel/dmic.m4') - -DEBUG_START - -ifdef(`NO_AMP',,` -ifdef(`AMP_SSP',`',`fatal_error(note: Define AMP_SSP for speaker amp SSP Index)')') - -ifdef(`NO_AMP',,` -ifdef(`SMART_AMP',,` -include(`muxdemux.m4') - -# -# Define the demux configure -# -# PCM0 --> volume --> demux --> SSP1/SSP2 (speaker - max98360a/rt1019) -# | -# PCM6 <----------------+ - -#define speaker SSP index -define(`SPK_SSP_INDEX', AMP_SSP) -# define SSP BE dai_link name -define(`SPK_SSP_NAME', concat(concat(`SSP', SPK_SSP_INDEX),`-Codec')) -# define BE dai_link ID -define(`SPK_BE_ID', 7) -# Ref capture related -# Ref capture BE dai_name -define(`SPK_REF_DAI_NAME', concat(concat(`SSP', SPK_SSP_INDEX),`.IN')) -define(`DEMUX_ROUTE')')') -ifdef(`DEMUX_ROUTE', -dnl Configure demux -dnl name, pipeline_id, routing_matrix_rows -dnl Diagonal 1's in routing matrix mean that every input channel is -dnl copied to corresponding output channels in all output streams. -dnl I.e. row index is the input channel, 1 means it is copied to -dnl corresponding output channel (column index), 0 means it is discarded. -dnl There's a separate matrix for all outputs. -`define(matrix1, `ROUTE_MATRIX(1, - `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 1 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,1 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,1 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,1 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,1 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,1)')')' - -`define(matrix2, `ROUTE_MATRIX(9, - `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 1 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,1 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,1 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,1 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,1 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,1)')')' - -dnl name, num_streams, route_matrix list -`MUXDEMUX_CONFIG(demux_priv_1, 2, LIST_NONEWLINE(`', `matrix1,', `matrix2'))') - -ifdef(`NO_AMP',,` -ifdef(`SMART_AMP',` -# PCM0 ----> smart_amp ----> SSP1 (Speaker - max98373) -# ^ -# | -# | -# PCM0 <---- demux <----- SSP1 (Speaker - max98373)')') -# PCM1 <---> volume <----> SSP0 (Headset - NAU8825) -# PCM2 ----> volume -----> iDisp1 -# PCM3 ----> volume -----> iDisp2 -# PCM4 ----> volume -----> iDisp3 -# PCM5 ----> volume -----> iDisp4 -ifdef(`BT_OFFLOAD', ` -# PCM7 ----> passthrough ----> SSP2 (Bluetooth)') -# PCM99 <---- volume <---- DMIC01 (dmic 48k capture) -# PCM100 <---- kpb <---- DMIC16K (dmic 16k capture) - -ifdef(`SPK_MIC_PERIOD_US',`', `define(`SPK_MIC_PERIOD_US', 1000)') - -# Run Speakers pipeline on core#1 by default for low power considering -ifdef(`SPK_PLAYBACK_CORE', `', `define(`SPK_PLAYBACK_CORE', `1')') - -ifdef(`NO_AMP',,` -ifdef(`SMART_AMP',` -# Smart amplifier related -# SSP related -#define smart amplifier SSP index -define(`SMART_SSP_INDEX', AMP_SSP) -#define SSP BE dai_link name -define(`SMART_SSP_NAME', concat(concat(`SSP', AMP_SSP),`-Codec')) -#define BE dai_link ID -define(`SMART_BE_ID', 7) -#define SSP mclk -define(`SSP_MCLK', 24576000) -#define Core ID -define(`SMART_AMP_CORE', SPK_PLAYBACK_CORE) -# Playback related -define(`SMART_PB_PPL_ID', 1) -define(`SMART_PB_CH_NUM', 2) -define(`SMART_TX_CHANNELS', 4) -define(`SMART_RX_CHANNELS', 4) -define(`SMART_FB_CHANNELS', 4) -# Ref capture related -define(`SMART_REF_PPL_ID', 11) -define(`SMART_REF_CH_NUM', 2) -# PCM related -define(`SMART_PCM_ID', 0) -define(`SMART_PCM_NAME', `smart373-spk') - -# Include Smart Amplifier support -ifdef(`DTS',` -include(`sof-eq-iir-dts-codec-smart-amplifier.m4')',` -include(`sof-smart-amplifier.m4')')')') - -# Define pipeline id for intel-generic-dmic-kwd.m4 -# to generate dmic setting with kwd when we have dmic -# define channel -define(CHANNELS, `4') -# define kfbm with volume -define(KFBM_TYPE, `vol-kfbm') -# define pcm, pipeline and dai id -define(DMIC_PCM_48k_ID, `99') -define(DMIC_PIPELINE_48k_ID, `4') -define(DMIC_DAI_LINK_48k_ID, `1') -define(DMIC_PCM_16k_ID, `100') -define(DMIC_PIPELINE_16k_ID, `12') -define(DMIC_PIPELINE_KWD_ID, `13') -define(DMIC_DAI_LINK_16k_ID, `2') -# Offload DMIC_PIPELINE_48K to secondary core for IGO. -ifdef(`IGO', `define(`DMIC_PIPELINE_48k_CORE_ID', 1)') -# define pcm, pipeline and dai id -define(KWD_PIPE_SCH_DEADLINE_US, 20000) -# include the generic dmic with kwd -ifdef(`NOHOTWORD', -` -define(NO16KDMIC) -define(DMIC_48k_CORE_ID, 1) -define(DMICPROC, passthrough) -include(`platform/intel/intel-generic-dmic.m4')', -`include(`platform/intel/intel-generic-dmic-kwd.m4')') - -# define(`SSP_MCLK', ) -ifdef(`SSP_MCLK',`',`define(`SSP_MCLK', 19200000)') - -ifdef(`BT_OFFLOAD', ` -define(`BT_PIPELINE_PB_ID', eval(DMIC_PIPELINE_KWD_ID + 1)) -define(`BT_PIPELINE_CP_ID', eval(DMIC_PIPELINE_KWD_ID + 2)) -define(`BT_DAI_LINK_ID', 7) - -ifdef(`AMP_SSP',` -define(`BT_DAI_LINK_ID', 8)') - -define(`BT_PCM_ID', `7') -define(`HW_CONFIG_ID', eval(BT_DAI_LINK_ID)) -include(`platform/intel/intel-generic-bt.m4')') - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate) - -ifdef(`NO_AMP',,` -ifdef(`SMART_AMP',,` -# Low Latency playback pipeline 1 on PCM 0 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-demux-playback.m4, - 1, 0, 2, s32le, - SPK_MIC_PERIOD_US, 0, SPK_PLAYBACK_CORE, - 48000, 48000, 48000)')') - -# Low Latency playback pipeline 2 on PCM 1 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD( -ifdef(`DTS', sof/pipe-eq-iir-dts-codec-playback.m4, sof/pipe-volume-playback.m4), - 2, 1, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency capture pipeline 3 on PCM 1 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, - 3, 1, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 5 on PCM 2 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 5, 2, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 6 on PCM 3 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 6, 3, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 7 on PCM 4 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 7, 4, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 8 on PCM 5 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 8, 5, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl deadline, priority, core, time_domain) - -# playback DAI is SSP0 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 2, SSP, 0, SSP0-Codec, - PIPELINE_SOURCE_2, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is SSP0 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 3, SSP, 0, SSP0-Codec, - PIPELINE_SINK_3, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp1 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 5, HDA, 0, iDisp1, - PIPELINE_SOURCE_5, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 6, HDA, 1, iDisp2, - PIPELINE_SOURCE_6, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 7, HDA, 2, iDisp3, - PIPELINE_SOURCE_7, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp4 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 8, HDA, 3, iDisp4, - PIPELINE_SOURCE_8, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -ifdef(`NO_AMP',,` -ifdef(`SMART_AMP',,` -# playback DAI is SSP1 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 1, SSP, SPK_SSP_INDEX, SPK_SSP_NAME, - PIPELINE_SOURCE_1, 2, FMT, - SPK_MIC_PERIOD_US, 0, SPK_PLAYBACK_CORE, SCHEDULE_TIME_DOMAIN_TIMER) - -# The echo refenrence pipeline has no connections in it, -# it is used for the capture DAI widget to dock. -DAI_ADD(sof/pipe-echo-ref-dai-capture.m4, - 29, SSP, SPK_SSP_INDEX, SPK_SSP_NAME, - PIPELINE_SINK_29, 3, FMT, - 1000, 0, SPK_PLAYBACK_CORE, SCHEDULE_TIME_DOMAIN_TIMER) - -# Capture pipeline 9 from demux on PCM 6 using max 2 channels of s32le. -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture-sched.m4, - 9, 6, 2, s32le, - 1000, 1, SPK_PLAYBACK_CORE, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) - -# Connect demux to capture -SectionGraph."PIPE_CAP" { - index "0" - - lines [ - # mux to capture - dapm(PIPELINE_SINK_9, PIPELINE_DEMUX_1) - ] -} - -# Connect virtual capture to dai -SectionGraph."PIPE_CAP_VIRT" { - index "9" - - lines [ - # mux to capture - dapm(ECHO REF 9, SPK_REF_DAI_NAME) - ] -}')') - -# -# Bind PCM with the pipeline -# -dnl PCM_PLAYBACK_ADD(name, pcm_id, playback, capture) -PCM_DUPLEX_ADD(Headset, 1, PIPELINE_PCM_2, PIPELINE_PCM_3) -PCM_PLAYBACK_ADD(HDMI1, 2, PIPELINE_PCM_5) -PCM_PLAYBACK_ADD(HDMI2, 3, PIPELINE_PCM_6) -PCM_PLAYBACK_ADD(HDMI3, 4, PIPELINE_PCM_7) -PCM_PLAYBACK_ADD(HDMI4, 5, PIPELINE_PCM_8) -ifdef(`NO_AMP',,` -ifdef(`SMART_AMP',,` -PCM_PLAYBACK_ADD(Speakers, 0, PIPELINE_PCM_1) -PCM_CAPTURE_ADD(EchoRef, 6, PIPELINE_PCM_9)')') - -# -# BE configurations - overrides config in ACPI if present -# -dnl DAI_CONFIG(type, dai_index, link_id, name, ssp_config/dmic_config) -dnl SSP_CONFIG(format, mclk, bclk, fsync, tdm, ssp_config_data) -dnl SSP_CLOCK(clock, freq, codec_master, polarity) -dnl SSP_CONFIG_DATA(type, idx, valid bits, mclk_id) -dnl mclk_id is optional -dnl ssp1-maxmspk - -#SSP 0 (ID: 0) -DAI_CONFIG(SSP, 0, 0, SSP0-Codec, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, SSP_MCLK, codec_mclk_in), - SSP_CLOCK(bclk, 3072000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 32, 3, 3), - SSP_CONFIG_DATA(SSP, 0, 32, 0, 0, 0, SSP_CC_BCLK_ES))) - -# 4 HDMI/DP outputs (ID: 3,4,5,6) -DAI_CONFIG(HDA, 0, 3, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 0, 48000, 2))) -DAI_CONFIG(HDA, 1, 4, iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 1, 48000, 2))) -DAI_CONFIG(HDA, 2, 5, iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 2, 48000, 2))) -DAI_CONFIG(HDA, 3, 6, iDisp4, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 3, 48000, 2))) - -ifdef(`NO_AMP',,` -ifdef(`SMART_AMP',,` -`# SSP' SPK_SSP_INDEX `(ID: 7)' -DAI_CONFIG(SSP, SPK_SSP_INDEX, SPK_BE_ID, SPK_SSP_NAME, -ifelse( - CODEC, `MAX98360A', ` - SSP_CONFIG(I2S, SSP_CLOCK(mclk, SSP_MCLK, codec_mclk_in), - SSP_CLOCK(bclk, 1536000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 16, 3, 3), - SSP_CONFIG_DATA(SSP, SPK_SSP_INDEX, 16)))', - CODEC, `RT1019P', ` - SSP_CONFIG(I2S, SSP_CLOCK(mclk, SSP_MCLK, codec_mclk_in), - SSP_CLOCK(bclk, 1536000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 16, 3, 3), - SSP_CONFIG_DATA(SSP, SPK_SSP_INDEX, 16)))', - CODEC, `RT1015P', ` - SSP_CONFIG(I2S, SSP_CLOCK(mclk, SSP_MCLK, codec_mclk_in), - SSP_CLOCK(bclk, 3072000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 32, 3, 3), - SSP_CONFIG_DATA(SSP, SPK_SSP_INDEX, 32)))', - CODEC, `NAU8318', ` - SSP_CONFIG(I2S, SSP_CLOCK(mclk, SSP_MCLK, codec_mclk_in), - SSP_CLOCK(bclk, 1536000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 16, 3, 3), - SSP_CONFIG_DATA(SSP, SPK_SSP_INDEX, 16)))', -)')') - -DEBUG_END diff --git a/tools/topology/topology1/sof-cavs-nocodec.m4 b/tools/topology/topology1/sof-cavs-nocodec.m4 index d5c3e2ed147f..ba5f741f26e2 100644 --- a/tools/topology/topology1/sof-cavs-nocodec.m4 +++ b/tools/topology/topology1/sof-cavs-nocodec.m4 @@ -101,17 +101,19 @@ dnl time_domain, sched_comp) # Volume switch capture pipeline 2 on PCM 0 using max 2 channels of PIPE_BITS. # Set 1000us deadline on core SSP0_CORE_ID with priority 0 -PIPELINE_PCM_ADD(sof/pipe-volume-switch-capture.m4, +ifdef(`DISABLE_SSP0',, + `PIPELINE_PCM_ADD(sof/pipe-volume-switch-capture.m4, 2, 0, 2, PIPE_BITS, 1000, 0, SSP0_CORE_ID, - 48000, 48000, 48000) + 48000, 48000, 48000)') # Volume switch capture pipeline 4 on PCM 1 using max 2 channels of PIPE_BITS. # Set 1000us deadline on core SSP1_CORE_ID with priority 0 -PIPELINE_PCM_ADD(sof/pipe-volume-switch-capture.m4, +ifdef(`DISABLE_SSP1',, + `PIPELINE_PCM_ADD(sof/pipe-volume-switch-capture.m4, 4, 1, 2, PIPE_BITS, 1000, 0, SSP1_CORE_ID, - 48000, 48000, 48000) + 48000, 48000, 48000)') # Volume switch capture pipeline 6 on PCM 2 using max 2 channels of PIPE_BITS. # Set 1000us deadline with priority 0 on core SSP2_CORE_ID @@ -132,19 +134,21 @@ dnl deadline, priority, core, time_domain) # playback DAI is SSP0 using 2 periods # Buffers use DAI_BITS format, 1000us deadline with priority 0 on core SSP0_CORE_ID # The 'NOT_USED_IGNORED' is due to dependencies and is adjusted later with an explicit dapm line. -DAI_ADD(sof/pipe-mixer-volume-dai-playback.m4, +ifdef(`DISABLE_SSP0',, + `DAI_ADD(sof/pipe-mixer-volume-dai-playback.m4, 1, SSP, SSP0_IDX, NoCodec-0, NOT_USED_IGNORED, 2, DAI_BITS, - 1000, 0, SSP0_CORE_ID, SCHEDULE_TIME_DOMAIN_TIMER, 2, 48000) + 1000, 0, SSP0_CORE_ID, SCHEDULE_TIME_DOMAIN_TIMER, 2, 48000)') # Low Latency playback pipeline 1 on PCM 0 using max 2 channels of PIPE_BITS. # Set 1000us deadline on core SSP0_CORE_ID with priority 0 -PIPELINE_PCM_ADD(sof/pipe-host-volume-playback.m4, +ifdef(`DISABLE_SSP0',, + `PIPELINE_PCM_ADD(sof/pipe-host-volume-playback.m4, 7, 0, 2, PIPE_BITS, 1000, 0, SSP0_CORE_ID, 48000, 48000, 48000, SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) + PIPELINE_PLAYBACK_SCHED_COMP_1)') # Deep buffer playback pipeline 11 on PCM 3 using max 2 channels of PIPE_BITS. # Set 1000us deadline on core SSP0_CORE_ID with priority 0. @@ -158,33 +162,37 @@ PIPELINE_PCM_ADD(sof/pipe-host-volume-playback.m4, # capture DAI is SSP0 using 2 periods # Buffers use DAI_BITS format, 1000us deadline with priority 0 on core SSP0_IDX -DAI_ADD(sof/pipe-dai-capture.m4, +ifdef(`DISABLE_SSP0',, + `DAI_ADD(sof/pipe-dai-capture.m4, 2, SSP, SSP0_IDX, NoCodec-0, PIPELINE_SINK_2, 2, DAI_BITS, - 1000, 0, SSP0_CORE_ID, SCHEDULE_TIME_DOMAIN_TIMER) + 1000, 0, SSP0_CORE_ID, SCHEDULE_TIME_DOMAIN_TIMER)') # playback DAI is SSP1 using 2 periods # Buffers use DAI_BITS format, 1000us deadline with priority 0 on core SSP1_CORE_ID -DAI_ADD(sof/pipe-mixer-volume-dai-playback.m4, +ifdef(`DISABLE_SSP1',, + `DAI_ADD(sof/pipe-mixer-volume-dai-playback.m4, 3, SSP, SSP1_IDX, NoCodec-1, NOT_USED_IGNORED, 2, DAI_BITS, - 1000, 0, SSP1_CORE_ID, SCHEDULE_TIME_DOMAIN_TIMER, 2, 48000) + 1000, 0, SSP1_CORE_ID, SCHEDULE_TIME_DOMAIN_TIMER, 2, 48000)') # Low Latency playback pipeline 8 on PCM 1 using max 2 channels of PIPE_BITS. # Set 1000us deadline on core SSP1_CORE_ID with priority 0 -PIPELINE_PCM_ADD(sof/pipe-host-volume-playback.m4, +ifdef(`DISABLE_SSP1',, + `PIPELINE_PCM_ADD(sof/pipe-host-volume-playback.m4, 8, 1, 2, PIPE_BITS, 1000, 0, SSP1_CORE_ID, 48000, 48000, 48000, SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_3) + PIPELINE_PLAYBACK_SCHED_COMP_3)') # capture DAI is SSP1 using 2 periods # Buffers use DAI_BITS format, 1000us deadline with priority 0 on core SSP1_CORE_ID -DAI_ADD(sof/pipe-dai-capture.m4, +ifdef(`DISABLE_SSP1',, + `DAI_ADD(sof/pipe-dai-capture.m4, 4, SSP, SSP1_IDX, NoCodec-1, PIPELINE_SINK_4, 2, DAI_BITS, - 1000, 0, SSP1_CORE_ID, SCHEDULE_TIME_DOMAIN_TIMER) + 1000, 0, SSP1_CORE_ID, SCHEDULE_TIME_DOMAIN_TIMER)') # playback DAI is SSP2 using 2 periods # Buffers use DAI_BITS format, 1000us deadline with priority 0 on core SSP2_CORE_ID @@ -214,8 +222,8 @@ SectionGraph."mixer-host" { lines [ # connect mixer dai pipelines to PCM pipelines - dapm(PIPELINE_MIXER_1, PIPELINE_SOURCE_7) - dapm(PIPELINE_MIXER_3, PIPELINE_SOURCE_8) + ifdef(`DISABLE_SSP0',,`dapm(PIPELINE_MIXER_1, PIPELINE_SOURCE_7)') + ifdef(`DISABLE_SSP1',, `dapm(PIPELINE_MIXER_3, PIPELINE_SOURCE_8)') dapm(PIPELINE_MIXER_5, PIPELINE_SOURCE_9) ] } diff --git a/tools/topology/topology1/sof-cml-demux-rt5682.m4 b/tools/topology/topology1/sof-cml-demux-rt5682.m4 deleted file mode 100644 index ff131dfb75b5..000000000000 --- a/tools/topology/topology1/sof-cml-demux-rt5682.m4 +++ /dev/null @@ -1,228 +0,0 @@ -# -# Topology for Cometlake with rt5682 codec. -# - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`ssp.m4') -include(`muxdemux.m4') -include(`hda.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include platform specific DSP configuration -include(`platform/intel/'PLATFORM`.m4') - -DEBUG_START - -dnl Configure demux -dnl name, pipeline_id, routing_matrix_rows -dnl Diagonal 1's in routing matrix mean that every input channel is -dnl copied to corresponding output channels in all output streams. -dnl I.e. row index is the input channel, 1 means it is copied to -dnl corresponding output channel (column index), 0 means it is discarded. -dnl There's a separate matrix for all outputs. -define(matrix1, `ROUTE_MATRIX(1, - `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 1 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,1 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,1 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,1 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,1 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,1)')') - -define(matrix2, `ROUTE_MATRIX(5, - `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 1 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,1 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,1 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,1 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,1 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,1)')') - -dnl name, num_streams, route_matrix list -MUXDEMUX_CONFIG(demux_priv_1, 2, LIST_NONEWLINE(`', `matrix1,', `matrix2')) - -# -# Define the pipelines -# -# PCM0 ----> demux ----> SSP(SSP_INDEX) -# PCM0 <---- volume <----- SSP(SSP_INDEX) -# PCM1 ----> volume -----> DMIC01 (dmic0 capture) -# PCM2 ----> volume -----> iDisp1 -# PCM3 ----> volume -----> iDisp2 -# PCM4 ----> volume -----> iDisp3 -# PCM5 <---- demux -# - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp) - -# Demux pipeline 1 on PCM 0 using max 2 channels of s24le. -# Set 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-demux-playback.m4, - 1, 0, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency capture pipeline 2 on PCM 0 using max 2 channels of s24le. -# Set 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, - 2, 0, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Passthrough capture pipeline 3 on PCM 1 using max 4 channels. -# Set 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, - 3, 1, 4, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 4 on PCM 2 using max 2 channels of s32le. -# Set 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 4, 2, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 5 on PCM 3 using max 2 channels of s32le. -# Set 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 7, 3, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 6 on PCM 4 using max 2 channels of s32le. -# Set 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 6, 4, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl deadline, priority, core, time_domain) - -# playback DAI is SSP(SPP_INDEX) using 2 periods -# Buffers use s24le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 1, SSP, SSP_INDEX, SSP_NAME, - PIPELINE_SOURCE_1, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is SSP(SSP_INDEX) using 2 periods -# Buffers use s24le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 2, SSP,SSP_INDEX, SSP_NAME, - PIPELINE_SINK_2, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# Capture pipeline 5 on PCM 5 using max 2 channels of s32le. -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture-sched.m4, - 5, 5, 2, s32le, - 1000, 1, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER) - -# Connect demux to capture -SectionGraph."PIPE_CAP" { - index "0" - - lines [ - # demux to capture - dapm(PIPELINE_SINK_5, PIPELINE_DEMUX_1) - ] -} - -# Connect virtual capture to dai -SectionGraph."PIPE_CAP_VIRT" { - index "5" - - lines [ - # mux to capture - dapm(ECHO REF 5, `SSP'SSP_INDEX`.IN') - ] -} - -# capture DAI is DMIC01 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 3, DMIC, 0, dmic01, - PIPELINE_SINK_3, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp1 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 4, HDA, 0, iDisp1, - PIPELINE_SOURCE_4, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 7, HDA, 1, iDisp2, - PIPELINE_SOURCE_7, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 6, HDA, 2, iDisp3, - PIPELINE_SOURCE_6, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# PCM Low Latency, id 0 -dnl PCM_PLAYBACK_ADD(name, pcm_id, playback) -PCM_DUPLEX_ADD(Port1, 0, PIPELINE_PCM_1, PIPELINE_PCM_2) -PCM_CAPTURE_ADD(DMIC, 1, PIPELINE_PCM_3) -PCM_PLAYBACK_ADD(HDMI1, 2, PIPELINE_PCM_4) -PCM_PLAYBACK_ADD(HDMI2, 3, PIPELINE_PCM_7) -PCM_PLAYBACK_ADD(HDMI3, 4, PIPELINE_PCM_6) -PCM_CAPTURE_ADD(EchoRef, 5, PIPELINE_PCM_5) - -# -# BE configurations - overrides config in ACPI if present -# - -#SSP SSP_INDEX (ID: 0) -DAI_CONFIG(SSP, SSP_INDEX, 0, SSP_NAME, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, SSP_MCLK_RATE, codec_mclk_in), - SSP_CLOCK(bclk, 2400000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 25, 3, 3), - SSP_CONFIG_DATA(SSP, SSP_INDEX, 24))) - -# dmic01 (ID: 1) -DAI_CONFIG(DMIC, 0, 1, dmic01, - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, - DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, - PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) - -# 3 HDMI/DP outputs (ID: 3,4,5) -DAI_CONFIG(HDA, 0, 3, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 0, 48000, 2))) -DAI_CONFIG(HDA, 1, 4, iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 1, 48000, 2))) -DAI_CONFIG(HDA, 2, 5, iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 2, 48000, 2))) - - -DEBUG_END diff --git a/tools/topology/topology1/sof-cml-rt5682-kwd.m4 b/tools/topology/topology1/sof-cml-rt5682-kwd.m4 deleted file mode 100644 index f05ed9913ae4..000000000000 --- a/tools/topology/topology1/sof-cml-rt5682-kwd.m4 +++ /dev/null @@ -1,235 +0,0 @@ -# -# Topology for Cometlake with rt5682 codec and Keyword Detect. -# - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`ssp.m4') -include(`hda.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -include(`abi.h') -# Include Platform specific DSP configuration -include(`platform/intel/'PLATFORM`.m4') - -define(KWD_PIPE_SCH_DEADLINE_US, 5000) - -DEBUG_START - -# if XPROC is not defined, define with default pipe -ifdef(`HSMICPROC', , `define(HSMICPROC, volume)') -ifdef(`HSEARPROC', , `define(HSEARPROC, volume)') -ifdef(`DMICPROC', , `define(DMICPROC, passthrough)') -ifdef(`DMIC16KPROC', , `define(DMIC16KPROC, passthrough)') - -# FIXME: Using DMIC16kHz instead of DMIC16k, otherwise M4 does not return. -define(DMIC_16k_PCM_NAME, DMIC16kHz) - -# -# Define the pipelines -# -# PCM0 <---> volume <----> SSP(SSP_INDEX, BE link 0) -# PCM1 <---- DMICPROC <--- DMIC01 (dmic0 capture, , BE link 1) -# PCM2 ----> volume -----> iDisp1 (HDMI/DP playback, BE link 3) -# PCM3 ----> volume -----> iDisp2 (HDMI/DP playback, BE link 4) -# PCM4 ----> volume -----> iDisp3 (HDMI/DP playback, BE link 5) -# PCM8 <-------(pipe 8) <------------+- KPBM 0 <----- DMIC1 (dmic16k, BE link 2) -# | -# Detector <--- selector (pipe 9) <---+ -# - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp) - -# Low Latency playback pipeline 1 on PCM 0 using max 2 channels of s24le. -# Schedule 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 1, 0, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency capture pipeline 2 on PCM 0 using max 2 channels of s24le. -# Schedule 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, - 2, 0, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# DMICPROC capture pipeline 3 on PCM 1 using max 4 channels. -# Schedule 1000us deadline with priority 0 on core 0 -ifdef(`DMICPROC_FILTER1', `define(PIPELINE_FILTER1, DMICPROC_FILTER1)') -ifdef(`DMICPROC_FILTER2', `define(PIPELINE_FILTER2, DMICPROC_FILTER2)') - -PIPELINE_PCM_ADD(sof/pipe-DMICPROC-capture.m4, - 3, 1, 4, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -undefine(`PIPELINE_FILTER1') -undefine(`PIPELINE_FILTER2') - -# Low Latency playback pipeline 4 on PCM 2 using max 2 channels of s32le. -# Schedule 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 4, 2, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 5 on PCM 3 using max 2 channels of s32le. -# Schedule 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 5, 3, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 6 on PCM 4 using max 2 channels of s32le. -# Schedule 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 6, 4, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl deadline, priority, core, time_domain) - -# playback DAI is SSP(SPP_INDEX) using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 1, SSP, SSP_INDEX, SSP_NAME, - PIPELINE_SOURCE_1, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is SSP(SSP_INDEX) using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 2, SSP,SSP_INDEX, SSP_NAME, - PIPELINE_SINK_2, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is DMIC01 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 3, DMIC, 0, dmic01, - PIPELINE_SINK_3, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp1 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 4, HDA, 0, iDisp1, - PIPELINE_SOURCE_4, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 5, HDA, 1, iDisp2, - PIPELINE_SOURCE_5, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 6, HDA, 2, iDisp3, - PIPELINE_SOURCE_6, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# -# KWD configuration -# - -# Passthrough capture pipeline 7 on PCM 7 using max 2 channels. -# Schedule 20000us deadline with priority 0 on core 0 -PIPELINE_PCM_DAI_ADD(sof/pipe-kfbm-capture.m4, - 8, 8, 2, s24le, - KWD_PIPE_SCH_DEADLINE_US, 0, 0, DMIC, 1, s32le, 3, - 16000, 16000, 16000) - -# capture DAI is DMIC 1 using 3 periods -# Buffers use s32le format, with 320 frame per 20000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 8, DMIC, 1, dmic16k, - PIPELINE_SINK_8, 3, s32le, - KWD_PIPE_SCH_DEADLINE_US, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# PCM Low Latency, id 0 -dnl PCM_PLAYBACK_ADD(name, pcm_id, playback) -PCM_DUPLEX_ADD(Port1, 0, PIPELINE_PCM_1, PIPELINE_PCM_2) -PCM_CAPTURE_ADD(DMIC, 1, PIPELINE_PCM_3) -PCM_PLAYBACK_ADD(HDMI1, 2, PIPELINE_PCM_4) -PCM_PLAYBACK_ADD(HDMI2, 3, PIPELINE_PCM_5) -PCM_PLAYBACK_ADD(HDMI3, 4, PIPELINE_PCM_6) - -# keyword detector pipe -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp, dynamic) -PIPELINE_PCM_ADD(sof/pipe-detect.m4, - 9, 1, 2, s24le, - KWD_PIPE_SCH_DEADLINE_US, 1, 0, - 16000, 16000, 16000, - SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_SCHED_COMP_8) - -# Connect pipelines together -SectionGraph."pipe-sof-cml-keyword-detect" { - index "0" - - lines [ - # keyword detect - dapm(PIPELINE_SINK_9, PIPELINE_SOURCE_8) - dapm(PIPELINE_PCM_8, PIPELINE_DETECT_9) - ] -} - -# -# BE configurations - overrides config in ACPI if present -# - -#SSP SSP_INDEX (ID: 0) -DAI_CONFIG(SSP, SSP_INDEX, 0, SSP_NAME, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, SSP_MCLK_RATE, codec_mclk_in), - SSP_CLOCK(bclk, 2400000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 25, 3, 3), - SSP_CONFIG_DATA(SSP, SSP_INDEX, 24))) - -# dmic01 (ID: 1) -DAI_CONFIG(DMIC, 0, 1, dmic01, - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, - DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, - PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) - -# dmic16k (ID: 2) -DAI_CONFIG(DMIC, 1, 2, dmic16k, - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, - DMIC_WORD_LENGTH(s32le), 400, DMIC, 1, - PDM_CONFIG(DMIC, 1, STEREO_PDM0))) - -# 3 HDMI/DP outputs (ID: 3,4,5) -DAI_CONFIG(HDA, 0, 3, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 0, 48000, 2))) -DAI_CONFIG(HDA, 1, 4, iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 1, 48000, 2))) -DAI_CONFIG(HDA, 2, 5, iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 2, 48000, 2))) - -DEBUG_END diff --git a/tools/topology/topology1/sof-cml-rt5682.m4 b/tools/topology/topology1/sof-cml-rt5682.m4 deleted file mode 100644 index ac928383ea08..000000000000 --- a/tools/topology/topology1/sof-cml-rt5682.m4 +++ /dev/null @@ -1,212 +0,0 @@ -# -# Topology for Cometlake with rt5682 codec. -# - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`ssp.m4') -include(`hda.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include Platform specific DSP configuration -include(`platform/intel/'PLATFORM`.m4') - -DEBUG_START - -# if XPROC is not defined, define with default pipe -ifdef(`HSMICPROC', , `define(HSMICPROC, volume)') -ifdef(`HSEARPROC', , `define(HSEARPROC, volume)') -ifdef(`DMICPROC', , `define(DMICPROC, passthrough)') -ifdef(`DMIC16KPROC', , `define(DMIC16KPROC, passthrough)') - -# -# Define the pipelines -# -`# PCM0 ---> 'HSEARPROC` ----> SSP(SSP_INDEX, BE link 0)' -`# PCM0 <--- 'HSMICPROC` <---- SSP(SSP_INDEX, BE link 0)' -`# PCM1 <--- 'DMICPROC` <----- DMIC01 (dmic0 capture, , BE link 1)' -# PCM2 ----> volume -----> iDisp1 (HDMI/DP playback, BE link 3) -# PCM3 ----> volume -----> iDisp2 (HDMI/DP playback, BE link 4) -# PCM4 ----> volume -----> iDisp3 (HDMI/DP playback, BE link 5) -`# PCM8 <---- 'DMIC16KPROC` <----- DMIC16k (dmic16k, BE link 2)' -# - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp) - -# Low Latency playback pipeline 1 on PCM 0 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-`HSEARPROC'-playback.m4, - 1, 0, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency capture pipeline 2 on PCM 0 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-`HSMICPROC'-capture.m4, - 2, 0, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Passthrough capture pipeline 3 on PCM 1 using max 4 channels. -# 1000us deadline with priority 0 on core 0 -ifdef(`DMICPROC_FILTER1', `define(PIPELINE_FILTER1, DMICPROC_FILTER1)', `undefine(`PIPELINE_FILTER1')') -ifdef(`DMICPROC_FILTER2', `define(PIPELINE_FILTER2, DMICPROC_FILTER2)', `undefine(`PIPELINE_FILTER2')') -define(`PGA_NAME', Dmic0) - -PIPELINE_PCM_ADD(sof/pipe-`DMICPROC'-capture.m4, - 3, 1, 4, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -undefine(`PGA_NAME') -undefine(`PIPELINE_FILTER1') -undefine(`PIPELINE_FILTER2') - -# Low Latency playback pipeline 4 on PCM 2 using max 2 channels of s32le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 4, 2, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 5 on PCM 3 using max 2 channels of s32le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 5, 3, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 6 on PCM 4 using max 2 channels of s32le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 6, 4, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Passthrough capture pipeline 7 on PCM 5 using max 2 channels. -# Schedule 1000us deadline with priority 0 on core 0 -ifdef(`DMIC16KPROC_FILTER1', `define(PIPELINE_FILTER1, DMIC16KPROC_FILTER1)', `undefine(`PIPELINE_FILTER1')') -ifdef(`DMIC16KPROC_FILTER2', `define(PIPELINE_FILTER2, DMIC16KPROC_FILTER2)', `undefine(`PIPELINE_FILTER2')') -define(`PGA_NAME', Dmic1) - -PIPELINE_PCM_ADD(sof/pipe-`DMIC16KPROC'-capture-16khz.m4, - 8, 8, 2, s24le, - 1000, 0, 0, - 16000, 16000, 16000) - -undefine(`PGA_NAME') -undefine(`PIPELINE_FILTER1') -undefine(`PIPELINE_FILTER2') - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl deadline, priority, core, time_domain) - -# playback DAI is SSP(SPP_INDEX) using 2 periods -# Buffers use s24le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 1, SSP, SSP_INDEX, SSP_NAME, - PIPELINE_SOURCE_1, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is SSP(SSP_INDEX) using 2 periods -# Buffers use s24le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 2, SSP,SSP_INDEX, SSP_NAME, - PIPELINE_SINK_2, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is DMIC01 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 3, DMIC, 0, dmic01, - PIPELINE_SINK_3, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp1 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 4, HDA, 0, iDisp1, - PIPELINE_SOURCE_4, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 5, HDA, 1, iDisp2, - PIPELINE_SOURCE_5, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 6, HDA, 2, iDisp3, - PIPELINE_SOURCE_6, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is DMIC16k using 2 periods -# Buffers use s32le format, with 16 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 8, DMIC, 1, dmic16k, - PIPELINE_SINK_8, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - - -# PCM Low Latency, id 0 -dnl PCM_PLAYBACK_ADD(name, pcm_id, playback) -PCM_DUPLEX_ADD(Port1, 0, PIPELINE_PCM_1, PIPELINE_PCM_2) -PCM_CAPTURE_ADD(DMIC, 1, PIPELINE_PCM_3) -PCM_PLAYBACK_ADD(HDMI1, 2, PIPELINE_PCM_4) -PCM_PLAYBACK_ADD(HDMI2, 3, PIPELINE_PCM_5) -PCM_PLAYBACK_ADD(HDMI3, 4, PIPELINE_PCM_6) -PCM_CAPTURE_ADD(DMIC16kHz, 8, PIPELINE_PCM_8) - -# -# BE configurations - overrides config in ACPI if present -# - -#SSP SSP_INDEX (ID: 0) -DAI_CONFIG(SSP, SSP_INDEX, 0, SSP_NAME, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, SSP_MCLK_RATE, codec_mclk_in), - SSP_CLOCK(bclk, 2400000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 25, 3, 3), - SSP_CONFIG_DATA(SSP, SSP_INDEX, 24))) - -# dmic01 (ID: 1) -DAI_CONFIG(DMIC, 0, 1, dmic01, - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, - DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, - PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) - -# dmic16k (ID: 2) -DAI_CONFIG(DMIC, 1, 2, dmic16k, - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, - DMIC_WORD_LENGTH(s32le), 400, DMIC, 1, - PDM_CONFIG(DMIC, 1, STEREO_PDM0))) - -# 3 HDMI/DP outputs (ID: 3,4,5) -DAI_CONFIG(HDA, 0, 3, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 0, 48000, 2))) -DAI_CONFIG(HDA, 1, 4, iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 1, 48000, 2))) -DAI_CONFIG(HDA, 2, 5, iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 2, 48000, 2))) - -DEBUG_END diff --git a/tools/topology/topology1/sof-ehl-rt5660.m4 b/tools/topology/topology1/sof-ehl-rt5660.m4 deleted file mode 100644 index 132740bbb10f..000000000000 --- a/tools/topology/topology1/sof-ehl-rt5660.m4 +++ /dev/null @@ -1,222 +0,0 @@ -# -# Topology for ELKHARTLAKE with rt5660 codec -# - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`ssp.m4') -include(`hda.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include Elkhartlake DSP configuration -include(`platform/intel/ehl.m4') -include(`platform/intel/dmic.m4') - -DEBUG_START - -# -# Define the pipelines -# -# PCM0 <---> volume <----> SSP0 BE dailink 0 -# PCM1 <---- volume <----- DMIC48k (dmic48k, BE dailink 1) - -ifelse(HDMI, `1', -` -# PCM2 ----> volume -----> iDisp1 (HDMI/DP playback, BE link 5) -# PCM3 ----> volume -----> iDisp2 (HDMI/DP playback, BE link 6) -# PCM4 ----> volume -----> iDisp3 (HDMI/DP playback, BE link 7) -# PCM5 ----> volume -----> iDisp3 (HDMI/DP playback, BE link 8) -') - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp) -# time_domain and sched_comp is used for a "branched" pipeline, -# which is not applicable in ehl-rt5660. - -# Low Latency playback pipeline 1 on PCM 0 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 1, 0, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency capture pipeline 2 on PCM 0 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, - 2, 0, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency capture pipeline 3 on PCM 1 using max 4 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, - 3, 1, 4, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Passthrough capture pipeline 4 on PCM 3 using max 2 channels. -# Schedule 16 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, - 4, 3, 2, s16le, - 1000, 0, 0, - 16000, 16000, 16000) - -ifelse(HDMI, `1', -` -# Low Latency playback pipeline 4 on PCM 2 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 5, 2, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 5 on PCM 3 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 6, 3, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 6 on PCM 4 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 7, 4, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 7 on PCM 5 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 8, 5, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) -') - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl period , priority, core, time_domain) - -# playback DAI is SSP0 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 1, SSP, 0, SSP0-Codec, - PIPELINE_SOURCE_1, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is SSP0 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 2, SSP, 0, SSP0-Codec, - PIPELINE_SINK_2, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is DMIC48k using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 3, DMIC, 0, dmic48k, - PIPELINE_SINK_3, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is DMIC16k using 2 periods -# Buffers use s16le format, with 16 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 4, DMIC, 1, dmic16k, - PIPELINE_SINK_4, 2, s16le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) -ifelse(HDMI, `1', -` -# playback DAI is iDisp1 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 5, HDA, 0, iDisp1, - PIPELINE_SOURCE_5, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 6, HDA, 1, iDisp2, - PIPELINE_SOURCE_6, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 7, HDA, 2, iDisp3, - PIPELINE_SOURCE_7, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp4 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 8, HDA, 3, iDisp4, - PIPELINE_SOURCE_8, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) -') - -# PCM Low Latency, id 0 -dnl PCM_PLAYBACK_ADD(name, pcm_id, playback) -PCM_DUPLEX_ADD(Headset, 0, PIPELINE_PCM_1, PIPELINE_PCM_2) -PCM_CAPTURE_ADD(DMIC, 1, PIPELINE_PCM_3) -PCM_CAPTURE_ADD(DMIC16kHz, 2, PIPELINE_PCM_4) - -ifelse(HDMI, `1', -` -PCM_PLAYBACK_ADD(HDMI1, 3, PIPELINE_PCM_5) -PCM_PLAYBACK_ADD(HDMI2, 4, PIPELINE_PCM_6) -PCM_PLAYBACK_ADD(HDMI3, 5, PIPELINE_PCM_7) -PCM_PLAYBACK_ADD(HDMI4, 6, PIPELINE_PCM_8) -') - -# -# BE configurations - overrides config in ACPI if present -# -#SSP 2 (ID: 0) -DAI_CONFIG(SSP, 0, 0, SSP0-Codec, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, 9600000, codec_mclk_in), - SSP_CLOCK(bclk, 2400000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 25, 3, 3), - SSP_CONFIG_DATA(SSP, 0, 24))) - -# dmic48k (ID: 1) -DAI_CONFIG(DMIC, 0, 1, dmic48k, - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, - DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, - PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) - -# dmic16k (ID: 2) -DAI_CONFIG(DMIC, 1, 2, dmic16k, - DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, - DMIC_WORD_LENGTH(s16le), 400, DMIC, 1, - PDM_CONFIG(DMIC, 1, STEREO_PDM0))) - -ifelse(HDMI, `1', -` -# 4 HDMI/DP outputs (ID: 5,6,7,8) -DAI_CONFIG(HDA, 0, 5, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 0, 48000, 2))) -DAI_CONFIG(HDA, 1, 6, iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 1, 48000, 2))) -DAI_CONFIG(HDA, 2, 7, iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 2, 48000, 2))) -DAI_CONFIG(HDA, 3, 8, iDisp4, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 3, 48000, 2))) -') - -DEBUG_END diff --git a/tools/topology/topology1/sof-glk-es8336.m4 b/tools/topology/topology1/sof-glk-es8336.m4 deleted file mode 100644 index 1e63c87d0065..000000000000 --- a/tools/topology/topology1/sof-glk-es8336.m4 +++ /dev/null @@ -1,205 +0,0 @@ -# -# Topology for generic Apollolake UP^2 with es8316 codec. -# - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`ssp.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include DSP configuration -include(`platform/intel/'PLATFORM`.m4') - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`hda.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# define(`SSP_MCLK', ) -define(`SSP_MCLK', 19200000) - -# Define pipeline id for intel-generic-dmic.m4 -# to generate dmic setting - -ifelse(CHANNELS, `0', , -` - -# if XPROC is not defined, define with default pipe -ifdef(`DMICPROC', , `define(DMICPROC, eq-iir-volume)') -ifdef(`DMIC16KPROC', , `define(DMIC16KPROC, eq-iir-volume)') - -define(DMIC_PCM_48k_ID, `1') -define(DMIC_PCM_16k_ID, `2') -define(DMIC_DAI_LINK_48k_ID, `1') -define(DMIC_DAI_LINK_16k_ID, `2') -define(DMIC_PIPELINE_48k_ID, `3') -define(DMIC_PIPELINE_16k_ID, `4') - -include(`platform/intel/intel-generic-dmic.m4') -' -) - -# Add HDMI-SSP Audio Offload pass-through -ifdef(`HDMI_1_SSP_NUM', -` define(`HDMI_SSP_NUM', HDMI_1_SSP_NUM) - define(`HDMI_SSP_PIPELINE_CP_ID', `8') - define(`HDMI_SSP_DAI_LINK_ID', 6) - define(`HDMI_SSP_PCM_ID', `3') dnl use fixed PCM_ID - include(`platform/intel/intel-hdmi-ssp.m4') -' -) - -ifdef(`HDMI_2_SSP_NUM', -` define(`HDMI_SSP_NUM', HDMI_2_SSP_NUM) - define(`HDMI_SSP_PIPELINE_CP_ID', `9') - define(`HDMI_SSP_DAI_LINK_ID', 7) - define(`HDMI_SSP_PCM_ID', `4') dnl use fixed PCM_ID - include(`platform/intel/intel-hdmi-ssp.m4') -' -) - -DEBUG_START -# -# Define the pipelines -# -# PCM0 <----> volume <-----> SSP2 (es8316) -# -ifelse(CHANNELS, `0', -` -# PCM2 <-------------------- DMIC01 (dmic0 capture, BE dailink 2) -# PCM3 <-------------------- DMIC16k (dmic16k, BE dailink 3) -') -# PCM5 ----> volume (pipe 5) -----> iDisp1 (HDMI/DP playback, BE link 5) -# PCM6 ----> Volume (pipe 6) -----> iDisp2 (HDMI/DP playback, BE link 6) -# PCM7 ----> volume (pipe 7) -----> iDisp3 (HDMI/DP playback, BE link 7) -ifdef(`HDMI_1_SSP_NUM', -` -# PCM3 <---- volume <----- HDMI_1_SSP_NUM (lt6911) -' -) -ifdef(`HDMI_2_SSP_NUM', -` -# PCM4 <---- volume <----- HDMI_2_SSP_NUM (lt6911) -' -) - -# Low Latency playback pipeline 1 on PCM 0 using max 2 channels of s32le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 1, 0, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency capture pipeline 2 on PCM 0 using max 2 channels of s32le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-low-latency-capture.m4, - 2, 0, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 5 on PCM 5 using max 2 channels of s32le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 5, 5, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 6 on PCM 6 using max 2 channels of s32le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 6, 6, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 7 on PCM 7 using max 2 channels of s32le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 7, 7, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl deadline, priority, core, time_domain) - -# playback DAI is SSP2 using 2 periods -# Buffers use s24le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 1, SSP, SSP_NUM, `SSP'SSP_NUM`-Codec', - PIPELINE_SOURCE_1, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_DMA) - -# capture DAI is SSP2 using 2 periods -# Buffers use s24le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 2, SSP, SSP_NUM, `SSP'SSP_NUM`-Codec', - PIPELINE_SINK_2, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_DMA) - -# playback DAI is iDisp1 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 5, HDA, 3, iDisp1, - PIPELINE_SOURCE_5, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 6, HDA, 4, iDisp2, - PIPELINE_SOURCE_6, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 7, HDA, 5, iDisp3, - PIPELINE_SOURCE_7, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -PCM_DUPLEX_ADD(ES8336, 0, PIPELINE_PCM_1, PIPELINE_PCM_2) - -PCM_PLAYBACK_ADD(HDMI 1, 5, PIPELINE_PCM_5) -PCM_PLAYBACK_ADD(HDMI 2, 6, PIPELINE_PCM_6) -PCM_PLAYBACK_ADD(HDMI 3, 7, PIPELINE_PCM_7) - -# BE configurations - overrides config in ACPI if present - -DAI_CONFIG(SSP, SSP_NUM, 0, `SSP'SSP_NUM`-Codec', - SSP_CONFIG(I2S, SSP_CLOCK(mclk, SSP_MCLK, codec_mclk_in), - SSP_CLOCK(bclk, 2400000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 25, 3, 3), - SSP_CONFIG_DATA(SSP, SSP_NUM, 24, 0))) - - -# 3 HDMI/DP outputs (ID: 3,4,5) -DAI_CONFIG(HDA, 3, 3, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 3, 48000, 2))) -DAI_CONFIG(HDA, 4, 4, iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 4, 48000, 2))) -DAI_CONFIG(HDA, 5, 5, iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 5, 48000, 2))) - -DEBUG_END - - diff --git a/tools/topology/topology1/sof-hda-generic-idisp.m4 b/tools/topology/topology1/sof-hda-generic-idisp.m4 deleted file mode 100644 index 65cd7f6a3804..000000000000 --- a/tools/topology/topology1/sof-hda-generic-idisp.m4 +++ /dev/null @@ -1,129 +0,0 @@ -# -# Topology for SKL+ HDA Generic machine w/ iDISP codec only -# - -# if XPROC is not defined, define with default pipe -ifdef(`DMICPROC', , `define(DMICPROC, eq-iir-volume)') -ifdef(`DMIC16KPROC', , `define(DMIC16KPROC, eq-iir-volume)') - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`hda.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include bxt DSP configuration -include(`platform/intel/bxt.m4') - -# Define pipeline id for intel-generic-dmic.m4 -# to generate dmic setting - -ifelse(CHANNELS, `0', , -` -define(DMIC_PCM_48k_ID, `6') -define(DMIC_PCM_16k_ID, `7') -define(DMIC_DAI_LINK_48k_ID, `6') -define(DMIC_DAI_LINK_16k_ID, `7') -define(DMIC_PIPELINE_48k_ID, `5') -define(DMIC_PIPELINE_16k_ID, `6') - -include(`platform/intel/intel-generic-dmic.m4') -' -) - -# -# Define the pipelines -# -# PCM1 ----> volume -----> iDisp1 -# PCM2 ----> volume -----> iDisp2 -# PCM3 ----> volume -----> iDisp3 -# - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp) - -# Low Latency playback pipeline 2 on PCM 1 using max 2 channels of s32le. -# Set 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 2, 1, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 3 on PCM 2 using max 2 channels of s32le. -# Set 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 3, 2, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 4 on PCM 3 using max 2 channels of s32le. -# Set 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 4, 3, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl deadline, priority, core) - -# playback DAI is iDisp1 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 2, HDA, 0, iDisp1, - PIPELINE_SOURCE_2, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 3, HDA, 1, iDisp2, - PIPELINE_SOURCE_3, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 4, HDA, 2, iDisp3, - PIPELINE_SOURCE_4, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# PCM Low Latency, id 0 -dnl PCM_PLAYBACK_ADD(name, pcm_id, playback) -PCM_PLAYBACK_ADD(HDMI1, 1, PIPELINE_PCM_2) -PCM_PLAYBACK_ADD(HDMI2, 2, PIPELINE_PCM_3) -PCM_PLAYBACK_ADD(HDMI3, 3, PIPELINE_PCM_4) - -# -# BE configurations - overrides config in ACPI if present -# - -# 3 HDMI/DP outputs (ID: 1,2,3) -DAI_CONFIG(HDA, 0, 1, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 0, 48000, 2))) -DAI_CONFIG(HDA, 1, 2, iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 1, 48000, 2))) -DAI_CONFIG(HDA, 2, 3, iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 2, 48000, 2))) - -VIRTUAL_DAPM_ROUTE_OUT(iDisp1_out, HDA, 0, OUT, 2) -VIRTUAL_DAPM_ROUTE_OUT(iDisp2_out, HDA, 1, OUT, 3) -VIRTUAL_DAPM_ROUTE_OUT(iDisp3_out, HDA, 2, OUT, 4) - -VIRTUAL_WIDGET(iDisp3 Tx, out_drv, 0) -VIRTUAL_WIDGET(iDisp2 Tx, out_drv, 1) -VIRTUAL_WIDGET(iDisp1 Tx, out_drv, 2) diff --git a/tools/topology/topology1/sof-hda-generic.m4 b/tools/topology/topology1/sof-hda-generic.m4 deleted file mode 100644 index b920bf7c411e..000000000000 --- a/tools/topology/topology1/sof-hda-generic.m4 +++ /dev/null @@ -1,222 +0,0 @@ -# Topology for SKL+ HDA Generic machine -# - -# if XPROC is not defined, define with default pipe -ifdef(`DMICPROC', , `define(DMICPROC, eq-iir-volume)') -ifdef(`DMIC16KPROC', , `define(DMIC16KPROC, eq-iir-volume)') -ifdef(`HSPROC', , `define(HSPROC, volume)') -ifdef(`HSSFX', , `define(HSSFX, volume)') - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`hda.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include bxt DSP configuration -include(`platform/intel/bxt.m4') - -# Define pipeline id for intel-generic-dmic.m4 -# to generate dmic setting - -ifelse(CHANNELS, `0', , -` -define(DMIC_PCM_48k_ID, `6') -define(DMIC_PCM_16k_ID, `7') -define(DMIC_DAI_LINK_48k_ID, `6') -define(DMIC_DAI_LINK_16k_ID, `7') -define(DMIC_PIPELINE_48k_ID, `10') -define(DMIC_PIPELINE_16k_ID, `11') - -include(`platform/intel/intel-generic-dmic.m4') -' -) - -# The pipeline naming notation is pipe-mixer-PROCESSING-dai-DIRECTION.m4 -# HSPROC is set by makefile, if not the default above is applied -define(PIPE_HEADSET_PLAYBACK, `sof/pipe-mixer-`HSPROC'-dai-playback.m4') - -# -# Define the pipelines -# -# PCM0P --> volume (pipe 1) --> HDA Analog (HDA Analog playback) -# PCM0C <-- volume, EQ (pipe 2) <-- HDA Analog (HDA Analog capture) -# PCM3 ----> volume (pipe 7) ----> iDisp1 (HDMI/DP playback, BE link 3) -# PCM4 ----> Volume (pipe 8) ----> iDisp2 (HDMI/DP playback, BE link 4) -# PCM5 ----> volume (pipe 9) ----> iDisp3 (HDMI/DP playback, BE link 5) -# - -# If HSPROC_FILTERx is defined set PIPELINE_FILTERx -ifdef(`HSPROC_FILTER1', `define(PIPELINE_FILTER1, HSPROC_FILTER1)', `undefine(`PIPELINE_FILTER1')') -ifdef(`HSPROC_FILTER2', `define(PIPELINE_FILTER2, HSPROC_FILTER2)', `undefine(`PIPELINE_FILTER2')') - -# Low Latency capture pipeline 2 on PCM 0 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-highpass-capture.m4, - 2, 0, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 7 on PCM 3 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 7, 3, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 8 on PCM 4 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 8, 4, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 9 on PCM 5 using max 2 channels of s24le. -# 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 9, 5, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000) - -# -# DAIs configuration -# - -# playback DAI is HDA Analog using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -# The 'NOT_USED_IGNORED' is due to dependencies and is adjusted later with an explicit dapm line. -DAI_ADD(PIPE_HEADSET_PLAYBACK, - 1, HDA, 0, Analog Playback and Capture, - NOT_USED_IGNORED, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER, 2, 48000) - -# If HSSFX_FILTERx is defined set PIPELINE_FILTERx -ifdef(`HSSFX_FILTER1', `define(PIPELINE_FILTER1, HSSFX_FILTER1)', `undefine(`PIPELINE_FILTER1')') -ifdef(`HSSFX_FILTER2', `define(PIPELINE_FILTER2, HSSFX_FILTER2)', `undefine(`PIPELINE_FILTER2')') - -# Low Latency playback pipeline 1 on PCM 30 using max 2 channels of s32le. -# 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-host-HSSFX-playback.m4, - 30, 0, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) - -# Deep buffer playback pipeline 31 on PCM 31 using max 2 channels of s32le -# Set 1000us deadline on core 0 with priority 0. -# TODO: Modify pipeline deadline to account for deep buffering -ifdef(`DEEP_BUFFER', -` -PIPELINE_PCM_ADD(sof/pipe-host-volume-playback.m4, - 31, 31, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) -' -) - -# Undefine PIPELINE_FILTERx to avoid to propagate elsewhere, other endpoints -# with filters blobs will need similar handling as HSPROC_FILTERx. -undefine(`PIPELINE_FILTER1') -undefine(`PIPELINE_FILTER2') - -# capture DAI is HDA Analog using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 2, HDA, 1, Analog Playback and Capture, - PIPELINE_SINK_2, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp1 using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 7, HDA, 4, iDisp1, - PIPELINE_SOURCE_7, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 8, HDA, 5, iDisp2, - PIPELINE_SOURCE_8, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# Dai buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 9, HDA, 6, iDisp3, - PIPELINE_SOURCE_9, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -SectionGraph."mixer-host" { - index "0" - - lines [ - # connect mixer dai pipelines to PCM pipelines - dapm(PIPELINE_MIXER_1, PIPELINE_SOURCE_30) -ifdef(`DEEP_BUFFER', -` - dapm(PIPELINE_MIXER_1, PIPELINE_SOURCE_31) -' -) - ] -} - -PCM_DUPLEX_ADD(HDA Analog, 0, PIPELINE_PCM_30, PIPELINE_PCM_2) -ifdef(`DEEP_BUFFER', -` -PCM_PLAYBACK_ADD(HDA Analog Deep Buffer, 31, PIPELINE_PCM_31) -' -) -PCM_PLAYBACK_ADD(HDMI1, 3, PIPELINE_PCM_7) -PCM_PLAYBACK_ADD(HDMI2, 4, PIPELINE_PCM_8) -PCM_PLAYBACK_ADD(HDMI3, 5, PIPELINE_PCM_9) - -# -# BE configurations - overrides config in ACPI if present -# - -# HDA outputs -DAI_CONFIG(HDA, 0, 4, Analog Playback and Capture, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 0, 48000, 2))) - -# 3 HDMI/DP outputs (ID: 3,4,5) -DAI_CONFIG(HDA, 4, 1, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 4, 48000, 2))) -DAI_CONFIG(HDA, 5, 2, iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 5, 48000, 2))) -DAI_CONFIG(HDA, 6, 3, iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 6, 48000, 2))) - - -VIRTUAL_DAPM_ROUTE_IN(codec0_in, HDA, 1, IN, 1) -VIRTUAL_DAPM_ROUTE_IN(codec1_in, HDA, 3, IN, 2) -VIRTUAL_DAPM_ROUTE_OUT(codec0_out, HDA, 0, OUT, 3) -VIRTUAL_DAPM_ROUTE_OUT(codec1_out, HDA, 2, OUT, 4) - -# codec2 is not supported in dai links but it exists -# in dapm routes, so hack this one to HDA1 -VIRTUAL_DAPM_ROUTE_IN(codec2_in, HDA, 3, IN, 5) -VIRTUAL_DAPM_ROUTE_OUT(codec2_out, HDA, 2, OUT, 6) - -VIRTUAL_DAPM_ROUTE_OUT(iDisp1_out, HDA, 4, OUT, 7) -VIRTUAL_DAPM_ROUTE_OUT(iDisp2_out, HDA, 5, OUT, 8) -VIRTUAL_DAPM_ROUTE_OUT(iDisp3_out, HDA, 6, OUT, 9) - -VIRTUAL_WIDGET(iDisp3 Tx, out_drv, 0) -VIRTUAL_WIDGET(iDisp2 Tx, out_drv, 1) -VIRTUAL_WIDGET(iDisp1 Tx, out_drv, 2) -VIRTUAL_WIDGET(Analog CPU Playback, out_drv, 3) -VIRTUAL_WIDGET(Digital CPU Playback, out_drv, 4) -VIRTUAL_WIDGET(Alt Analog CPU Playback, out_drv, 5) -VIRTUAL_WIDGET(Analog CPU Capture, input, 6) -VIRTUAL_WIDGET(Digital CPU Capture, input, 7) -VIRTUAL_WIDGET(Alt Analog CPU Capture, input, 8) diff --git a/tools/topology/topology1/sof-icl-rt711-rt1308-rt715-hdmi.m4 b/tools/topology/topology1/sof-icl-rt711-rt1308-rt715-hdmi.m4 deleted file mode 100644 index c397d2bc8a93..000000000000 --- a/tools/topology/topology1/sof-icl-rt711-rt1308-rt715-hdmi.m4 +++ /dev/null @@ -1,398 +0,0 @@ -# -# Topology for Icelake with rt711 + rt1308 (x2) + rt715. -# - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`alh.m4') -include(`muxdemux.m4') -include(`hda.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include Platform specific DSP configuration -include(`platform/intel/'PLATFORM`.m4') - -ifdef(`UAJ_LINK',`', -`define(UAJ_LINK, `0')') - -ifdef(`AMP_1_LINK',`', -`define(AMP_1_LINK, `1')') - -ifdef(`AMP_2_LINK',`', -`define(AMP_2_LINK, `2')') - -ifdef(`MIC_LINK',`', -`define(MIC_LINK, `3')') - -# uncomment to remove HDMI support -#define(NOHDMI, `1') - -# UAJ ID: 0, 1 -# AMP ID: 2, 3 (if EXT_AMP_REF defined) -# DMIC ID: 4 -# HDMI ID calculated based on the configuration -define(HDMI_BE_ID_BASE, `0') - -ifdef(`NO_JACK', `', - `undefine(`HDMI_BE_ID_BASE') - define(HDMI_BE_ID_BASE, `2')' -) - -ifdef(`NOAMP', `', - `undefine(`HDMI_BE_ID_BASE') - define(HDMI_BE_ID_BASE, `3')' -) - -ifdef(`EXT_AMP_REF', - `undefine(`HDMI_BE_ID_BASE') - define(HDMI_BE_ID_BASE, `4')', - `' -) - -ifdef(`NO_LOCAL_MIC', `', - `undefine(`HDMI_BE_ID_BASE') - define(HDMI_BE_ID_BASE, `5')' -) - -DEBUG_START - -dnl Configure demux -dnl name, pipeline_id, routing_matrix_rows -dnl Diagonal 1's in routing matrix mean that every input channel is -dnl copied to corresponding output channels in all output streams. -dnl I.e. row index is the input channel, 1 means it is copied to -dnl corresponding output channel (column index), 0 means it is discarded. -dnl There's a separate matrix for all outputs. -ifdef(`NOAMP', `', -` -ifdef(`MONO', `', -` -define(matrix1, `ROUTE_MATRIX(3, - `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 1 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,1 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,1 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,1 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,1 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,1)')') - -define(matrix2, `ROUTE_MATRIX(4, - `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 1 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,1 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,1 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,1 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,1 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,1)')') - -dnl name, num_streams, route_matrix list -MUXDEMUX_CONFIG(demux_priv_3, 2, LIST_NONEWLINE(`', `matrix1,', `matrix2')) -') -') - -# -# Define the pipelines -# -ifdef(`NOJACK', `', -` -# PCM0 ---> volume ----> mixer --->ALH 2 BE UAJ_LINK -# PCM31 ---> volume ------^ -# PCM1 <--- volume <---- ALH 3 BE UAJ_LINK -') -ifdef(`NOAMP', `', -` -# PCM2 ---> volume ----> ALH 2 BE AMP_1_LINK -ifdef(`MONO', `', -`# PCM40 ---> volume ----> ALH 2 BE AMP_2_LINK') -') -ifdef(`NO_LOCAL_MIC', `', -`# PCM4 <--- volume <---- ALH 2 BE MIC_LINK') - -ifdef(`NOHDMI', `', -` -# PCM5 ---> volume ----> iDisp1 -# PCM6 ---> volume ----> iDisp2 -# PCM7 ---> volume ----> iDisp3 -') - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp) - -ifdef(`NOJACK', `', -` -# Low Latency capture pipeline 2 on PCM 1 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-switch-capture.m4, - 2, 1, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) -') - -ifdef(`NOAMP', `', -` -ifdef(`MONO', -` -# Low Latency playback pipeline 3 on PCM 2 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 3, 2, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) -', -` -# Low Latency playback pipeline 3 on PCM 2 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-demux-playback.m4, - 3, 2, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 4 on PCM 40 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-dai-endpoint.m4, - 4, 40, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) -') -') - -ifdef(`NO_LOCAL_MIC', `', -` -# Low Latency capture pipeline 5 on PCM 4 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-highpass-switch-capture.m4, - 5, 4, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) -') - -# Low Latency playback pipeline 6 on PCM 5 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 6, 5, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 7 on PCM 6 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 7, 6, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 8 on PCM 7 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 8, 7, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl deadline, priority, core, time_domain) - -ifdef(`NOJACK', `', -` -# playback DAI is ALH(UAJ_LINK PIN2) using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -# The NOT_USED_IGNORED is due to dependencies and is adjusted later with an explicit dapm line. - -DAI_ADD(sof/pipe-mixer-volume-dai-playback.m4, - 1, ALH, eval(UAJ_LINK * 256 + 2), `SDW'eval(UAJ_LINK)`-Playback', - NOT_USE_IGNORED, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER, 2, 48000) - -# capture DAI is ALH(UAJ_LINK PIN3) using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 2, ALH, eval(UAJ_LINK * 256 + 3), `SDW'eval(UAJ_LINK)`-Capture', - PIPELINE_SINK_2, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# Low Latency playback pipeline 30 on PCM 0 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-host-volume-playback.m4, - 30, 0, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) - -# Deep buffer playback pipeline 31 on PCM 31 using max 2 channels of s32le -# Set 1000us deadline on core 0 with priority 0. -# TODO: Modify pipeline deadline to account for deep buffering -ifdef(`HEADSET_DEEP_BUFFER', -` -PIPELINE_PCM_ADD(sof/pipe-host-volume-playback.m4, - 31, 31, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) -' -) - -SectionGraph."mixer-host" { - index "0" - - lines [ - # connect mixer dai pipelines to PCM pipelines - dapm(PIPELINE_MIXER_1, PIPELINE_SOURCE_30) -ifdef(`HEADSET_DEEP_BUFFER', -` - dapm(PIPELINE_MIXER_1, PIPELINE_SOURCE_31) -' -) - ] -} - -' -) - -ifdef(`NOAMP', `', -` -# playback DAI is ALH(AMP_1_LINK PIN2/AMP_2_LINK PIN2) using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 3, ALH, eval(AMP_1_LINK * 256 + 2), `SDW'eval(AMP_1_LINK)`-Playback', - PIPELINE_SOURCE_3, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -ifdef(`MONO', `', -`DAI_ADD_SCHED(sof/pipe-dai-sched-playback.m4, - 4, ALH, eval(AMP_2_LINK * 256 + 2), `SDW'eval(AMP_1_LINK)`-Playback', - PIPELINE_SOURCE_4, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_3) - -# Connect demux to 2nd pipeline -SectionGraph."PIPE_DEMUX" { - index "4" - - lines [ - # mux to 2nd pipeline - dapm(PIPELINE_SOURCE_4, PIPELINE_DEMUX_3) - ] -} -') -') - -ifdef(`NO_LOCAL_MIC', `', -` -# capture DAI is ALH(MIC_LINK PIN2) using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 5, ALH, eval(MIC_LINK * 256 + 2), `SDW'eval(MIC_LINK)`-Capture', - PIPELINE_SINK_5, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) -') - -ifdef(`NOHDMI', `', -` -# playback DAI is iDisp1 using 2 periods -# # Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 6, HDA, 0, iDisp1, - PIPELINE_SOURCE_6, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# # Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 7, HDA, 1, iDisp2, - PIPELINE_SOURCE_7, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# # Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 8, HDA, 2, iDisp3, - PIPELINE_SOURCE_8, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) -') - -# PCM Low Latency, id 0 -dnl PCM_PLAYBACK_ADD(name, pcm_id, playback) - -ifdef(`NOJACK', `', -` -PCM_PLAYBACK_ADD(Jack Out, 0, PIPELINE_PCM_30) -ifdef(`HEADSET_DEEP_BUFFER', -` -PCM_PLAYBACK_ADD(Jack Out DeepBuffer, 31, PIPELINE_PCM_31) -' -) -PCM_CAPTURE_ADD(Jack In, 1, PIPELINE_PCM_2) -') -ifdef(`NOAMP', `', -` -PCM_PLAYBACK_ADD(Speaker, 2, PIPELINE_PCM_3) -') -ifdef(`NO_LOCAL_MIC', `', `PCM_CAPTURE_ADD(Microphone, 4, PIPELINE_PCM_5)') - -ifdef(`NOHDMI', `', -` -PCM_PLAYBACK_ADD(HDMI 1, 5, PIPELINE_PCM_6) -PCM_PLAYBACK_ADD(HDMI 2, 6, PIPELINE_PCM_7) -PCM_PLAYBACK_ADD(HDMI 3, 7, PIPELINE_PCM_8) -') - -# -# BE configurations - overrides config in ACPI if present -# - -ifdef(`NOJACK', `', -` -#ALH dai index = ((link_id << 8) | PDI id) -#ALH UAJ_LINK Pin2 (ID: 0) -DAI_CONFIG(ALH, eval(UAJ_LINK * 256 + 2), 0, `SDW'eval(UAJ_LINK)`-Playback', - ALH_CONFIG(ALH_CONFIG_DATA(ALH, eval(UAJ_LINK * 256 + 2), 48000, 2))) - -#ALH UAJ_LINK Pin3 (ID: 1) -DAI_CONFIG(ALH, eval(UAJ_LINK * 256 + 3), 1, `SDW'eval(UAJ_LINK)`-Capture', - ALH_CONFIG(ALH_CONFIG_DATA(ALH, eval(UAJ_LINK * 256 + 3), 48000, 2))) -') - -ifdef(`NOAMP', `', -` -#ALH AMP_1_LINK Pin2 (ID: 2) -DAI_CONFIG(ALH, eval(AMP_1_LINK * 256 + 2), 2, `SDW'eval(AMP_1_LINK)`-Playback', - ALH_CONFIG(ALH_CONFIG_DATA(ALH, eval(AMP_1_LINK * 256 + 2), 48000, 2))) -') - -ifdef(`NO_LOCAL_MIC', `', -` -#ALH MIC_LINK Pin2 (ID: 4) -DAI_CONFIG(ALH, eval(MIC_LINK * 256 + 2), 4, `SDW'eval(MIC_LINK)`-Capture', - ALH_CONFIG(ALH_CONFIG_DATA(ALH, eval(MIC_LINK * 256 + 2), 48000, 2))) -') - -ifdef(`NOHDMI', `', -` -# 3 HDMI/DP outputs (ID: from HDMI_BE_ID_BASE) -DAI_CONFIG(HDA, 0, HDMI_BE_ID_BASE, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 0, 48000, 2))) -DAI_CONFIG(HDA, 1, eval(HDMI_BE_ID_BASE + 1), iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 1, 48000, 2))) -DAI_CONFIG(HDA, 2, eval(HDMI_BE_ID_BASE + 2), iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 2, 48000, 2))) -') - -DEBUG_END diff --git a/tools/topology/topology1/sof-imx8mp-micfil.m4 b/tools/topology/topology1/sof-imx8mp-micfil.m4 new file mode 100644 index 000000000000..f8bf88bb5335 --- /dev/null +++ b/tools/topology/topology1/sof-imx8mp-micfil.m4 @@ -0,0 +1,35 @@ +# +# Topology for i.MX8M with MICFIL found on IMX-AUD-HAT +# + +# Include topology builder +include(`utils.m4') +include(`dai.m4') +include(`pipeline.m4') +include(`micfil.m4') +# Include TLV library +include(`common/tlv.m4') + +# Include Token library +include(`sof/tokens.m4') + +#Include DSP configuration +include(`platform/imx/imx8.m4') + +#DMIC +# Capture pipeline 3 on PCM 1 using max 4 channels of s32le. +PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, + 1, 0, 4, s32le, + 2000, 0, 0, + 48000, 48000, 48000) + +DAI_ADD(sof/pipe-dai-capture.m4, 1, MICFIL, 2, micfil-dmic-hifi, +PIPELINE_SINK_1, 2, s32le, 2000, 0, 0, SCHEDULE_TIME_DOMAIN_DMA) + +dnl DAI_CONFIG(type, dai_index, link_id, name, acpdmic_config) +DAI_CONFIG(MICFIL, 0, 0, micfil-dmic-hifi, + MICFIL_CONFIG(MICFIL_CONFIG_DATA(MICFIL, 0, 48000, 4))) + +# PCM id 1 +PCM_CAPTURE_ADD(MICFIL, 0, PIPELINE_PCM_1) +#/**********************************************************************************/ diff --git a/tools/topology/topology1/sof-smart-amplifier-nocodec.m4 b/tools/topology/topology1/sof-smart-amplifier-nocodec.m4 deleted file mode 100644 index 5b5facd6c7c4..000000000000 --- a/tools/topology/topology1/sof-smart-amplifier-nocodec.m4 +++ /dev/null @@ -1,56 +0,0 @@ -# -# Topology for Tigerlake smart amplifier nocodec mode verification -# - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`ssp.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include platform specific DSP configuration -include(`platform/intel/tgl.m4') - -DEBUG_START - -# -# Define the pipelines -# -# PCM0 ----> smart_amp ----> SSP(SSP_INDEX) -# ^ -# | -# | -# PCM0 <---- demux <----- SSP(SSP_INDEX) -# - -# Smart amplifier related -# SSP related -#define smart amplifier SSP index -define(`SMART_SSP_INDEX', 0) -#define SSP BE dai_link name -define(`SMART_SSP_NAME', `NoCodec-0') -#define BE dai_link ID -define(`SMART_BE_ID', 0) -#define SSP QUIRK -define(`SMART_SSP_QUIRK', `SSP_QUIRK_LBM') - -# Playback related -define(`SMART_PB_PPL_ID', 1) -define(`SMART_PB_CH_NUM', 2) -define(`SMART_TX_CHANNELS', 4) -define(`SMART_RX_CHANNELS', 8) -define(`SMART_FB_CHANNELS', 8) -# Ref capture related -define(`SMART_REF_PPL_ID', 2) -define(`SMART_REF_CH_NUM', 4) -# PCM related -define(`SMART_PCM_ID', 0) -define(`SMART_PCM_NAME', `smart373-spk') - -# Include Smart Amplifier support -include(`sof-smart-amplifier.m4') - -DEBUG_END diff --git a/tools/topology/topology1/sof-tgl-max98357a-rt5682.m4 b/tools/topology/topology1/sof-tgl-max98357a-rt5682.m4 deleted file mode 100644 index 04bfc96471ff..000000000000 --- a/tools/topology/topology1/sof-tgl-max98357a-rt5682.m4 +++ /dev/null @@ -1,531 +0,0 @@ -# -# Topology for Tigerlake with CODEC amp + rt5682 codec + DMIC + 4 HDMI -# - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`ssp.m4') -include(`muxdemux.m4') -include(`hda.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include Tigerlake DSP configuration -include(`platform/intel/'PLATFORM`.m4') -include(`platform/intel/dmic.m4') - -# Include machine driver definitions -include(`platform/intel/intel-boards.m4') - -DEBUG_START - -# -# Check option conflicts -# -ifdef(`2CH_2WAY', `ifdef(`4CH_PASSTHROUGH', `fatal_error(note: 2CH_2WAY and 4CH_PASSTHROUGH are mutually exclusive)')') - -# -# Set headphone type, default is RT5682 -# -ifdef(`USE_DA7219',`define(HEADPHONE, `DA7219')',` - ifdef(`USE_RT5650',`define(HEADPHONE, `RT5650')',`define(HEADPHONE, `RT5682')')') - -# -# Set the MCLK rate for headphone and amplifier SSP ports -# -ifelse( - HEADPHONE, `DA7219', ` - define(MCLK_RATE, `24576000')', - HEADPHONE, `RT5650', ` - define(MCLK_RATE, `24576000') - define(CODEC, `RT5650')', - HEADPHONE, `RT5682', ` - define(MCLK_RATE, `19200000')', - `fatal_error(note: unknown HEADPHONE type)') - -# -# Define the demux configure -# -dnl Configure demux -dnl name, pipeline_id, routing_matrix_rows -dnl Diagonal 1's in routing matrix mean that every input channel is -dnl copied to corresponding output channels in all output streams. -dnl I.e. row index is the input channel, 1 means it is copied to -dnl corresponding output channel (column index), 0 means it is discarded. -dnl There's a separate matrix for all outputs. -define(matrix1, `ROUTE_MATRIX(1, - `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 1 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,1 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,1 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,1 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,1 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,1)')') - -define(matrix2, `ROUTE_MATRIX(9, - `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 1 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,1 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,1 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,1 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,1 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,1)')') - -define(matrix3, `ROUTE_MATRIX(1, - `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,0)')') - -define(matrix4, `ROUTE_MATRIX(10, - `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 1 ,0 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,1 ,0 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,1 ,0 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,1 ,0 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,1 ,0)', - `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,1)')') - -dnl name, num_streams, route_matrix list -ifdef(`NO_AMP',`',` -ifdef(`GOOGLE_RTC_AUDIO_PROCESSING', - `ifdef(`2CH_2WAY', - `MUXDEMUX_CONFIG(demux_priv_1, 2, LIST_NONEWLINE(`', `matrix3,', `matrix4'))', - `MUXDEMUX_CONFIG(demux_priv_1, 3, LIST_NONEWLINE(`', `matrix1,', `matrix2,', `matrix4'))')', - `ifdef(`2CH_2WAY', - `MUXDEMUX_CONFIG(demux_priv_1, 1, LIST_NONEWLINE(`', `matrix3'))', - `MUXDEMUX_CONFIG(demux_priv_1, 2, LIST_NONEWLINE(`', `matrix1,', `matrix2'))')' -)') - -# -# Define the pipelines -# -ifdef(`2CH_2WAY',` -ifdef(`WAVES',` -# PCM0 --> waves --> demux(2to4-ch) --> eq_iir --> SSP$AMP_SSP (Speaker - CODEC)',` -# PCM0 --> demux(2to4-ch) --> eq_iir --> SSP$AMP_SSP (Speaker - CODEC)')',` -ifdef(`WAVES',` -# PCM0 --> waves --> volume --> demux --> SSP$AMP_SSP (Speaker - CODEC) -# | -# PCM6 <--------------------------+',` -# PCM0 --> volume --> demux --> SSP$AMP_SSP (Speaker - CODEC) -# | -# PCM6 <----------------+')') -# PCM1 <---> volume <----> SSP0 (Headset - ALC5682) -# PCM99 <---- volume <----- DMIC01 (dmic0 capture) -# PCM2 ----> volume -----> iDisp1 -# PCM3 ----> volume -----> iDisp2 -# PCM4 ----> volume -----> iDisp3 -# PCM5 ----> volume -----> iDisp4 -# PCM99 <---- volume <---- DMIC01 (dmic 48k capture) -# PCM100 <---- kpb <---- DMIC16K (dmic 16k capture) - -ifdef(`SPK_MIC_PERIOD_US',`', `define(`SPK_MIC_PERIOD_US', 1000)') - -ifdef(`NO_AMP',`',` -# Define pipeline id for sof-tgl-CODEC-rt5682.m4 -ifdef(`AMP_SSP',`',`fatal_error(note: Define AMP_SSP for speaker amp SSP Index)') -# Speaker related -# SSP related -# define speaker SSP index -define(`SPK_SSP_INDEX', AMP_SSP) -# define SSP BE dai_link name -define(`SPK_SSP_NAME', concat(concat(`SSP', SPK_SSP_INDEX),`-Codec')) -# define BE dai_link ID -define(`SPK_BE_ID', BOARD_SPK_BE_ID) -# Ref capture related -# Ref capture BE dai_name -define(`SPK_REF_DAI_NAME', concat(concat(`SSP', SPK_SSP_INDEX),`.IN'))') - -# to generate dmic setting with kwd when we have dmic -# define channel -ifdef(`CHANNELS', `', `define(`CHANNELS', 4)') -# define kfbm with volume -define(KFBM_TYPE, `vol-kfbm') -# define pcm, pipeline and dai id -define(DMIC_PCM_48k_ID, `99') -define(DMIC_PIPELINE_48k_ID, `10') -define(DMIC_DAI_LINK_48k_ID, BOARD_DMIC_BE_ID_BASE) -define(DMIC_PCM_16k_ID, `100') -define(DMIC_PIPELINE_16k_ID, `11') -define(DMIC_PIPELINE_KWD_ID, `12') -define(DMIC_DAI_LINK_16k_ID, eval(BOARD_DMIC_BE_ID_BASE + 1)) -define(DMIC_PIPELINE_48k_CORE_ID, `1') - -ifdef(`GOOGLE_RTC_AUDIO_PROCESSING', - `ifdef(`RTNR', - `define(`DMICPROC', rtnr-google-rtc-audio-processing)', - `define(`DMICPROC', google-rtc-audio-processing)')' - `define(`DMIC_48k_PERIOD_US', 10000)' - , - `ifdef(`RTNR', - `define(`DMICPROC', rtnr)' -# 5ms period is required for RTNR build 20220728 and later versions - `define(`DMIC_48k_PERIOD_US', 5000)')' -) - -# Run Speakers pipeline on core#1 by default for low power considering -ifdef(`GOOGLE_RTC_AUDIO_PROCESSING', `define(`SPK_PLAYBACK_CORE', DMIC_PIPELINE_48k_CORE_ID)', - `ifdef(`SPK_PLAYBACK_CORE', `', `define(`SPK_PLAYBACK_CORE', `1')')') - -# Google RTC Audio processing processes 10ms at a time. It needs to have time to process it. -ifdef(`GOOGLE_RTC_AUDIO_PROCESSING', `define(`DMIC_48k_PERIOD', 10000)', `') - -# When Google RTC Audio (AEC) is applied, put DMIC pipe task after Speaker in schedule order. -ifdef(`GOOGLE_RTC_AUDIO_PROCESSING', `define(`DMIC_48k_PRIORITY', 1)', `') - -# define pcm, pipeline and dai id -define(KWD_PIPE_SCH_DEADLINE_US, 5000) - -# include the generic dmic with kwd -ifdef(`NOHOTWORD', -` -define(NO16KDMIC) -define(DMIC_48k_CORE_ID, 1) -ifdef(`DMICPROC',`',`define(`DMICPROC', passthrough)') -include(`platform/intel/intel-generic-dmic.m4')', -`include(`platform/intel/intel-generic-dmic-kwd.m4')') - -ifdef(`BT_OFFLOAD', ` -# BT offload support -define(`BT_PIPELINE_PB_ID', `13') -define(`BT_PIPELINE_CP_ID', `14') -define(`BT_DAI_LINK_ID', BOARD_BT_BE_ID) -define(`BT_PCM_ID', `7') -define(`HW_CONFIG_ID', BOARD_BT_BE_ID) -include(`platform/intel/intel-generic-bt.m4')') - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl frames, deadline, priority, core) - -ifdef(`NO_AMP',`',` -`# Low Latency playback pipeline 1 on PCM 0 using max 'ifdef(`4CH_PASSTHROUGH', `4', `2')` channels of s24le.' -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -define(`ENDPOINT_NAME', `Speakers') -PIPELINE_PCM_ADD( - ifdef(`2CH_2WAY', - ifdef(`WAVES', sof/pipe-waves-demux-eq-iir-playback.m4, - sof/pipe-demux-eq-iir-playback.m4), - ifdef(`WAVES', sof/pipe-waves-codec-demux-playback.m4, - ifdef(`DRC_EQ', sof/pipe-drc-eq-volume-demux-playback.m4, - sof/pipe-volume-demux-playback.m4))), - 1, 0, ifdef(`4CH_PASSTHROUGH', `4', `2'), s32le, - SPK_MIC_PERIOD_US, 0, SPK_PLAYBACK_CORE, - 48000, 48000, 48000) -undefine(`ENDPOINT_NAME')') - -ifdef(`NO_HEADPHONE',`',` -# define Waves integration on Headphones = WAVES && !WAVES_SPK_ONLY -ifdef(`WAVES', `ifdef(`WAVES_SPK_ONLY', `', `define(`WAVES_HEADPHONE')')', `') - -# Low Latency playback pipeline 2 on PCM 1 using max 2 channels of s24le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -define(`ENDPOINT_NAME', `Headphones') -PIPELINE_PCM_ADD( - ifdef(`WAVES_HEADPHONE', sof/pipe-waves-codec-playback.m4, sof/pipe-volume-playback.m4), - 2, 1, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) -undefine(`ENDPOINT_NAME') - -# Low Latency capture pipeline 3 on PCM 1 using max 2 channels of s24le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, - 3, 1, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000)') - -# Low Latency playback pipeline 2 on PCM 2 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 5, 2, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 3 on PCM 3 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 6, 3, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 4 on PCM 4 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 7, 4, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 5 on PCM 5 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 8, 5, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl frames, deadline, priority, core) - -ifdef(`NO_AMP',`',` -# playback DAI is SSP1 using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 1, SSP, SPK_SSP_INDEX, SPK_SSP_NAME, - PIPELINE_SOURCE_1, 2, FMT, - SPK_MIC_PERIOD_US, 0, SPK_PLAYBACK_CORE, SCHEDULE_TIME_DOMAIN_TIMER) - -ifelse(CODEC, `MAX98390', ` -# Low Latency capture pipeline 9 on PCM 6 using max 4 channels of s32le. -# Schedule 48 frames per 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, - 9, 6, 4, s32le, - SPK_MIC_PERIOD_US, 0, SPK_PLAYBACK_CORE, - 48000, 48000, 48000) - -# capture DAI is SSP1 using 2 periods -# Buffers use FMT format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 9, SSP, SPK_SSP_INDEX, SPK_SSP_NAME, - PIPELINE_SINK_9, 2, FMT, - SPK_MIC_PERIOD_US, 0, SPK_PLAYBACK_CORE, SCHEDULE_TIME_DOMAIN_TIMER) -', CODEC, `CS35L41', ` -# Low Latency capture pipeline 9 on PCM 6 using max 4 channels of s32le. -# Schedule 48 frames per 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, - 9, 6, 4, s32le, - SPK_MIC_PERIOD_US, 0, SPK_PLAYBACK_CORE, - 48000, 48000, 48000) - -# capture DAI is SSP1 using 2 periods -# Buffers use FMT format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 9, SSP, SPK_SSP_INDEX, SPK_SSP_NAME, - PIPELINE_SINK_9, 2, FMT, - SPK_MIC_PERIOD_US, 0, SPK_PLAYBACK_CORE, SCHEDULE_TIME_DOMAIN_TIMER)', -` -ifdef(`2CH_2WAY',`# No echo reference for 2-way speakers', -` -# The echo refenrence pipeline has no connections in it, -# it is used for the capture DAI widget to dock. -DAI_ADD(sof/pipe-echo-ref-dai-capture.m4, - 29, SSP, SPK_SSP_INDEX, SPK_SSP_NAME, - PIPELINE_SINK_29, 3, FMT, - SPK_MIC_PERIOD_US, 0, SPK_PLAYBACK_CORE, SCHEDULE_TIME_DOMAIN_TIMER) - -`# Capture pipeline 9 from demux on PCM 6 using max 'ifdef(`4CH_PASSTHROUGH', `4', `2')` channels of s32le.' -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture-sched.m4, - 9, 6, ifdef(`4CH_PASSTHROUGH', `4', `2'), s32le, - SPK_MIC_PERIOD_US, 1, SPK_PLAYBACK_CORE, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) - -# Connect demux to capture -SectionGraph."PIPE_CAP" { - index "0" - - lines [ - # mux to capture - dapm(PIPELINE_SINK_9, PIPELINE_DEMUX_1) - ] -} - -# Connect virtual capture to dai -SectionGraph."PIPE_CAP_VIRT" { - index "9" - - lines [ - # mux to capture - dapm(ECHO REF 9, SPK_REF_DAI_NAME) - ] -} -')')') - -dnl if using Google AEC -ifdef(`GOOGLE_RTC_AUDIO_PROCESSING', -`# Connect demux to capture' -`SectionGraph."PIPE_GOOGLE_RTC_AUDIO_PROCESSING_REF_AEC" {' -` index "0"' -` lines [' -` # mux to capture' -` dapm(N_AEC_REF_BUF, PIPELINE_DEMUX_1)' -` ]' -`}' -dnl else -, `') - -ifdef(`NO_HEADPHONE',`',` -# playback DAI is SSP0 using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 2, SSP, 0, SSP0-Codec, - PIPELINE_SOURCE_2, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is SSP0 using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 3, SSP, 0, SSP0-Codec, - PIPELINE_SINK_3, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER)') - -# playback DAI is iDisp1 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 5, HDA, 0, iDisp1, - PIPELINE_SOURCE_5, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 6, HDA, 1, iDisp2, - PIPELINE_SOURCE_6, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 7, HDA, 2, iDisp3, - PIPELINE_SOURCE_7, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp4 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 8, HDA, 3, iDisp4, - PIPELINE_SOURCE_8, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# PCM Low Latency, id 0 -dnl PCM_PLAYBACK_ADD(name, pcm_id, playback) -ifdef(`NO_AMP',`',` -PCM_PLAYBACK_ADD(Speakers, 0, PIPELINE_PCM_1)') -ifdef(`NO_HEADPHONE',`',` -PCM_DUPLEX_ADD(Headset, 1, PIPELINE_PCM_2, PIPELINE_PCM_3)') -PCM_PLAYBACK_ADD(HDMI1, 2, PIPELINE_PCM_5) -PCM_PLAYBACK_ADD(HDMI2, 3, PIPELINE_PCM_6) -PCM_PLAYBACK_ADD(HDMI3, 4, PIPELINE_PCM_7) -PCM_PLAYBACK_ADD(HDMI4, 5, PIPELINE_PCM_8) -ifdef(`NO_AMP',`',` -ifdef(`2CH_2WAY',`# No echo reference for 2-way speakers', -`PCM_CAPTURE_ADD(EchoRef, 6, PIPELINE_PCM_9)')') - -# -# BE conf2igurations - overrides config in ACPI if present -# -dnl DAI_CONFIG(type, dai_index, link_id, name, ssp_config/dmic_config) -dnl SSP_CONFIG(format, mclk, bclk, fsync, tdm, ssp_config_data) -dnl SSP_CLOCK(clock, freq, codec_master, polarity) -dnl SSP_CONFIG_DATA(type, idx, valid bits, mclk_id) -dnl mclk_id is optional -dnl ssp1-maxmspk - -ifdef(`NO_AMP',`',` -# SSP SPK_SSP_INDEX (ID: SPK_BE_ID) -DAI_CONFIG(SSP, SPK_SSP_INDEX, SPK_BE_ID, SPK_SSP_NAME, -ifelse( - CODEC, `MAX98357A', ` - SSP_CONFIG(I2S, SSP_CLOCK(mclk, MCLK_RATE, codec_mclk_in), - SSP_CLOCK(bclk, 1536000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 16, 3, 3), - SSP_CONFIG_DATA(SSP, SPK_SSP_INDEX, 16)))', - CODEC, `MAX98360A', ` - SSP_CONFIG(I2S, SSP_CLOCK(mclk, MCLK_RATE, codec_mclk_in), - SSP_CLOCK(bclk, 3072000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 32, 3, 3), - SSP_CONFIG_DATA(SSP, SPK_SSP_INDEX, 32)))', - CODEC, `MAX98360A_TDM', ` - SSP_CONFIG(DSP_A, SSP_CLOCK(mclk, MCLK_RATE, codec_mclk_in), - SSP_CLOCK(bclk, 12288000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(8, 32, 15, 15), - SSP_CONFIG_DATA(SSP, SPK_SSP_INDEX, 32)))', - CODEC, `RT1011', ` - SSP_CONFIG(DSP_A, SSP_CLOCK(mclk, MCLK_RATE, codec_mclk_in), - SSP_CLOCK(bclk, 4800000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(4, 25, 3, 15), - SSP_CONFIG_DATA(SSP, SPK_SSP_INDEX, 24)))', - CODEC, `MAX98390', ` - SSP_CONFIG(DSP_B, SSP_CLOCK(mclk, MCLK_RATE, codec_mclk_in), - SSP_CLOCK(bclk, 6144000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(4, 32, 3, 15), - SSP_CONFIG_DATA(SSP, SPK_SSP_INDEX, 32)))', - CODEC, `RT1019', ` - SSP_CONFIG(I2S, SSP_CLOCK(mclk, MCLK_RATE, codec_mclk_in), - SSP_CLOCK(bclk, 3072000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 32, 3, 3), - SSP_CONFIG_DATA(SSP, SPK_SSP_INDEX, 24)))', - CODEC, `CS35L41', ` - SSP_CONFIG(DSP_A, SSP_CLOCK(mclk, MCLK_RATE, codec_mclk_in), - SSP_CLOCK(bclk, 6144000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(4, 32, 3, 15), - SSP_CONFIG_DATA(SSP, SPK_SSP_INDEX, 24)))', - CODEC, `RT5650', ` - SSP_CONFIG(I2S, SSP_CLOCK(mclk, MCLK_RATE, codec_mclk_in), - SSP_CLOCK(bclk, 3072000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 32, 3, 3), - SSP_CONFIG_DATA(SSP, SPK_SSP_INDEX, 24, 0, 0, 0, SSP_CC_MCLK_AON)))', - )') - -ifdef(`NO_HEADPHONE',`',` -# SSP 0 (ID: BOARD_HP_BE_ID) -DAI_CONFIG(SSP, 0, BOARD_HP_BE_ID, SSP0-Codec, -ifelse( - HEADPHONE, `DA7219', ` - SSP_CONFIG(I2S, SSP_CLOCK(mclk, MCLK_RATE, codec_mclk_in), - SSP_CLOCK(bclk, 3072000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 32, 3, 3), - SSP_CONFIG_DATA(SSP, 0, 24)))', - HEADPHONE, `RT5682', ` - SSP_CONFIG(I2S, SSP_CLOCK(mclk, MCLK_RATE, codec_mclk_in), - SSP_CLOCK(bclk, 2400000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 25, 3, 3), - SSP_CONFIG_DATA(SSP, 0, 24, 0, 0, 0, SSP_CC_BCLK_ES)))', - HEADPHONE, `RT5650', ` - SSP_CONFIG(I2S, SSP_CLOCK(mclk, MCLK_RATE, codec_mclk_in), - SSP_CLOCK(bclk, 3072000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 32, 3, 3), - SSP_CONFIG_DATA(SSP, 0, 24, 0, 0, 0, SSP_CC_MCLK_AON)))', - )') - -# 4 HDMI/DP outputs (ID: 3,4,5,6) -DAI_CONFIG(HDA, 0, BOARD_HDMI_BE_ID_BASE, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 0, 48000, 2))) -DAI_CONFIG(HDA, 1, eval(BOARD_HDMI_BE_ID_BASE + 1), iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 1, 48000, 2))) -DAI_CONFIG(HDA, 2, eval(BOARD_HDMI_BE_ID_BASE + 2), iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 2, 48000, 2))) -DAI_CONFIG(HDA, 3, eval(BOARD_HDMI_BE_ID_BASE + 3), iDisp4, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 3, 48000, 2))) - -DEBUG_END diff --git a/tools/topology/topology1/sof-tgl-max98373-rt5682.m4 b/tools/topology/topology1/sof-tgl-max98373-rt5682.m4 deleted file mode 100644 index 5d92bb3c7f92..000000000000 --- a/tools/topology/topology1/sof-tgl-max98373-rt5682.m4 +++ /dev/null @@ -1,257 +0,0 @@ -# -# Topology for Tigerlake with Max98373 amp (SSP: $AMP_SSP) + rt5682 codec + DMIC + 4 HDMI -# - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`ssp.m4') -include(`hda.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include Tigerlake DSP configuration -include(`platform/intel/tgl.m4') -include(`platform/intel/dmic.m4') - -DEBUG_START - -# -# Define the pipelines -# -# PCM0 ----> smart_amp ----> SSP$AMP_SSP (Speaker -max98373) -# ^ -# | -# | -# PCM0 <---- demux <----- SSP$AMP_SSP (Speaker -max98373) -# PCM1 <---> volume <----> SSP0 (Headset - ALC5682) -# PCM2 ----> volume -----> iDisp1 -# PCM3 ----> volume -----> iDisp2 -# PCM4 ----> volume -----> iDisp3 -# PCM5 ----> volume -----> iDisp4 -# PCM6 ----> passthrough ----> SSP2 (Bluetooth) -# PCM99 <---- volume <---- DMIC01 (dmic 48k capture) -# PCM100 <---- kpb <---- DMIC16K (dmic 16k capture) - -# Run Speakers pipeline on core#1 by default for low power considering -ifdef(`SPK_PLAYBACK_CORE', `', `define(`SPK_PLAYBACK_CORE', `1')') - -ifdef(`AMP_SSP',`',`fatal_error(note: Define AMP_SSP for speaker amp SSP Index)') -# Smart amplifier related -# SSP related -#define smart amplifier SSP index -define(`SMART_SSP_INDEX', AMP_SSP) -#define SSP BE dai_link name -define(`SMART_SSP_NAME', concat(concat(`SSP', AMP_SSP),`-Codec')) -#define BE dai_link ID -define(`SMART_BE_ID', 7) -#define SSP mclk -define(`SSP_MCLK', 24576000) -# Run Smart Amp pipeline on core#1 by default for low power considering -define(`SMART_AMP_CORE', SPK_PLAYBACK_CORE) -# Playback related -define(`SMART_PB_PPL_ID', 1) -define(`SMART_PB_CH_NUM', 2) -define(`SMART_TX_CHANNELS', 4) -define(`SMART_RX_CHANNELS', 4) -define(`SMART_FB_CHANNELS', 4) -# Ref capture related -define(`SMART_REF_PPL_ID', 11) -define(`SMART_REF_CH_NUM', 2) -# PCM related -define(`SMART_PCM_ID', 0) -define(`SMART_PCM_NAME', `smart373-spk') - -# Include Smart Amplifier support -include(`sof-smart-amplifier.m4') - -# Define pipeline id for intel-generic-dmic-kwd.m4 -# to generate dmic setting with kwd when we have dmic -# define channel -define(CHANNELS, `4') -# define kfbm with volume -define(KFBM_TYPE, `vol-kfbm') -# define pcm, pipeline and dai id -define(DMIC_PCM_48k_ID, `99') -define(DMIC_PIPELINE_48k_ID, `4') -define(DMIC_DAI_LINK_48k_ID, `1') -define(DMIC_PCM_16k_ID, `100') -define(DMIC_PIPELINE_16k_ID, `9') -define(DMIC_PIPELINE_KWD_ID, `10') -define(DMIC_DAI_LINK_16k_ID, `2') -# Offload DMIC_PIPELINE_48K to secondary core of TGL. -define(DMIC_PIPELINE_48k_CORE_ID, 1) -# define pcm, pipeline and dai id -define(KWD_PIPE_SCH_DEADLINE_US, 20000) - -ifdef(`IGO', - `define(`DMICPROC', igonr)' - `define(`DMIC_48k_PERIOD_US', 16000)', - `') - -# include the generic dmic with kwd -include(`platform/intel/intel-generic-dmic-kwd.m4') - -# BT offload support -ifdef(`BT_OFFLOAD', ` -define(`BT_PIPELINE_PB_ID', eval(SMART_REF_PPL_ID + 1)) -define(`BT_PIPELINE_CP_ID', eval(SMART_REF_PPL_ID + 2)) -define(`BT_DAI_LINK_ID', eval(SMART_BE_ID + 1)) -define(`BT_PCM_ID', `6') -define(`HW_CONFIG_ID', `8') -include(`platform/intel/intel-generic-bt.m4')') - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl frames, deadline, priority, core) - -ifdef(`INCLUDE_IIR_EQ', -` -# Low Latency playback pipeline 2 on PCM 1 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-eq-iir-volume-playback.m4, - 2, 1, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) -' -, -` -# Low Latency playback pipeline 2 on PCM 1 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 2, 1, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) -') - - -# Low Latency capture pipeline 3 on PCM 1 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, - 3, 1, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 5 on PCM 2 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 5, 2, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 6 on PCM 3 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 6, 3, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 7 on PCM 4 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 7, 4, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 8 on PCM 5 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 8, 5, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl frames, deadline, priority, core) - -# playback DAI is SSP0 using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 2, SSP, 0, SSP0-Codec, - PIPELINE_SOURCE_2, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is SSP0 using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 3, SSP, 0, SSP0-Codec, - PIPELINE_SINK_3, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp1 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 5, HDA, 0, iDisp1, - PIPELINE_SOURCE_5, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 6, HDA, 1, iDisp2, - PIPELINE_SOURCE_6, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 7, HDA, 2, iDisp3, - PIPELINE_SOURCE_7, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp4 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 8, HDA, 3, iDisp4, - PIPELINE_SOURCE_8, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# -# Bind PCM with the pipeline -# -dnl PCM_PLAYBACK_ADD(name, pcm_id, playback) -PCM_DUPLEX_ADD(Headset, 1, PIPELINE_PCM_2, PIPELINE_PCM_3) -PCM_PLAYBACK_ADD(HDMI1, 2, PIPELINE_PCM_5) -PCM_PLAYBACK_ADD(HDMI2, 3, PIPELINE_PCM_6) -PCM_PLAYBACK_ADD(HDMI3, 4, PIPELINE_PCM_7) -PCM_PLAYBACK_ADD(HDMI4, 5, PIPELINE_PCM_8) - -# -# BE configurations - overrides config in ACPI if present -# -dnl DAI_CONFIG(type, dai_index, link_id, name, ssp_config/dmic_config) -dnl SSP_CONFIG(format, mclk, bclk, fsync, tdm, ssp_config_data) -dnl SSP_CLOCK(clock, freq, codec_master, polarity) -dnl SSP_CONFIG_DATA(type, idx, valid bits, mclk_id) -dnl mclk_id is optional -dnl ssp1-maxmspk, ssp0-RTHeadset - -#SSP 0 (ID: 0) -DAI_CONFIG(SSP, 0, 0, SSP0-Codec, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, SSP_MCLK, codec_mclk_in), - SSP_CLOCK(bclk, 3072000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 32, 3, 3), - SSP_CONFIG_DATA(SSP, 0, 32))) - -# 4 HDMI/DP outputs (ID: 3,4,5,6) -DAI_CONFIG(HDA, 0, 3, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 0, 48000, 2))) -DAI_CONFIG(HDA, 1, 4, iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 1, 48000, 2))) -DAI_CONFIG(HDA, 2, 5, iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 2, 48000, 2))) -DAI_CONFIG(HDA, 3, 6, iDisp4, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 3, 48000, 2))) - -DEBUG_END diff --git a/tools/topology/topology1/sof-tgl-rt1308-hdmi-ssp.m4 b/tools/topology/topology1/sof-tgl-rt1308-hdmi-ssp.m4 deleted file mode 100644 index a10cd51c05f8..000000000000 --- a/tools/topology/topology1/sof-tgl-rt1308-hdmi-ssp.m4 +++ /dev/null @@ -1,219 +0,0 @@ -# -# Topology for Tigerlake with rt1308 codec + DMIC + 3 HDMI out + 2 HDMI-in capture -# - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`ssp.m4') -include(`hda.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include Tigerlake DSP configuration -include(`platform/intel/'PLATFORM`.m4') -include(`platform/intel/dmic.m4') - -define(`HDMI1_SSP_NAME', concat(concat(`SSP', HDMI_1_SSP_NUM),`-HDMI')) -define(`HDMI2_SSP_NAME', concat(concat(`SSP', HDMI_2_SSP_NUM),`-HDMI')) -define(`AMP_SSP_NAME', concat(concat(`SSP', AMP_SSP_NUM),`-Codec')) - -ifdef(`NO_AMP',`',` -ifdef(`AMP_SSP_NUM',`',`fatal_error(note: Define AMP_SSP_NUM for speaker amp SSP)')') - -DEBUG_START -# -# Define the pipelines -# -# PCM0 <---- volume <----- HDMI-1 SSP -# PCM1 <---- volume <----- HDMI-2 SSP -# PCM2 ----> volume -----> Codec SSP -# PCM3 <---- volume <----- DMIC01 (dmic0 capture) -# - -# PCM5 ----> volume (pipe 5) -----> iDisp1 (HDMI/DP playback, BE link 5) -# PCM6 ----> Volume (pipe 6) -----> iDisp2 (HDMI/DP playback, BE link 6) -# PCM7 ----> volume (pipe 7) -----> iDisp3 (HDMI/DP playback, BE link 7) - - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl frames, deadline, priority, core) - -# Low Latency capture pipeline 1 on PCM 0 using max 2 channels of s16le. -# Schedule 48 frames per 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, - 1, 0, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - - -# Low Latency capture pipeline 2 on PCM 1 using max 2 channels of s16le. -# Schedule 48 frames per 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, - 2, 1, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -ifdef(`NO_AMP',`',` -# Low Latency playback pipeline 3 on PCM 2 using max 2 channels of s24le. -# Schedule 48 frames per 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 3, 2, 2, s24le, - 1000, 0, 0, - 48000, 48000, 48000)') - -# Passthrough capture pipeline 4 on PCM 3 using max 4 channels. -# Schedule 48 frames per 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, - 4, 3, 4, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 5 on PCM 5 using max 2 channels of s24le. -# Schedule 48 frames per 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 5, 5, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 6 on PCM 6 using max 2 channels of s24le. -# Schedule 48 frames per 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 6, 6, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 7 on PCM 7 using max 2 channels of s24le. -# Schedule 48 frames per 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 7, 7, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl frames, deadline, priority, core) - -# capture DAI using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 1, SSP, HDMI_1_SSP_NUM, HDMI1_SSP_NAME, - PIPELINE_SINK_1, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI using 2 periods -# Buffers use s16le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 2, SSP, HDMI_2_SSP_NUM, HDMI2_SSP_NAME, - PIPELINE_SINK_2, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -ifdef(`NO_AMP',`',` -# playback DAI using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 3, SSP, AMP_SSP_NUM, AMP_SSP_NAME, - PIPELINE_SOURCE_3, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER)') - -# capture DAI is DMIC01 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 4, DMIC, 0, dmic01, - PIPELINE_SINK_4, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp1 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 5, HDA, 5, iDisp1, - PIPELINE_SOURCE_5, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 6, HDA, 6, iDisp2, - PIPELINE_SOURCE_6, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 7, HDA, 7, iDisp3, - PIPELINE_SOURCE_7, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# PCM Low Latency, id 0 -dnl PCM_CAPTURE_ADD(name, pcm_id, capture) -PCM_CAPTURE_ADD(HDMI-IN-1, 0, PIPELINE_PCM_1) - -dnl PCM_CAPTURE_ADD(name, pcm_id, capture) -PCM_CAPTURE_ADD(HDMI-IN-2, 1, PIPELINE_PCM_2) - -ifdef(`NO_AMP',`',` -dnl PCM_PLAYBACK_ADD(name, pcm_id, playback) -PCM_PLAYBACK_ADD(Speaker, 2, PIPELINE_PCM_3)') -PCM_CAPTURE_ADD(DMIC01, 3, PIPELINE_PCM_4) - -PCM_PLAYBACK_ADD(HDMI 1, 5, PIPELINE_PCM_5) -PCM_PLAYBACK_ADD(HDMI 2, 6, PIPELINE_PCM_6) -PCM_PLAYBACK_ADD(HDMI 3, 7, PIPELINE_PCM_7) - -# -# BE configurations - overrides config in ACPI if present -# - -#HDMI-1 SSP (ID: 0) -#MCLK is not required and won't impact for HDMI-in capture use case. -DAI_CONFIG(SSP, HDMI_1_SSP_NUM, 0, HDMI1_SSP_NAME, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, 38400000, codec_mclk_in), - SSP_CLOCK(bclk, 3072000, codec_master), - SSP_CLOCK(fsync, 48000, codec_master), - SSP_TDM(2, 32, 3, 3), - SSP_CONFIG_DATA(SSP, HDMI_1_SSP_NUM, 32, 0))) - -#HDMI-2 SSP (ID: 1) -#MCLK is not required and won't impact for HDMI-in capture use case. -DAI_CONFIG(SSP, HDMI_2_SSP_NUM, 1, HDMI2_SSP_NAME, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, 38400000, codec_mclk_in), - SSP_CLOCK(bclk, 3072000, codec_master), - SSP_CLOCK(fsync, 48000, codec_master), - SSP_TDM(2, 32, 3, 3), - SSP_CONFIG_DATA(SSP, HDMI_2_SSP_NUM, 32, 0))) - -ifdef(`NO_AMP',`',` -#Amplifier Codec SSP (ID: 2) -DAI_CONFIG(SSP, AMP_SSP_NUM, 2, AMP_SSP_NAME, - SSP_CONFIG(I2S, SSP_CLOCK(mclk, 38400000, codec_mclk_in), - SSP_CLOCK(bclk, 2400000, codec_slave), - SSP_CLOCK(fsync, 48000, codec_slave), - SSP_TDM(2, 25, 3, 3), - SSP_CONFIG_DATA(SSP, AMP_SSP_NUM, 24)))') - -# dmic01 (ID: 3) -DAI_CONFIG(DMIC, 0, 3, dmic01, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, - DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, - PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) - - -# 3 HDMI/DP outputs (ID: 5,6,7) -DAI_CONFIG(HDA, 5, 5, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 5, 48000, 2))) -DAI_CONFIG(HDA, 6, 6, iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 6, 48000, 2))) -DAI_CONFIG(HDA, 7, 7, iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 7, 48000, 2))) -DEBUG_END diff --git a/tools/topology/topology1/sof-tgl-rt711-rt1308.m4 b/tools/topology/topology1/sof-tgl-rt711-rt1308.m4 deleted file mode 100644 index 73f3bc7b67ae..000000000000 --- a/tools/topology/topology1/sof-tgl-rt711-rt1308.m4 +++ /dev/null @@ -1,303 +0,0 @@ -# -# Topology for Tigerlake with rt711 + rt1308 (x2). -# - -# if XPROC is not defined, define with default pipe -ifdef(`DMICPROC', , `define(DMICPROC, eq-iir-volume)') -ifdef(`DMIC16KPROC', , `define(DMIC16KPROC, eq-iir-volume)') - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`alh.m4') -include(`hda.m4') -include(`platform/intel/dmic.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -include(`platform/intel/'PLATFORM`.m4') - -ifdef(`NO_JACK', -` -define(JACK_OFFSET, `0') -', -` -define(JACK_OFFSET, `2') -') - -ifdef(`AMP_1_LINK',`', -`define(AMP_1_LINK, `1')') - -# if there is an external RT1308 amplifier connected over SoundWire, -# enable "EXT_AMP" option in the CMakefile. -ifdef(`EXT_AMP', -` -define(AMP_OFFSET, `1') -', -` -define(AMP_OFFSET, `0') -' -) - -ifdef(`EXT_AMP_REF', -` -define(AMP_REF_OFFSET, `1') -', -` -define(AMP_REF_OFFSET, `0') -' -) - -# Define pipeline id for intel-generic-dmic.m4 -# to generate dmic setting -ifelse(CHANNELS, `0', -` -define(DMIC_OFFSET, `0') -' -, -` -define(DMIC_PCM_48k_ID, `10') -define(DMIC_PCM_16k_ID, `11') -define(DMIC_PIPELINE_48k_ID, `4') -define(DMIC_PIPELINE_16k_ID, `5') - -define(DMIC_DAI_LINK_48k_ID, eval(JACK_OFFSET+AMP_OFFSET+AMP_REF_OFFSET)) -define(DMIC_DAI_LINK_16k_ID, eval(JACK_OFFSET+AMP_OFFSET+AMP_REF_OFFSET+1)) -include(`platform/intel/intel-generic-dmic.m4') - -define(DMIC_OFFSET, `2') -' -) - -define(HDMI_BE_ID_BASE, eval(JACK_OFFSET+AMP_OFFSET+AMP_REF_OFFSET+DMIC_OFFSET)) - -# Add Bluetooth Audio Offload pass-through - -ifdef(`BT_OFFLOAD', -` define(`BT_PIPELINE_PB_ID', `13') - define(`BT_PIPELINE_CP_ID', `14') - define(`BT_DAI_LINK_ID', eval(HDMI_BE_ID_BASE + 4)) - define(`BT_PCM_ID', `14') dnl use fixed PCM_ID - define(HW_CONFIG_ID, eval(6 + DMIC_OFFSET)) - include(`platform/intel/intel-generic-bt.m4') -' -) - -DEBUG_START - -# -# Define the pipelines -# -# PCM0 ---> volume ----> mixer --->ALH 2 BE dailink 0 -# PCM31 ---> volume ------^ -# PCM1 <--- volume <---- ALH 3 BE dailink 1 -ifdef(`EXT_AMP', ` -# PCM2 ---> volume ----> ALH 2 BE dailink AMP_1_LINK -') -# PCM5 ---> volume <---- iDisp1 -# PCM6 ---> volume <---- iDisp2 -# PCM7 ---> volume <---- iDisp3 -# PCM8 ---> volume <---- iDisp4 -# PCM10 <----volume <---- DMIC01 -# PCM11 <----volume <---- DMIC16k -ifdef(`BT_OFFLOAD', -` -# PCM14 <---> passthrough <---> SSP2 BT playback/capture -') - -# Low Latency capture pipeline 2 on PCM 1 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-switch-capture.m4, - 2, 1, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -ifdef(`EXT_AMP', -` -# Low Latency playback pipeline 3 on PCM 2 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 3, 2, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) -') -# Low Latency playback pipeline 6 on PCM 5 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 6, 5, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 7 on PCM 6 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 7, 6, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 8 on PCM 7 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 8, 7, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 9 on PCM 8 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 9, 8, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl deadline, priority, core, time_domain) - -# playback DAI is ALH(SDW0 PIN2) using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-mixer-volume-dai-playback.m4, - 1, ALH, 2, SDW0-Playback, - NOT_USED_IGNORED, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER, 2, 48000) - -# capture DAI is ALH(SDW0 PIN2) using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 2, ALH, 3, SDW0-Capture, - PIPELINE_SINK_2, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# Low Latency playback pipeline 30 on PCM 0 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-host-volume-playback.m4, - 30, 0, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) - -# Deep buffer playback pipeline 31 on PCM 31 using max 2 channels of s32le -# Set 1000us deadline on core 0 with priority 0. -# TODO: Modify pipeline deadline to account for deep buffering -ifdef(`HEADSET_DEEP_BUFFER', -` -PIPELINE_PCM_ADD(sof/pipe-host-volume-playback.m4, - 31, 31, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000, - SCHEDULE_TIME_DOMAIN_TIMER, - PIPELINE_PLAYBACK_SCHED_COMP_1) -' -) - -SectionGraph."mixer-host" { - index "0" - - lines [ - # connect mixer dai pipelines to PCM pipelines - dapm(PIPELINE_MIXER_1, PIPELINE_SOURCE_30) -ifdef(`HEADSET_DEEP_BUFFER', -` - - dapm(PIPELINE_MIXER_1, PIPELINE_SOURCE_31) -' -) - ] -} - -ifdef(`EXT_AMP', -` -# playback DAI is ALH(AMP_1_LINK PIN2) using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 3, ALH, eval(AMP_1_LINK * 256 + 2), `SDW'eval(AMP_1_LINK)`-Playback', - PIPELINE_SOURCE_3, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) -') - -# playback DAI is iDisp1 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 6, HDA, 0, iDisp1, - PIPELINE_SOURCE_6, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 7, HDA, 1, iDisp2, - PIPELINE_SOURCE_7, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# Buffers use s32le format, 1000us deadline with priority 0 on core 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 8, HDA, 2, iDisp3, - PIPELINE_SOURCE_8, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp4 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 9, HDA, 3, iDisp4, - PIPELINE_SOURCE_9, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# PCM Low Latency, id 0 -dnl PCM_PLAYBACK_ADD(name, pcm_id, playback) -PCM_PLAYBACK_ADD(Jack Out, 0, PIPELINE_PCM_30) -ifdef(`HEADSET_DEEP_BUFFER', -` -PCM_PLAYBACK_ADD(Jack Out DeepBuffer, 31, PIPELINE_PCM_31) -' -) -PCM_CAPTURE_ADD(Jack In, 1, PIPELINE_PCM_2) -ifdef(`EXT_AMP', -` -PCM_PLAYBACK_ADD(Speaker, 2, PIPELINE_PCM_3) -') -PCM_PLAYBACK_ADD(HDMI 1, 5, PIPELINE_PCM_6) -PCM_PLAYBACK_ADD(HDMI 2, 6, PIPELINE_PCM_7) -PCM_PLAYBACK_ADD(HDMI 3, 7, PIPELINE_PCM_8) -PCM_PLAYBACK_ADD(HDMI 4, 8, PIPELINE_PCM_9) -# -# BE configurations - overrides config in ACPI if present -# - -#ALH dai index = ((link_id << 8) | PDI id) -#ALH SDW0 Pin2 (ID: 0) -DAI_CONFIG(ALH, 2, 0, SDW0-Playback, - ALH_CONFIG(ALH_CONFIG_DATA(ALH, 2, 48000, 2))) - -#ALH SDW0 Pin3 (ID: 1) -DAI_CONFIG(ALH, 3, 1, SDW0-Capture, - ALH_CONFIG(ALH_CONFIG_DATA(ALH, 3, 48000, 2))) - -ifdef(`EXT_AMP', -` -#ALH SDW AMP_1_LINK Pin2 (ID: 2) -DAI_CONFIG(ALH, eval(AMP_1_LINK * 256 + 2), 2, `SDW'eval(AMP_1_LINK)`-Playback', - ALH_CONFIG(ALH_CONFIG_DATA(ALH, eval(AMP_1_LINK * 256 + 2), 48000, 2))) -') - -# 3 HDMI/DP outputs -DAI_CONFIG(HDA, 0, HDMI_BE_ID_BASE, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 0, 48000, 2))) -DAI_CONFIG(HDA, 1, eval(HDMI_BE_ID_BASE + 1), iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 1, 48000, 2))) -DAI_CONFIG(HDA, 2, eval(HDMI_BE_ID_BASE + 2), iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 2, 48000, 2))) -DAI_CONFIG(HDA, 3, eval(HDMI_BE_ID_BASE + 3), iDisp4, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 3, 48000, 2))) - -DEBUG_END diff --git a/tools/topology/topology1/sof-tgl-sdw-max98373-rt5682.m4 b/tools/topology/topology1/sof-tgl-sdw-max98373-rt5682.m4 deleted file mode 100644 index 0dc461d934c9..000000000000 --- a/tools/topology/topology1/sof-tgl-sdw-max98373-rt5682.m4 +++ /dev/null @@ -1,246 +0,0 @@ -# -# Topology for Tigerlake with sdw rt5682 + Max98373 amp + DMIC + 4 HDMI -# - -# Include topology builder -include(`utils.m4') -include(`dai.m4') -include(`pipeline.m4') -include(`alh.m4') -include(`hda.m4') - -# Include TLV library -include(`common/tlv.m4') - -# Include Token library -include(`sof/tokens.m4') - -# Include Tigerlake DSP configuration -include(`platform/intel/'PLATFORM`.m4') -include(`platform/intel/dmic.m4') - -define(DMIC_PDM_CONFIG, ifelse(CHANNELS, `4', ``FOUR_CH_PDM0_PDM1'', - `ifelse(CHANNELS, `2', ``STEREO_PDM0'', `')')) - -DEBUG_START - -# -# Define the pipelines -# -# PCM0 <---> volume <----> playback (Headset - ALC5682) -# PCM1 <---> volume <----> capture (Headset - ALC5682) -# PCM2 ----> smart_amp ----> ALH0xy02 (Speaker -max98373) -# ^ -# | -# | -# PCM3 <---- demux <----- ALH0xy03 (Speaker -max98373) -# PCM5 ----> volume -----> iDisp1 -# PCM6 ----> volume -----> iDisp2 -# PCM7 ----> volume -----> iDisp3 -# PCM8 ----> volume -----> iDisp4 -# PCM10 <---- volume <---- DMIC01 (dmic 48k capture) -# PCM12 <---- kpb <---- DMIC16k (dmic 16k capture) -# PCM14 <---> passthrough <---> SSP2 (Bluetooth playback/capture) - - -define(`SDW', 1) - -# Smart amplifier related -# ALH related -ifelse(PLATFORM, `tgl', -` #define smart amplifier ALH index - define(`SMART_ALH_INDEX', 0x102) - #define ALH BE dai_link name - define(`SMART_ALH_PLAYBACK_NAME', `SDW1-Playback') - define(`SMART_ALH_CAPTURE_NAME', `SDW1-Capture') -', `') -ifelse(PLATFORM, `adl', -` define(`SMART_ALH_INDEX', 0x202) - define(`SMART_ALH_PLAYBACK_NAME', `SDW2-Playback') - define(`SMART_ALH_CAPTURE_NAME', `SDW2-Capture') - # Add BT audio offload support - define(`BT_PIPELINE_PB_ID', `14') dnl DMIC_PIPELINE_KWD_ID + 1 - define(`BT_PIPELINE_CP_ID', `15') dnl DMIC_PIPELINE_KWD_ID + 2 - define(`BT_DAI_LINK_ID', `10') - define(`BT_PCM_ID', `14') - define(`HW_CONFIG_ID', `10') - include(`platform/intel/intel-generic-bt.m4') -', `') -#define BE dai_link ID -define(`SMART_BE_ID', 2) - -# Playback related -define(`SMART_PB_PPL_ID', 3) -define(`SMART_PB_CH_NUM', 2) -# channel number for playback on sdw link -define(`SMART_TX_CHANNELS', 2) -# channel number for I/V feedback on sdw link -define(`SMART_RX_CHANNELS', 4) -# Smart_amp algorithm specific. channel number -# for feedback provided to smart_amp algorithm -define(`SMART_FB_CHANNELS', 4) -# Ref capture related -define(`SMART_REF_PPL_ID', 4) -define(`SMART_REF_CH_NUM', 2) -# PCM related -define(`SMART_PCM_ID', 2) -define(`SMART_PCM_NAME', `Speaker') - -# Include Smart Amplifier support -include(`sof-smart-amplifier.m4') - -dnl PIPELINE_PCM_ADD(pipeline, -dnl pipe id, pcm, max channels, format, -dnl period, priority, core, -dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp) - -# Low Latency playback pipeline 1 on PCM 0 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 1, 0, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency capture pipeline 2 on PCM 1 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, - 2, 1, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Define pipeline id for intel-generic-dmic-kwd.m4 -# to generate dmic setting with kwd when we have dmic -# define channel -define(CHANNELS, `4') -# define kfbm with volume -define(KFBM_TYPE, `vol-kfbm') -# define pcm, pipeline and dai id -define(DMIC_PCM_48k_ID, `10') -define(DMIC_PIPELINE_48k_ID, `11') -define(DMIC_DAI_LINK_48k_ID, `4') -define(DMIC_PCM_16k_ID, `12') -define(DMIC_PIPELINE_16k_ID, `12') -define(DMIC_PIPELINE_KWD_ID, `13') -define(DMIC_DAI_LINK_16k_ID, `5') -define(DMIC_16k_PCM_NAME, `BufferedMic') -# define pcm, pipeline and dai id -define(KWD_PIPE_SCH_DEADLINE_US, 5000) -# include the generic dmic with kwd -include(`platform/intel/intel-generic-dmic-kwd.m4') - - -# Low Latency playback pipeline 6 on PCM 5 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 6, 5, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 7 on PCM 6 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 7, 6, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 8 on PCM 7 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 8, 7, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# Low Latency playback pipeline 9 on PCM 8 using max 2 channels of s32le. -# Schedule 48 frames per 1000us deadline with priority 0 on core 0 -PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, - 9, 8, 2, s32le, - 1000, 0, 0, - 48000, 48000, 48000) - -# -# DAIs configuration -# - -dnl DAI_ADD(pipeline, -dnl pipe id, dai type, dai_index, dai_be, -dnl buffer, periods, format, -dnl deadline, priority, core, time_domain) - -# playback DAI is ALH(ALH0 PIN2) using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 1, ALH, 2, SDW0-Playback, - PIPELINE_SOURCE_1, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# capture DAI is ALH(ALH0 PIN2) using 2 periods -# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-capture.m4, - 2, ALH, 3, SDW0-Capture, - PIPELINE_SINK_2, 2, s24le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp1 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 6, HDA, 0, iDisp1, - PIPELINE_SOURCE_6, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp2 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 7, HDA, 1, iDisp2, - PIPELINE_SOURCE_7, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp3 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 8, HDA, 2, iDisp3, - PIPELINE_SOURCE_8, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# playback DAI is iDisp4 using 2 periods -# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 -DAI_ADD(sof/pipe-dai-playback.m4, - 9, HDA, 3, iDisp4, - PIPELINE_SOURCE_9, 2, s32le, - 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) - -# -# Bind PCM with the pipeline -# -dnl PCM_PLAYBACK_ADD(name, pcm_id, playback) -PCM_PLAYBACK_ADD(Jack Out, 0, PIPELINE_PCM_1) -PCM_CAPTURE_ADD(Jack In, 1, PIPELINE_PCM_2) -PCM_PLAYBACK_ADD(HDMI 1, 5, PIPELINE_PCM_6) -PCM_PLAYBACK_ADD(HDMI 2, 6, PIPELINE_PCM_7) -PCM_PLAYBACK_ADD(HDMI 3, 7, PIPELINE_PCM_8) -PCM_PLAYBACK_ADD(HDMI 4, 8, PIPELINE_PCM_9) - -# -# BE configurations - overrides config in ACPI if present -# -dnl DAI_CONFIG(type, dai_index, link_id, name, ssp_config/dmic_config) - -#ALH SDW0 Pin2 (ID: 0) -DAI_CONFIG(ALH, 2, 0, SDW0-Playback, - ALH_CONFIG(ALH_CONFIG_DATA(ALH, 2, 48000, 2))) - -#ALH SDW0 Pin3 (ID: 1) -DAI_CONFIG(ALH, 3, 1, SDW0-Capture, - ALH_CONFIG(ALH_CONFIG_DATA(ALH, 3, 48000, 2))) - -# 4 HDMI/DP outputs (ID: 6,7,8,9) -DAI_CONFIG(HDA, 0, 6, iDisp1, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 0, 48000, 2))) -DAI_CONFIG(HDA, 1, 7, iDisp2, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 1, 48000, 2))) -DAI_CONFIG(HDA, 2, 8, iDisp3, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 2, 48000, 2))) -DAI_CONFIG(HDA, 3, 9, iDisp4, - HDA_CONFIG(HDA_CONFIG_DATA(HDA, 3, 48000, 2))) - -DEBUG_END diff --git a/tools/topology/topology1/sof/tokens.m4 b/tools/topology/topology1/sof/tokens.m4 index 728b7478f538..d70ea05cc096 100644 --- a/tools/topology/topology1/sof/tokens.m4 +++ b/tools/topology/topology1/sof/tokens.m4 @@ -148,3 +148,7 @@ SectionVendorTokens."sof_acpdmic_tokens" { SOF_TKN_AMD_ACPDMIC_CH "1801" } +SectionVendorTokens."sof_micfil_tokens" { + SOF_TKN_IMX_MICFIL_RATE "2000" + SOF_TKN_IMX_MICFIL_CH "2001" +} diff --git a/tools/topology/topology2/CMakeLists.txt b/tools/topology/topology2/CMakeLists.txt index 6abb55262170..d3cd9ecca5f9 100644 --- a/tools/topology/topology2/CMakeLists.txt +++ b/tools/topology/topology2/CMakeLists.txt @@ -3,15 +3,14 @@ add_custom_target(topologies2) # Check alsatplg version and build topology2 if alsatplg version is # 1.2.7 or greater, see https://github.com/thesofproject/sof/issues/5323 -execute_process(COMMAND alsatplg --version RESULT_VARIABLE STATUS OUTPUT_VARIABLE ALSA_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) -if(STATUS AND NOT STATUS EQUAL 0) - message(WARNING "alsatplg error: ${STATUS}, topology2 will be skipped") +alsatplg_version(STATUS ALSATPLG_VERSION_NUMBER) + +if(NOT STATUS EQUAL 0) + message(WARNING "alsatplg error: ${STATUS}; topology2 will be skipped") else() - string(REPLACE "\n" ";" ALSA_VERSION_LIST ${ALSA_VERSION}) - list(GET ALSA_VERSION_LIST 0 ALSATPLG_VERSION) - string(REGEX MATCH "[0-9]\.[0-9]\.*[0-9]*" ALSATPLG_VERSION_NUMBER ${ALSATPLG_VERSION}) if(${ALSATPLG_VERSION_NUMBER} VERSION_LESS "1.2.7") - message(WARNING "topology2 will be skipped. Minimum required version for alsatplg: 1.2.7") + message(WARNING "topology2 skipped. Minimum alsatplg version 1.2.7,\ + found ${ALSATPLG_VERSION_NUMBER}.") else() add_dependencies(topologies topologies2) endif() diff --git a/tools/topology/topology2/cavs-benchmark-hda.conf b/tools/topology/topology2/cavs-benchmark-hda.conf index e47866791af5..ee6470447659 100644 --- a/tools/topology/topology2/cavs-benchmark-hda.conf +++ b/tools/topology/topology2/cavs-benchmark-hda.conf @@ -1,12 +1,9 @@ +<include/components/dcblock.conf> + Define { ANALOG_PLAYBACK_PCM 'Analog Playback' ANALOG_CAPTURE_PCM 'Analog Capture' - HDA_ANALOG_DAI_NAME 'Analog' - DEEP_BUFFER_PIPELINE_ID 15 - DEEP_BUFFER_PCM_ID 31 - DEEP_BUFFER_PIPELINE_SRC 'mixin.15.1' - DEEP_BUFFER_PIPELINE_SINK 'mixout.2.1' - DEEP_BUFFER_PCM_NAME 'Deepbuffer HDA Analog' + HDA_ANALOG_DAI_NAME 'Analog' } Object.Dai.HDA [ @@ -22,114 +19,6 @@ Object.Dai.HDA [ } ] -Object.Pipeline { - mixout-dai-copier-playback [ - { - index 3 - - Object.Widget.dai-copier.1 { - node_type $HDA_LINK_OUTPUT_CLASS - stream_name $HDA_ANALOG_DAI_NAME - dai_type "HDA" - copier_type "HDA" - } - } - ] - - mixout-aria-gain-mixin-playback [ - { - index 2 - - Object.Widget.gain.1 { - Object.Control.mixer.1 { - name 'Post Mixer $ANALOG_PLAYBACK_PCM Volume' - } - } - Object.Widget.aria.1 { - num_input_audio_formats 1 - num_output_audio_formats 1 - # 32-bit 48KHz 2ch - Object.Base.input_audio_format [ - { - in_bit_depth 32 - in_valid_bit_depth 32 - } - ] - Object.Base.output_audio_format [ - { - out_bit_depth 32 - out_valid_bit_depth 32 - } - ] - Object.Control.bytes."1" { - name "SSP2 Aria Control" - } - } - } - ] - - host-copier-gain-mixin-playback [ - { - index 1 - - Object.Widget.host-copier.1 { - stream_name $ANALOG_PLAYBACK_PCM - pcm_id 0 - } - - Object.Widget.gain.1 { - Object.Control.mixer.1 { - name 'Pre Mixer $ANALOG_PLAYBACK_PCM Volume' - } - } - } - ] - - host-gateway-capture [ - { - index 3 - Object.Widget.host-copier.1 { - stream_name $ANALOG_CAPTURE_PCM - pcm_id 0 - } - } - ] - - highpass-capture-be [ - { - index 4 - direction capture - - Object.Widget.dai-copier."1" { - dai_type "HDA" - type "dai_out" - copier_type "HDA" - stream_name $HDA_ANALOG_DAI_NAME - node_type $HDA_LINK_INPUT_CLASS - num_output_pins 1 - num_input_audio_formats 1 - num_output_audio_formats 1 - Object.Base.input_audio_format [ - { - in_bit_depth 32 - in_valid_bit_depth 32 - } - ] - Object.Base.output_audio_format [ - { - out_bit_depth 32 - out_valid_bit_depth 32 - } - ] - } - Object.Widget.eqiir.1 { - Object.Control.bytes."1" { - name '$ANALOG_CAPTURE_PCM IIR Eq' - } - } - } - ] -} Object.PCM.pcm [ { id 0 @@ -151,30 +40,207 @@ Object.PCM.pcm [ } ] -# top-level pipeline connections -Object.Base.route [ - { - sink 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.playback' - source 'mixout.3.1' +IncludeByKey.BENCH_CONFIG { + "benchmark" { + Object.Pipeline { + mixout-dai-copier-playback [ + { + index 3 + + Object.Widget.dai-copier.1 { + node_type $HDA_LINK_OUTPUT_CLASS + stream_name $HDA_ANALOG_DAI_NAME + dai_type "HDA" + copier_type "HDA" + } + } + ] + + mixout-aria-gain-mixin-playback [ + { + index 2 + + Object.Widget.gain.1 { + Object.Control.mixer.1 { + name 'Post Mixer $ANALOG_PLAYBACK_PCM Volume' + } + } + Object.Widget.aria.1 { + num_input_audio_formats 1 + num_output_audio_formats 1 + # 32-bit 48KHz 2ch + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + Object.Control.bytes."1" { + name "SSP2 Aria Control" + } + } + } + ] + + host-copier-gain-mixin-playback [ + { + index 1 + + Object.Widget.host-copier.1 { + stream_name $ANALOG_PLAYBACK_PCM + pcm_id 0 + } + + Object.Widget.gain.1 { + Object.Control.mixer.1 { + name 'Pre Mixer $ANALOG_PLAYBACK_PCM Volume' + } + } + } + ] + + host-gateway-capture [ + { + index 3 + Object.Widget.host-copier.1 { + stream_name $ANALOG_CAPTURE_PCM + pcm_id 0 + } + } + ] + + highpass-capture-be [ + { + index 4 + direction capture + + Object.Widget.dai-copier."1" { + dai_type "HDA" + type "dai_out" + copier_type "HDA" + stream_name $HDA_ANALOG_DAI_NAME + node_type $HDA_LINK_INPUT_CLASS + num_output_pins 1 + num_input_audio_formats 1 + num_output_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + } + Object.Widget.eqiir.1 { + Object.Control.bytes."1" { + name '$ANALOG_CAPTURE_PCM IIR Eq' + } + } + } + ] + } + + # top-level pipeline connections + Object.Base.route [ + { + sink 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.playback' + source 'mixout.3.1' + } + { + source 'mixin.2.1' + sink 'mixout.3.1' + } + { + source 'mixin.1.1' + sink 'mixout.2.1' + } + { + source 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.capture' + sink 'eqiir.4.1' + } + { + source 'eqiir.4.1' + sink 'host-copier.0.capture' + } + { + source 'host-copier.0.playback' + sink 'gain.1.1' + } + ] } - { - source 'mixin.2.1' - sink 'mixout.3.1' + + # + # DCblock component + # + + "dcblock16" { + <include/bench/dcblock_s16.conf> } - { - source 'mixin.1.1' - sink 'mixout.2.1' + + "dcblock24" { + <include/bench/dcblock_s24.conf> } - { - source 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.capture' - sink 'eqiir.4.1' + + "dcblock32" { + <include/bench/dcblock_s32.conf> } - { - source 'eqiir.4.1' - sink 'host-copier.0.capture' + + # + # DRC component + # + + "drc16" { + <include/bench/drc_s16.conf> } - { - source 'host-copier.0.playback' - sink 'gain.1.1' + + "drc24" { + <include/bench/drc_s24.conf> } -] + + "drc32" { + <include/bench/drc_s32.conf> + } + + # + # EQFIR component + # + + "eqfir16" { + <include/bench/eqfir_s16.conf> + } + + "eqfir24" { + <include/bench/eqfir_s24.conf> + } + + "eqfir32" { + <include/bench/eqfir_s32.conf> + } + + # + # EQIIR component + # + + "eqiir16" { + <include/bench/eqiir_s16.conf> + } + + "eqiir24" { + <include/bench/eqiir_s24.conf> + } + + "eqiir32" { + <include/bench/eqiir_s32.conf> + } +} diff --git a/tools/topology/topology2/cavs-mixin-mixout-efx-hda.conf b/tools/topology/topology2/cavs-mixin-mixout-efx-hda.conf index 076191afd289..2ce8e2fa2cbd 100644 --- a/tools/topology/topology2/cavs-mixin-mixout-efx-hda.conf +++ b/tools/topology/topology2/cavs-mixin-mixout-efx-hda.conf @@ -28,38 +28,81 @@ Object.Dai.HDA [ ] Object.Pipeline { - mixout-gain-efx-dai-copier-playback [ - { - index 2 + IncludeByKey.EFX_DRC_COMPONENT { + "singleband" { + mixout-gain-efx-dai-copier-playback [ + { + index 2 - Object.Widget.dai-copier.1 { - node_type $HDA_LINK_OUTPUT_CLASS - stream_name $HDA_ANALOG_DAI_NAME - dai_type "HDA" - copier_type "HDA" - } - Object.Widget.gain.1 { - Object.Control.mixer.1 { - name 'Post Mixer $ANALOG_PLAYBACK_PCM Volume' - } - } - Object.Widget.eqiir.1 { - Object.Control.bytes."1" { - name 'Post Mixer $ANALOG_PLAYBACK_PCM IIR Eq' - } - } - Object.Widget.eqfir.1 { - Object.Control.bytes."1" { - name 'Post Mixer $ANALOG_PLAYBACK_PCM FIR Eq' - } - } - Object.Widget.drc.1 { - Object.Control.bytes."1" { - name '2 Main playback DRC' - } - } - } - ] + Object.Widget.dai-copier.1 { + node_type $HDA_LINK_OUTPUT_CLASS + stream_name $HDA_ANALOG_DAI_NAME + dai_type "HDA" + copier_type "HDA" + } + Object.Widget.gain.1 { + Object.Control.mixer.1 { + name 'Post Mixer $ANALOG_PLAYBACK_PCM Volume' + } + } + Object.Widget.eqiir.1 { + Object.Control.bytes."1" { + name 'Post Mixer $ANALOG_PLAYBACK_PCM IIR Eq' + } + } + Object.Widget.eqfir.1 { + Object.Control.bytes."1" { + name 'Post Mixer $ANALOG_PLAYBACK_PCM FIR Eq' + } + } + Object.Widget.drc.1 { + Object.Control.bytes."1" { + name 'Post Mixer $ANALOG_PLAYBACK_PCM DRC' + } + } + } + ] + } + "multiband" { + mixout-gain-efx-mbdrc-dai-copier-playback [ + { + index 2 + + Object.Widget.dai-copier.1 { + node_type $HDA_LINK_OUTPUT_CLASS + stream_name $HDA_ANALOG_DAI_NAME + dai_type "HDA" + copier_type "HDA" + } + Object.Widget.gain.1 { + Object.Control.mixer.1 { + name 'Post Mixer $ANALOG_PLAYBACK_PCM Volume' + } + } + Object.Widget.eqiir.1 { + Object.Control.bytes."1" { + name 'Post Mixer $ANALOG_PLAYBACK_PCM IIR Eq' + } + } + Object.Widget.eqfir.1 { + Object.Control.bytes."1" { + name 'Post Mixer $ANALOG_PLAYBACK_PCM FIR Eq' + } + } + Object.Widget.multiband_drc.1 { + Object.Control { + bytes."1" { + name 'Post Mixer $ANALOG_PLAYBACK_PCM MBDRC bytes' + } + mixer."1" { + name 'Post Mixer $ANALOG_PLAYBACK_PCM MBDRC switch' + } + } + } + } + ] + } + } host-copier-gain-mixin-playback [ { @@ -140,21 +183,45 @@ Object.PCM.pcm [ ] # top-level pipeline connections -Object.Base.route [ - { - sink 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.playback' - source 'drc.2.1' - } - { - source 'mixin.1.1' - sink 'mixout.2.1' - } - { - source 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.capture' - sink 'host-copier.0.capture' - } - { - source 'host-copier.0.playback' - sink 'gain.1.1' - } -] +IncludeByKey.EFX_DRC_COMPONENT { + "singleband" { + Object.Base.route [ + { + sink 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.playback' + source 'drc.2.1' + } + { + source 'mixin.1.1' + sink 'mixout.2.1' + } + { + source 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.capture' + sink 'host-copier.0.capture' + } + { + source 'host-copier.0.playback' + sink 'gain.1.1' + } + ] + } + "multiband" { + Object.Base.route [ + { + sink 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.playback' + source 'multiband_drc.2.1' + } + { + source 'mixin.1.1' + sink 'mixout.2.1' + } + { + source 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.capture' + sink 'host-copier.0.capture' + } + { + source 'host-copier.0.playback' + sink 'gain.1.1' + } + ] + } +} diff --git a/tools/topology/topology2/cavs-nocodec-multicore.conf b/tools/topology/topology2/cavs-nocodec-multicore.conf index 9c7e9c833b59..36c20c6b682d 100644 --- a/tools/topology/topology2/cavs-nocodec-multicore.conf +++ b/tools/topology/topology2/cavs-nocodec-multicore.conf @@ -315,46 +315,62 @@ IncludeByKey.PASSTHROUGH { stream_name 'Gain Capture 19' num_input_audio_formats 2 num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] } Object.Widget.gain.1 { num_input_audio_formats 2 num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] Object.Control.mixer.1 { name 'Pre Demux $DMIC0_PCM_0_NAME Capture Volume' } @@ -376,46 +392,62 @@ IncludeByKey.PASSTHROUGH { pcm_id $DMIC0_PCM_0_PCM_ID num_input_audio_formats 2 num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] } Object.Widget.gain.1 { num_input_audio_formats 2 num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] Object.Control.mixer.1 { name 'Post Demux $DMIC0_PCM_0_NAME Capture Volume' } @@ -434,46 +466,62 @@ IncludeByKey.PASSTHROUGH { pcm_id $DMIC0_PCM_1_PCM_ID num_input_audio_formats 2 num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] } Object.Widget.gain.1 { num_input_audio_formats 2 num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] Object.Control.mixer.1 { name 'Post Demux $DMIC0_PCM_1_NAME Capture Volume' } diff --git a/tools/topology/topology2/cavs-nocodec.conf b/tools/topology/topology2/cavs-nocodec.conf index bac1fe2118c7..7284769c5194 100644 --- a/tools/topology/topology2/cavs-nocodec.conf +++ b/tools/topology/topology2/cavs-nocodec.conf @@ -188,6 +188,7 @@ IncludeByKey.PASSTHROUGH { pcm_id 0 } Object.Widget.gain.1 { + curve_type "windows_fade" Object.Control.mixer.1 { name 'Pre Mixer $SSP0_PCM_NAME Playback Volume' } @@ -204,6 +205,7 @@ IncludeByKey.PASSTHROUGH { pcm_id 2 } Object.Widget.gain.1 { + curve_type "windows_fade" Object.Control.mixer.1 { name 'Pre Mixer $SSP2_PCM_NAME Playback Volume' } @@ -224,6 +226,7 @@ IncludeByKey.PASSTHROUGH { } Object.Widget.gain.1 { + curve_type "windows_fade" Object.Control.mixer.1 { name 'Post Mixer $SSP0_PCM_NAME Playback Volume' } @@ -259,6 +262,7 @@ IncludeByKey.PASSTHROUGH { } Object.Widget.gain.1 { + curve_type "windows_fade" Object.Control.mixer.1 { name 'Post Mixer $SSP2_PCM_NAME Playback Volume' } @@ -275,6 +279,7 @@ IncludeByKey.PASSTHROUGH { pcm_id $SSP0_PCM_ID } Object.Widget.gain.1 { + curve_type "windows_fade" Object.Control.mixer.1 { name 'Post Demux $SSP0_PCM_NAME Capture Volume' } @@ -289,6 +294,7 @@ IncludeByKey.PASSTHROUGH { pcm_id $SSP0_CAPTURE_PCM_ID } Object.Widget.gain.1 { + curve_type "windows_fade" Object.Control.mixer.1 { name 'Post Demux $SSP0_CAPTURE_PCM Volume' } @@ -307,48 +313,68 @@ IncludeByKey.PASSTHROUGH { } Object.Widget.module-copier.1 { stream_name 'Gain Capture 19' + num_input_audio_formats 2 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] } Object.Widget.gain.1 { + curve_type "windows_fade" num_input_audio_formats 2 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] Object.Control.mixer.1 { name 'Pre Demux $DMIC0_PCM_0_NAME Capture Volume' } @@ -368,13 +394,24 @@ IncludeByKey.PASSTHROUGH { copier_type "SSP" stream_name "NoCodec-0" node_type $I2S_LINK_INPUT_CLASS - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + + num_output_pins 2 Object.Base.output_pin_binding.1 { output_pin_binding_name "gain.8.1" } @@ -386,14 +423,24 @@ IncludeByKey.PASSTHROUGH { Object.Widget.module-copier."2" { stream_name "NoCodec-0" - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } Object.Widget.gain.1 { + curve_type "windows_fade" Object.Control.mixer.1 { name 'Pre Demux $SSP0_PCM_NAME Capture Volume' } @@ -633,12 +680,21 @@ Object.Pipeline.io-gateway-capture [ copier_type "SSP" stream_name "NoCodec-2" node_type $I2S_LINK_INPUT_CLASS - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } } ] @@ -678,47 +734,67 @@ IncludeByKey.PASSTHROUGH { stream_name "Gain Capture 18" pcm_id 27 num_input_audio_formats 2 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] } Object.Widget.gain.1 { + curve_type "windows_fade" num_input_audio_formats 2 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + Object.Control.mixer.1 { name 'Post Demux $DMIC0_PCM_0_NAME Capture Volume' } @@ -734,47 +810,67 @@ IncludeByKey.PASSTHROUGH { stream_name "Gain Capture 20" pcm_id 28 num_input_audio_formats 2 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] } Object.Widget.gain.1 { + curve_type "windows_fade" num_input_audio_formats 2 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + Object.Control.mixer.1 { name 'Post Demux $DMIC0_PCM_1_NAME Capture Volume' } @@ -1069,12 +1165,21 @@ IncludeByKey.SSP1_ENABLED { copier_type "SSP" stream_name "NoCodec-1" node_type $I2S_LINK_INPUT_CLASS - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } } ] @@ -1101,6 +1206,7 @@ IncludeByKey.SSP1_ENABLED { pcm_id 1 } Object.Widget.gain.1 { + curve_type "windows_fade" Object.Control.mixer.1 { name 'Pre Mixer $SSP1_PCM_NAME Playback Volume' } @@ -1121,6 +1227,7 @@ IncludeByKey.SSP1_ENABLED { } Object.Widget.gain.1 { + curve_type "windows_fade" Object.Control.mixer.1 { name 'Post Mixer $SSP1_PCM_NAME Playback Volume' } diff --git a/tools/topology/topology2/cavs-rt5682.conf b/tools/topology/topology2/cavs-rt5682.conf index f3cdc8d47aeb..721c97afe94e 100644 --- a/tools/topology/topology2/cavs-rt5682.conf +++ b/tools/topology/topology2/cavs-rt5682.conf @@ -87,7 +87,6 @@ Define { INCLUDE_ECHO_REF false ECHO_REF_HOST_PIPELINE_ID 7 ECHO_REF_DAI_PIPELINE_ID 8 - ECHO_REF_COPIER_MODULE 'module-copier.8.2' ECHO_REF_PCM_ID 29 ECHO_REF_CORE_ID 0 # override BT default definitions @@ -96,13 +95,16 @@ Define { BT_PB_DAI_PIPELINE_SRC "copier.host.9.1" BT_PB_PIPELINE_STREAM_NAME "dai-copier.SSP.10.1" GOOGLE_RTC_AEC_SUPPORT 0 - GOOGLE_RTC_AEC_REF_SOURCE 'module-copier.8.2' GOOGLE_AEC_CORE_ID 0 HEADSET_PCM_NAME "Headset" HEADSET_PCM_ID 0 SPEAKER_PCM_NAME "Speakers" SPEAKER_PCM_ID 1 INCLUDE_BT_OFFLOAD true + GOOGLE_AEC_HOST_PIPELINE_PRIORITY 3 + GOOGLE_AEC_PIPELINE_PRIORITY 2 + DMIC_PIPELINE_PRIORITY 1 + ECHO_REF_PIPELINE_PRIORITY 0 } # override defaults with platform-specific config diff --git a/tools/topology/topology2/cavs-sdw-src-gain-mixin.conf b/tools/topology/topology2/cavs-sdw-src-gain-mixin.conf index b4c5cc4244dd..17acf2ceac4f 100644 --- a/tools/topology/topology2/cavs-sdw-src-gain-mixin.conf +++ b/tools/topology/topology2/cavs-sdw-src-gain-mixin.conf @@ -120,11 +120,6 @@ Object.Pipeline { Object.Widget.host-copier.1 { stream_name "Passthrough Capture 0" pcm_id 1 - Object.Base.audio_format.1 { - # 32 -> 16 bits conversion is done here, - # so in_bit_depth is 32 (and out_bit_depth is 16). - in_bit_depth 32 - } } } ] diff --git a/tools/topology/topology2/development/cavs-nocodec-crossover.conf b/tools/topology/topology2/development/cavs-nocodec-crossover.conf index cc49e9c3ef84..710e9125d567 100644 --- a/tools/topology/topology2/development/cavs-nocodec-crossover.conf +++ b/tools/topology/topology2/development/cavs-nocodec-crossover.conf @@ -315,12 +315,6 @@ Object.Pipeline.io-gateway-capture [ copier_type "SSP" stream_name "NoCodec-2" node_type $I2S_LINK_INPUT_CLASS - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } } } ] diff --git a/tools/topology/topology2/development/cavs-nocodec-rtcaec.conf b/tools/topology/topology2/development/cavs-nocodec-rtcaec.conf new file mode 100644 index 000000000000..b79ca37ad4f2 --- /dev/null +++ b/tools/topology/topology2/development/cavs-nocodec-rtcaec.conf @@ -0,0 +1,378 @@ +<searchdir:include> +<searchdir:include/common> +<searchdir:include/components> +<searchdir:include/dais> +<searchdir:include/pipelines/cavs> +<searchdir:platform> +<searchdir:platform/intel> + +<vendor-token.conf> +<manifest.conf> +<tokens.conf> +<virtual.conf> +<host-gateway-capture.conf> +<host-gateway-playback.conf> +<io-gateway-capture.conf> +<io-gateway.conf> +<data.conf> +<pcm.conf> +<pcm_caps.conf> +<fe_dai.conf> +<ssp.conf> +<intel/hw_config_cardinal_clk.conf> +<manifest.conf> +<route.conf> +<intel/common_definitions.conf> +<dai-copier.conf> +<module-copier.conf> +<pipeline.conf> +<dai.conf> +<host.conf> +<input_pin_binding.conf> +<output_pin_binding.conf> +<input_audio_format.conf> +<output_audio_format.conf> + +<controls/bytes.conf> +<google-rtc-aec.conf> + +Define { + MCLK 24576000 + PLATFORM "none" + SSP0_PCM_ID 0 + SSP0_PCM_NAME "Port0" + SSP1_PCM_NAME "Port1" + SSP2_PCM_NAME "Port2" +} + +# override defaults with platform-specific config +IncludeByKey.PLATFORM { + "tgl" "platform/intel/tgl.conf" + "adl" "platform/intel/tgl.conf" + "mtl" "platform/intel/mtl.conf" + "lnl" "platform/intel/mtl.conf" +} + +# +# List of all DAIs +# +Object.Dai.SSP [ + { + id 0 + dai_index 0 + direction "duplex" + name NoCodec-0 + default_hw_conf_id 0 + sample_bits 32 + quirks "lbm_mode" + io_clk $MCLK + + Object.Base.hw_config.1 { + name "SSP0" + id 0 + bclk_freq 3072000 + tdm_slot_width 32 + # TODO: remove this. Needs alsaptlg change. + Object.Base.link_config.1 { + clock_source 1 + } + } + } + { + id 2 + dai_index 2 + direction "duplex" + name NoCodec-2 + default_hw_conf_id 0 + sample_bits 32 + quirks "lbm_mode" + io_clk $MCLK + + Object.Base.hw_config.1 { + name "SSP2" + id 0 + bclk_freq 3072000 + tdm_slot_width 32 + # TODO: remove this. Needs alsaptlg change. + Object.Base.link_config.1 { + clock_source 1 + } + } + } +] + +# +# Pipeline definitions +# +# PCM0 --(1)----------------(2)--> SSP0 +# +# PCM2 --(5)----------------(6)--> SSP2 +# +# SSP0 --(8)---> RTCAEC ----(7)--> PCM0 +# ^ +# | +# SSP2 --(12)------+ + +Object.Pipeline.io-gateway [ + { + index 2 + direction playback + + Object.Widget.dai-copier.1 { + dai_index 0 + dai_type "SSP" + copier_type "SSP" + stream_name "NoCodec-0" + node_type $I2S_LINK_OUTPUT_CLASS + num_input_pins 1 + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + } + } + { + index 6 + direction playback + + Object.Widget.dai-copier.1 { + dai_index 2 + dai_type "SSP" + copier_type "SSP" + stream_name "NoCodec-2" + node_type $I2S_LINK_OUTPUT_CLASS + num_input_pins 1 + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + } + } +] + +Object.Pipeline.host-gateway-playback [ + { + index 1 + Object.Widget.host-copier.1 { + stream_name 'SSP0 Playback' + pcm_id 0 + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + ] + } + } + { + index 5 + Object.Widget.host-copier.1 { + stream_name 'SSP2 Playback' + pcm_id 2 + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + ] + } + } +] + +Object.Pipeline.host-gateway-capture [ + { + index 7 + + Object.Widget.host-copier.1 { + stream_name 'SSP0 Capture' + pcm_id 0 + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + ] + } + } +] + +Object.Pipeline.io-gateway-capture [ + { + index 8 + direction capture + + Object.Widget.dai-copier.1 { + dai_index 0 + dai_type "SSP" + type dai_out + copier_type "SSP" + stream_name "NoCodec-0" + node_type $I2S_LINK_INPUT_CLASS + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + ] + } + } + { + index 12 + direction capture + + Object.Widget.dai-copier.1 { + dai_index 2 + dai_type "SSP" + type dai_out + copier_type "SSP" + stream_name "NoCodec-2" + node_type $I2S_LINK_INPUT_CLASS + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + ] + } + } +] + +Object.PCM.pcm [ + { + name "$SSP0_PCM_NAME" + id $SSP0_PCM_ID + direction "duplex" + Object.Base.fe_dai.1 { + name "$SSP0_PCM_NAME" + } + + Object.PCM.pcm_caps.1 { + direction "playback" + name "SSP0 Playback" + formats 'S16_LE' + } + + Object.PCM.pcm_caps.2 { + direction "capture" + name "SSP0 Capture" + formats 'S16_LE' + } + } + { + name "$SSP2_PCM_NAME" + id 2 + direction "playback" + Object.Base.fe_dai.1 { + name "$SSP2_PCM_NAME" + } + + Object.PCM.pcm_caps.1 { + direction "playback" + name "SSP2 Playback" + formats 'S16_LE' + } + } +] + +Object.Widget.google-rtc-aec [ + { + index 7 + name "google-rtc-aec.7.1" + + Object.Base.input_pin_binding.1 { + input_pin_binding_name "dai-copier.SSP.NoCodec-0.capture" + } + + Object.Base.input_pin_binding.2 { + input_pin_binding_name "dai-copier.SSP.NoCodec-2.capture" + } + + Object.Control.bytes."1" { + name 'google-rtc-aec bytes' + <include/components/google-rtc-aec/rtc-aec-blob.conf> + } + } +] + +Object.Base.route [ + { + source "host-copier.0.playback" + sink "dai-copier.SSP.NoCodec-0.playback" + } + { + source "host-copier.2.playback" + sink "dai-copier.SSP.NoCodec-2.playback" + } + { + source "dai-copier.SSP.NoCodec-0.capture" + sink "google-rtc-aec.7.1" + } + { + source "dai-copier.SSP.NoCodec-2.capture" + sink "google-rtc-aec.7.1" + } + { + source "google-rtc-aec.7.1" + sink "host-copier.0.capture" + } +] diff --git a/tools/topology/topology2/development/tplg-targets.cmake b/tools/topology/topology2/development/tplg-targets.cmake index a2245db252a3..c7c0134ae959 100644 --- a/tools/topology/topology2/development/tplg-targets.cmake +++ b/tools/topology/topology2/development/tplg-targets.cmake @@ -50,6 +50,11 @@ SSP2_CORE_ID=1,PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-mtl-nocodec-multicore-s SSP0_CORE_ID=0,DMIC_CORE_ID=1,SSP2_CORE_ID=2,NUM_DMICS=4,PDM1_MIC_A_ENABLE=1,PDM1_MIC_B_ENABLE=1,\ PASSTHROUGH=false,PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-mtl-nocodec.bin" +# SSP topology for LNL +"cavs-nocodec\;sof-lnl-nocodec\;PLATFORM=lnl,NUM_DMICS=4,PDM1_MIC_A_ENABLE=1,PDM1_MIC_B_ENABLE=1,\ +PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-lnl-nocodec.bin,DEEPBUFFER_FW_DMA_MS=100,\ +DEEPBUFFER_D0I3_COMPATIBLE=true" + # SSP topology for LNL FPGA with lower DMIC IO clock of 19.2MHz, 2ch PDM1 enabled "cavs-nocodec\;sof-lnl-nocodec-fpga-2ch-pdm1\;PLATFORM=lnl,NUM_DMICS=2,PDM1_MIC_A_ENABLE=1,\ PDM1_MIC_B_ENABLE=1,PDM0_MIC_A_ENABLE=0,PDM0_MIC_B_ENABLE=0,PREPROCESS_PLUGINS=nhlt,\ @@ -81,6 +86,22 @@ PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-hda-efx-generic-4ch.bin,USE_CHAIN_DMA= DEEPBUFFER_FW_DMA_MS=100,EFX_FIR_PARAMS=passthrough,EFX_IIR_PARAMS=passthrough,\ EFX_DRC_PARAMS=passthrough" +"sof-hda-generic\;sof-hda-efx-mbdrc-generic\;\ +HDA_CONFIG=efx,USE_CHAIN_DMA=true,DEEPBUFFER_FW_DMA_MS=100,\ +EFX_FIR_PARAMS=passthrough,EFX_IIR_PARAMS=passthrough,\ +EFX_DRC_COMPONENT=multiband,EFX_MBDRC_PARAMS=passthrough" + +"sof-hda-generic\;sof-hda-efx-mbdrc-generic-2ch\;\ +HDA_CONFIG=efx,NUM_DMICS=2,PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-hda-fir-generic-2ch.bin,\ +USE_CHAIN_DMA=true,DEEPBUFFER_FW_DMA_MS=100,EFX_FIR_PARAMS=passthrough,EFX_IIR_PARAMS=passthrough,\ +EFX_DRC_COMPONENT=multiband,EFX_MBDRC_PARAMS=passthrough" + +"sof-hda-generic\;sof-hda-efx-mbdrc-generic-4ch\;\ +HDA_CONFIG=efx,NUM_DMICS=4,PDM1_MIC_A_ENABLE=1,PDM1_MIC_B_ENABLE=1,\ +PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-hda-efx-generic-4ch.bin,USE_CHAIN_DMA=true,\ +DEEPBUFFER_FW_DMA_MS=100,EFX_FIR_PARAMS=passthrough,EFX_IIR_PARAMS=passthrough,\ +EFX_DRC_COMPONENT=multiband,EFX_MBDRC_PARAMS=passthrough" + # CAVS HDA topology with gain and SRC before mixin for HDA and passthrough pipelines for HDMI "sof-hda-generic\;sof-hda-src-generic\;HDA_CONFIG=src,USE_CHAIN_DMA=true,DEEPBUFFER_FW_DMA_MS=100" @@ -100,11 +121,29 @@ PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-nocodec-bt-mtl-lbm.bin" # CAVS HDA topology for benchmarking performance # Copier - peak volume - mixin - mixout - aria - peak volume - mixin - mixout - copier -"sof-hda-generic\;sof-hda-benchmark-generic-tgl\;PLATFORM=TGL,HDA_CONFIG=benchmark,USE_CHAIN_DMA=true" -"sof-hda-generic\;sof-hda-benchmark-generic-mtl\;PLATFORM=MTL,HDA_CONFIG=benchmark,USE_CHAIN_DMA=true" -"sof-hda-generic\;sof-hda-benchmark-generic-lnl\;PLATFORM=LNL,HDA_CONFIG=benchmark,USE_CHAIN_DMA=true" +"sof-hda-generic\;sof-hda-benchmark-generic-tgl\;PLATFORM=TGL,HDA_CONFIG=benchmark,USE_CHAIN_DMA=true,BENCH_CONFIG=benchmark" +"sof-hda-generic\;sof-hda-benchmark-generic-mtl\;PLATFORM=MTL,HDA_CONFIG=benchmark,USE_CHAIN_DMA=true,BENCH_CONFIG=benchmark" +"sof-hda-generic\;sof-hda-benchmark-generic-lnl\;PLATFORM=LNL,HDA_CONFIG=benchmark,USE_CHAIN_DMA=true,BENCH_CONFIG=benchmark" + +# Test topologies for simple one source and sink processing components +"sof-hda-generic\;sof-hda-benchmark-dcblock16-tgl\;PLATFORM=TGL,HDA_CONFIG=benchmark,BENCH_CONFIG=dcblock16,BENCH_DCBLOCK_PARAMS=default" +"sof-hda-generic\;sof-hda-benchmark-dcblock24-tgl\;PLATFORM=TGL,HDA_CONFIG=benchmark,BENCH_CONFIG=dcblock24,BENCH_DCBLOCK_PARAMS=default" +"sof-hda-generic\;sof-hda-benchmark-dcblock32-tgl\;PLATFORM=TGL,HDA_CONFIG=benchmark,BENCH_CONFIG=dcblock32,BENCH_DCBLOCK_PARAMS=default" +"sof-hda-generic\;sof-hda-benchmark-drc16-tgl\;PLATFORM=TGL,HDA_CONFIG=benchmark,BENCH_CONFIG=drc16,BENCH_DRC_PARAMS=enabled" +"sof-hda-generic\;sof-hda-benchmark-drc24-tgl\;PLATFORM=TGL,HDA_CONFIG=benchmark,BENCH_CONFIG=drc24,BENCH_DRC_PARAMS=enabled" +"sof-hda-generic\;sof-hda-benchmark-drc32-tgl\;PLATFORM=TGL,HDA_CONFIG=benchmark,BENCH_CONFIG=drc32,BENCH_DRC_PARAMS=enabled" +"sof-hda-generic\;sof-hda-benchmark-eqiir16-tgl\;PLATFORM=TGL,HDA_CONFIG=benchmark,BENCH_CONFIG=eqiir16,BENCH_EQIIR_PARAMS=highpass_50hz_0db_48khz" +"sof-hda-generic\;sof-hda-benchmark-eqiir24-tgl\;PLATFORM=TGL,HDA_CONFIG=benchmark,BENCH_CONFIG=eqiir24,BENCH_EQIIR_PARAMS=highpass_50hz_0db_48khz" +"sof-hda-generic\;sof-hda-benchmark-eqiir32-tgl\;PLATFORM=TGL,HDA_CONFIG=benchmark,BENCH_CONFIG=eqiir32,BENCH_EQIIR_PARAMS=highpass_50hz_0db_48khz" +"sof-hda-generic\;sof-hda-benchmark-eqfir16-tgl\;PLATFORM=TGL,HDA_CONFIG=benchmark,BENCH_CONFIG=eqfir16,BENCH_EQFIR_PARAMS=loudness" +"sof-hda-generic\;sof-hda-benchmark-eqfir24-tgl\;PLATFORM=TGL,HDA_CONFIG=benchmark,BENCH_CONFIG=eqfir24,BENCH_EQFIR_PARAMS=loudness" +"sof-hda-generic\;sof-hda-benchmark-eqfir32-tgl\;PLATFORM=TGL,HDA_CONFIG=benchmark,BENCH_CONFIG=eqfir32,BENCH_EQFIR_PARAMS=loudness" # Topology to test IPC4 Crossover "development/cavs-nocodec-crossover\;sof-tgl-nocodec-crossover-2way\;PLATFORM=tgl,\ PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-tgl-nocodec-crossover.bin,EFX_CROSSOVER_PARAMS=2way" + +# Topology to test RTC AEC +"development/cavs-nocodec-rtcaec\;sof-tgl-nocodec-rtcaec\;PLATFORM=tgl,\ +PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-tgl-nocodec-rtcaec.bin" ) diff --git a/tools/topology/topology2/doc/CMakeLists.txt b/tools/topology/topology2/doc/CMakeLists.txt new file mode 100644 index 000000000000..303d06da3d15 --- /dev/null +++ b/tools/topology/topology2/doc/CMakeLists.txt @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.13) + +project(SOF_TOPOLOGY2_DOC NONE) + +set(SOF_ROOT_SOURCE_DIRECTORY "${PROJECT_SOURCE_DIR}/..") + +set(top_srcdir "${SOF_ROOT_SOURCE_DIRECTORY}") +set(top_bindir "${PROJECT_BINARY_DIR}") + +configure_file( + "${PROJECT_SOURCE_DIR}/sof.doxygen.in" + "${PROJECT_BINARY_DIR}/sof.doxygen" +) + +file(GLOB_RECURSE topology2_sources "${SOF_ROOT_SOURCE_DIRECTORY}/*.conf") +file(GLOB_RECURSE extra_sources "${PROJECT_SOURCE_DIR}/extra-contents/*.doxy") + +add_custom_command( + OUTPUT ${PROJECT_BINARY_DIR}/contents.doxy + COMMAND ${PROJECT_SOURCE_DIR}/topology2-generate-contents.sh > ${PROJECT_BINARY_DIR}/contents.doxy + DEPENDS ${PROJECT_SOURCE_DIR}/topology2-generate-contents.sh + DEPENDS ${topology2_sources} + VERBATIM +) + +add_custom_target(doc-contents + DEPENDS ${PROJECT_BINARY_DIR}/contents.doxy +) + +add_custom_command( + OUTPUT ${PROJECT_BINARY_DIR}/doxygen/html/index.html + COMMAND doxygen sof.doxygen + DEPENDS ${PROJECT_BINARY_DIR}/sof.doxygen + DEPENDS ${PROJECT_SOURCE_DIR}/topology2-filter.py + DEPENDS doc-contents + DEPENDS ${extra_sources} + DEPENDS ${topology2_sources} + VERBATIM + USES_TERMINAL +) + +add_custom_target(doc ALL + DEPENDS ${PROJECT_BINARY_DIR}/doxygen/html/index.html + VERBATIM +) diff --git a/tools/topology/topology2/doc/README b/tools/topology/topology2/doc/README new file mode 100644 index 000000000000..a412e1d2d707 --- /dev/null +++ b/tools/topology/topology2/doc/README @@ -0,0 +1,7 @@ +To build the topology2 source documentation do following steps: + +cd tools/topology/topology2/doc +cmake -B build/ +cmake --build build/ -v + +After the last command you should find the html documentation under: sof/tools/topology/topology2/doc/build/doxygen/html diff --git a/tools/topology/topology2/doc/extra-contents/mainpage.doxy b/tools/topology/topology2/doc/extra-contents/mainpage.doxy new file mode 100644 index 000000000000..4b2a2bfcabc8 --- /dev/null +++ b/tools/topology/topology2/doc/extra-contents/mainpage.doxy @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2023 Intel Corporation. All rights reserved. */ +/*! \mainpage Sound Open Firmware Topology2 + * + * \section this_document This Document + * + * This document is generated from SOF topology2 sources and its + * purpose is provide examples of how SOF ALSA topologies are built + * through instantiating toppology2 classes. + * + * The documentation is provided using Doxygen package and a Doxygen + * filter that translates the topology2 classes into C-structures. The + * filter is implemented in python and can be found from + * tools/topology/topology2/doc/topology2-filter.py + * + * The topology2 language syntax is described in detail <a + * href="https://thesofproject.github.io/latest/developer_guides/topology2/topology2.html">here</a>. + * + * \subsection doc_reading Reading the document + * + * The purpose of the translated C code is not to document actual + * topology2 code, but only to provide anchors for Doxygen to form a + * network of links through which to navigate the topology sources and + * find the pieces of related Doxygen documentation. The filter also + * creates separate pages of the original code and add links next to + * the pages in the C struct definition and instance documentation. + * + * The most essential part of the documentation is the documentation of + * classes that shown as C structs in this Doxygen documentation. + * + * \copydoc doc_contents + */ diff --git a/tools/topology/topology2/doc/sof.doxygen.in b/tools/topology/topology2/doc/sof.doxygen.in new file mode 100644 index 000000000000..8e278f79bfa3 --- /dev/null +++ b/tools/topology/topology2/doc/sof.doxygen.in @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: BSD-3-Clause +PROJECT_NAME = "Sound Open Firmware Topology2" +OUTPUT_DIRECTORY = doxygen +GENERATE_LATEX = NO +GENERATE_RTF = NO +GENERATE_MAN = NO +GENERATE_XML = YES + +CASE_SENSE_NAMES = NO +INPUT = @top_srcdir@ \ + @top_srcdir@/doc/extra-contents/ \ + @top_bindir@/contents.doxy + +RECURSIVE = YES +FILE_PATTERNS = *.conf,*.doxy +IMAGE_PATH = +QUIET = YES +WARN_LOGFILE = doxygen_warnings.txt + +EXTRACT_ALL = YES +EXTRACT_STATIC = YES +WARN_IF_UNDOCUMENTED = NO +SHOW_INCLUDE_FILES = YES +JAVADOC_AUTOBRIEF = YES +INHERIT_DOCS = YES + +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +OPTIMIZE_OUTPUT_FOR_C = YES + +HTML_TIMESTAMP = NO + +EXTENSION_MAPPING = conf=C,doxy=C +FILTER_PATTERNS = *.conf=@top_srcdir@/doc/topology2-filter.py diff --git a/tools/topology/topology2/doc/topology2-filter.py b/tools/topology/topology2/doc/topology2-filter.py new file mode 100755 index 000000000000..7ff465c66be7 --- /dev/null +++ b/tools/topology/topology2/doc/topology2-filter.py @@ -0,0 +1,745 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2023 Intel Corporation. All rights reserved. +# +# The usage of this command is simple. It takes one argument, a path +# to a SOF topology2 source file, and it produces to stdout something +# that can be parsed by Doxygen as C source. Produced output contains +# C struct definitions and instantiations analogous to the topology2 +# classes and object instances. +# +# The purpose of the translated C code is not to document actual +# topology2 code, but only to provide anchors for Doxygen to form a +# network of links through which to navigate the topology sources and +# find the pieces of related Doxygen documentation. The filter also +# creates separate pages of the original code and adds links next to the +# pages in the C struct definition, instance documentation and their +# possible Doxygen documentation. + +import sys +import os +import re +import io +import logging + +logging.basicConfig(filename='filter_debug.txt', filemode='a', encoding='utf-8', + level=logging.DEBUG) + +def fname(): + try: + name = sys._getframe(1).f_code.co_name + except (IndexError, TypeError, AttributeError): + name = "<unknown>" + return name + +def cbracket_count(line): + val = line.count("{") - line.count("}") + return val + +def sbracket_count(line): + val = line.count("[") - line.count("]") + return val + +def doxy_check_add(doxy, line): + if line.find("##") >= 0: + doxy = doxy + line[line.find("##"):].replace("##", "//!", 1) + if line.find("#") >= 0: + line = line[0:line.find("#")] + return (doxy, line) + +def print_doxy(doxy, file = sys.stdout): + if len(doxy): + print(doxy, file=file) + return "" + return doxy + +def parse_include_str(line): + if re.search(r"^\s*\<[A-Za-z0-9\/_\-\.]+\>\s*", line): + tok = line.split() + return "#include " + tok[0] + "\n" + return None + +def parse_include(line): + str = parse_include_str(line) + if str: + print(str) + return True + return False + +def parse_define_block(fline, instream): + """Parses topology2 Define { } block and outputs C-preprocessor #define macros + + Parameters: + fline (string): First input line that was read by the caller + instream (stream): Input stream of topology2 file we are decoding + + Returns: + string: The original code that was translated + """ + if re.search(r"^\s*Define\s+\{", fline): + logging.debug("fline: %s", fline) + doxy = "" + for line in instream: + if cbracket_count(line) < 0: + break + (doxy, line) = doxy_check_add(doxy, line) + doxy = print_doxy(doxy) + tok = line.split(maxsplit = 2) + if len(tok) < 2: + continue + val = trim_value(line[line.find(tok[0]) + len(tok[0]):]) + print("#define %s\t%s" % (trim_c_id(tok[0]), val)) + return True + return False + +def parse_include_by_key(fline, instream, file): # For now just skip + """Handles IncludeByKey { } blocks, currently handles only actual + includes, not nested {} blocks but everything is included into + raw_code return value. + + Parameters: + fline (string): First input line that was read by the caller + instream (stream): Input stream of topology2 file we are decoding + file (stream): Output stream for the translated output + + Returns: + string: The original code that was translated + + """ + if re.search(r"^\s*IncludeByKey\.", fline): + logging.debug("fline: %s", fline) + bsum = cbracket_count(fline) + if bsum == 1: + # Assume IncludeByKey.<variable> { + tok = fline.split() + tok = tok[0].split(".") + name = tok[1] + raw_code = "" + ifstr = "if" + for line in instream: + raw_code = raw_code + line + bsum = bsum + cbracket_count(line) + tok = line.split("\"") + if len(tok) >= 4: + print("#%s %s == \"%s\"\n#include <%s>" % + (ifstr, name, tok[1], tok[3]), file = file) + if ifstr == "if": + ifstr = "elif" + if bsum < 1: + if ifstr != "if": + print("#endif", file = file) + return raw_code + return None + +def trim_value(val): + val = val.strip(" \t\n$") + end = len(val) - 1 + if val[0:1] == "\"" and val[end:] == "\"": + return val + if val.isidentifier() or val.isnumeric(): + return val + if val[0:1] == "\'" and val[end:] == "\'": + val = val.strip("\'") + return "\"" + val + "\"" + +def trim_c_id(name): + name = name.strip(" \t\n\"\'") + name = name.replace("-", "_") + name = name.replace(" ", "_") + return name + + +def parse_attribute_constraints(instream, name): + """Parses a Constraints { } block and produces a C enum definition if possible + + Parameters: + instream (stream): Input stream of topology2 file we are decoding + name (string): Attribute name of this constraints block belongs to + + Returns: + string: C enum definition or an empty string + + """ + logging.debug("name: %s", name) + valid_values = [] + tuple_values = [] + doxy = "" # This is thrown away since there is no C anchror to connect it- + raw_code = "" + enum = "" + for line in instream: + raw_code = raw_code + line + (doxy, line) = doxy_check_add(doxy, line) + if cbracket_count(line) < 0: + break + if re.search(r"^\s*\!valid_values\s+\[", line): + for line in instream: + raw_code = raw_code + line + (doxy, line) = doxy_check_add(doxy, line) + if sbracket_count(line) < 0: + break + valid_values.append(trim_c_id(line)) + if re.search(r"^\s*\!tuple_values\s+\[", line): + for line in instream: + raw_code = raw_code + line + (doxy, line) = doxy_check_add(doxy, line) + if sbracket_count(line) < 0: + break + tuple_values.append(trim_value(line)) + if len(valid_values) > 1 and len(valid_values) == len(tuple_values): + enum = "enum " + name + " {\n" + for i in range(len(valid_values)): + enum = enum + "\t\t" + valid_values[i] + " =\t" + tuple_values[i] + ",\n" + enum = enum + "\t}" + elif len(valid_values) > 1 and len(tuple_values) == 0: + enum = "enum " + name + " {\n" + for i in range(len(valid_values)): + enum = enum + "\t\t" + valid_values[i] + "," + if valid_values[i][0:1] == "$": # If its a variable add a reference to it + enum = enum + " //!< \\ref " + valid_values[i][1:] + enum = enum + "\n" + enum = enum + "\t}" + return (raw_code, enum) + +def parse_class_attribute(attributes, doxy, instream, fline): + """Parses a DefineAttribute { } block and collects the information into + attributes dict. Any already accumulated Doxygen documentation is + also stored there under the attribute name- + + Parameters: + attributes (dict): A dictionary where data about the attribute is stored + doxy (strung): Doxygen documentation collected just before the attribute + instream (stream): Input stream of topology2 file we are decoding + fline (string): First input line that was read by the caller + + Returns: + string: The original code that was translated + """ + logging.debug("fline: %s", fline) + tok = fline.split("\"") + if len(tok) > 1: + name = tok[1] + else: + tok = fline.split(".") + tok = tok[1].split(" ") + name = tok[0] + (doxy, fline) = doxy_check_add(doxy, fline) + bsum = cbracket_count(fline) + typestr = "" + token_ref = "" + ref_type = "" + enum = "" + raw_code = "" + if bsum < 1: + # Assume: DefineAttribute.name {} + typestr = "int" + else: + for line in instream: + raw_code = raw_code + line + (doxy, line) = doxy_check_add(doxy, line) + bsum = bsum + cbracket_count(line) + if bsum < 1: + break + if re.search(r"^\s*constraints\s+\{", line) and bsum == 2: + (code, enum) = parse_attribute_constraints(instream, name) + raw_code = raw_code + code + bsum = 1 + elif re.search(r"^\s*type\s", line): + tok = line.split() + typestr = tok[1].strip(" \t\n\"\'") + elif re.search(r"^\s*token_ref\s", line): + tok = line.split() + token_ref = tok[1].strip(" \t\n\"\'") + tok = token_ref.split(".") + ref_type = tok[1] + logging.debug("type %s token_ref %s ref_type %s enum %s", + typestr, token_ref, ref_type, enum) + if enum != "" and ref_type != "bool": + typestr = enum + if ref_type == "string": + doxy = doxy + "//! \\em string type\n" + elif typestr == "" or ref_type == "bool": + typestr = ref_type + attributes[name] = { "type": typestr, "doxy": doxy, "token_ref": token_ref } + return raw_code + +def print_attributes(attributes): + """Print out struct members and their doxygen documentation from attributes dict. + + Parameters: + attributes (dict): A dictionary where data about the attributes was stored + """ + for name in attributes: + doxy = "" + if attributes[name].get("doxy"): + doxy = attributes[name]["doxy"] + "\n" + if attributes[name].get("type"): + typestr = attributes[name]["type"] + print("%s\t%s %s;\n" % (doxy, typestr, name)) + +def set_attribute_flag(attributes, attribute, flag): + if not attributes.get(attribute): + attributes[attribute] = {} + attributes[attribute][flag] = True + +def parse_attributes_block(instream, attributes, attrib_doxy): + """Parse attributes block inside class definition and store the flags in attributes dict + + Parameters: + instream (stream): Input stream of topology2 file we are decoding + attributes (dict): Dict where data about the attributes is stored + attrib_doxy (dict): Dict to store doxygen docs associated with the attributes block + + Returns: + string: The original code that was translated + """ + logging.debug("called") + raw_code = "" + doxy = "" + for line in instream: + raw_code = raw_code + line + (doxy, line) = doxy_check_add(doxy, line) + if cbracket_count(line) < 0: + break + if re.search(r"^\s*\!constructor\s+\[", line): + for line in instream: + raw_code = raw_code + line + (doxy, line) = doxy_check_add(doxy, line) + if sbracket_count(line) < 0: + break + set_attribute_flag(attributes, trim_c_id(line), "constructor") + attrib_doxy["constructor"] = doxy + doxy = "" + elif re.search(r"^\s*\!mandatory\s+\[", line): + for line in instream: + raw_code = raw_code + line + (doxy, line) = doxy_check_add(doxy, line) + if sbracket_count(line) < 0: + break + set_attribute_flag(attributes, trim_c_id(line), "mandatory") + attrib_doxy["mandatory"] = doxy + doxy = "" + elif re.search(r"^\s*\!immutable\s+\[", line): + for line in instream: + raw_code = raw_code + line + (doxy, line) = doxy_check_add(doxy, line) + if sbracket_count(line) < 0: + break + set_attribute_flag(attributes, trim_c_id(line), "immutable") + attrib_doxy["immutable"] = doxy + doxy = "" + elif re.search(r"^\s*\!deprecated\s+\[", line): + attrib_doxy["deprecated"] = doxy + doxy = "" + for line in instream: + raw_code = raw_code + line + (doxy, line) = doxy_check_add(doxy, line) + if sbracket_count(line) < 0: + break + set_attribute_flag(attributes, trim_c_id(line), "deprecated") + elif re.search(r"^\s*unique\s+", line): + tok = line.split() + attrib_doxy["unique"] = doxy + doxy = "" + set_attribute_flag(attributes, trim_c_id(tok[1]), "unique") + return raw_code + +def attribute_block_print(class_name, attributes, attrib_doxy): + """Generates a Doxygen documentation section from attribute flags + and doxygen docs stored to attrib_doxy + + Parameters: + class_name (string): Name of the class we are processing + attributes (dict): Dict where data about the attributes was stored + attrib_doxy (dict): Dict where doxygen docs of the attributes block was stored + + """ + logging.debug("class_name \'%s\'", class_name) + for field in attrib_doxy: + # Only add attribute paragraph if there are doxygen comment for it + if attrib_doxy[field] != "": + print("//! \\par %s attributes:\n//!" % field.capitalize()) + for attr in attributes: + if attributes[attr].get(field): + print("//! \\link %s::%s \\endlink \\n" % (class_name, attr)) + print("//! \\n\n%s" % attrib_doxy[field]) + +def attribute_block_info_add(attributes, attrib_doxy): + """Add simple bullets in the attribute (= struct members) documentation if + the attribute has constructor, mandatory, immutable, deprecated, or unique + property. + + Parameters: + attributes (dict): Dict where data about the attributes was stored + attrib_doxy (dict): Dict where doxygen docs of the attributes block was stored + + """ + # TODO: Add short documentation about the attribute properties and link to it. + for field in attrib_doxy: + for attr in attributes: + if attributes[attr].get(field): + if not attributes[attr].get("doxy"): + attributes[attr]["doxy"] = "" + attributes[attr]["doxy"] = "//! - \\em " + field + " attribute.\\n\n" + attributes[attr]["doxy"] + +def parse_class_contents(class_name, attributes, attrib_doxy, objs, defaults, + instream, includef = ""): + """Translates the contents inside a class definition { } block + + Parameters: + class_name (string): Class name + attributes (dict): Dict where data about the attributes is stored + attrib_doxy (dict): Dict to store doxygen docs associated with the attributes block + objs (dict): Dict to store fist level contained objects with Docxyge docs + defaults (streaM): Stream where the instances of the objects are printed + instream (stream): Input stream of topology2 file we are decoding + includef (string): Include file from where the attributes and objects inline included from + + Returns: + string: The original code that was translated + """ + bsum = 1 + doxy_addition = "" + if includef != "": + doxy_addition = "//! - Included from <" + includef + ">\\n\n" + doxy = "" + raw_code = "" + for line in instream: + raw_code = raw_code + line + if parse_include_str(line): + # Inline files that are included from within a class definition + filename = line[line.find("<") + 1:line.find(">")] + logging.debug("try to inline include \'%s\' from \'%s\'", + filename, os.getcwd()) + # NOTE: The path is relative to when the script exists so + # two levels up and we are at topology2 root + with open("../../" + filename, "r+", encoding="ascii") as ifile: + parse_class_contents(class_name, attributes, attrib_doxy, objs, + defaults, ifile, filename) + continue + if (code := parse_include_by_key(line, instream, sys.stdout)): + raw_code = raw_code + code + continue + if re.search(r"^\s*DefineAttribute\.", line): + doxy = doxy_addition + doxy + raw_code = raw_code + parse_class_attribute(attributes, doxy, instream, line) + doxy = "" + elif re.search(r"^\s*DefineArgument\.", line): + for line in instream: # Just skip, this is only used in bytes.conf + if cbracket_count(line) < 0: + break + elif re.search(r"^\s*attributes\s+\{", line): + doxy = "" # Doxy comments before attributes block end in weird places + raw_code = raw_code + parse_attributes_block(instream, attributes, attrib_doxy) + elif re.search(r"^\s*Object\.", line): + # TODO: Pass collected doxy comments to parse_object and store in objs + doxy = "" + raw_code = raw_code + parse_object(instream, line, file = defaults, + objects = objs, tabs = "\t", ending = ",") + else: # If nothing else matched, assume a default value definition for an attribute + (doxy, line) = doxy_check_add(doxy, line) + tok = line.split() + if len(tok) == 2 and tok[0].isidentifier(): + if doxy != "": + print(doxy, file = defaults) + doxy = "" + val = trim_value(line[line.find(tok[0]) + len(tok[0]):]) + print("\t.%s =\t%s," % (trim_c_id(tok[0]), val), + file = defaults) + bsum = bsum + cbracket_count(line) + if bsum < 1: + break + return raw_code + +def parse_class(instream, fline): + """Parse class definition and print out C struct definition + + Parameters: + fline (string): First input line that was read by the caller + instream (stream): Input stream of topology2 file we are decoding + """ + logging.debug("fline: %s", fline) + tok = fline.split(maxsplit = 2) + cdef = tok[0].split(".") + # base = cdef[1] # Just in case we go back to C++ tralation + class_name = cdef[2] + class_name = trim_c_id(class_name) + attributes = {} + attrib_doxy = {} + defaults = io.StringIO() + objs = {} + raw_code = fline + parse_class_contents(class_name, attributes, attrib_doxy, + objs, defaults, instream) + attribute_block_print(class_name, attributes, attrib_doxy) + attribute_block_info_add(attributes, attrib_doxy) + print("//! \\ref %s_rawcode" % class_name) + print("struct %s {" % class_name) + print_attributes(attributes) + for obj in objs: + if objs[obj]["count"] > 1: + for i in range(objs[obj]["count"]): + print(objs[obj]["doxy"][i]) + print("\tstruct %s %s%d;" % (obj, obj, i)) + else: + print(objs[obj]["doxy"][0]) + print("\tstruct %s %s;" % (obj, obj)) + print("};\n") + print("/*! \\page %s_rawcode The %s class definition in topology2 code\n\t\\code{.unparsed}" % + (class_name, class_name)) + print(raw_code) + print("\t\\endcode\n*/") + print("//! \\var struct %s %s_defaults" % (class_name, class_name)) + print("//! \\brief %s class default values" % class_name) + print("struct %s %s_defaults = {\n" % (class_name, class_name)) + print(defaults.getvalue()) + print("};\n") + defaults.close() + +def parse_members(instream, cbsum, tabs, file): + """Parse attribute initializations from object instantiation + + Parameters: + instream (stream): Input stream of topology2 file we are decoding + cbsum (int): The amount of curly brackets "{" WE HAVE OPEN + tabs (string): Current level of indentation + + Returns: + string: The original code that was translated + """ + doxy = "" + raw_code = "" + for line in instream: + raw_code = raw_code + line + if (code := parse_include_by_key(line, instream, file)): + raw_code = raw_code + code + continue + cbsum = cbsum + cbracket_count(line) + (doxy, line) = doxy_check_add(doxy, line) + # Assume ending } to be alone on its own line + if cbsum < 1: + break + if re.search(r"^\s*Object\.", line): + logging.debug("object-line: %s", line) + obj = line.split(".") + if cbsum == 2: + # Assume Object.Base.name.1 { + doxy = print_doxy(doxy, file = file) + raw_code = raw_code + parse_object(instream, line, file = file, tabs = tabs, ending = ",") + cbsum = 1 + elif cbsum == 1: + # Assume Object.Base.name.1 {} + doxy = print_doxy(doxy, file = file) + print("%s.%s = {}," % (tabs, obj[2]), file = file) + else: + tok = line.split(maxsplit = 1) + if len(tok) >=2: + name = tok[0] + val = trim_value(tok[1]) + doxy = print_doxy(doxy, file = file) + print("%s.%s = %s," % (tabs, name, val), file = file) + return raw_code + +# +def object_instance_prefix(name, ending): + """Decide "struct name name =" or ".name =" based on instantiation ending in ',' or ';' + + Parameters: + name (string): Name of the object instance + ending (string): Either ',' or ';' indication if this is an instance or a definition + + """ + if ending == ";": + return "struct " + name + " " + return "." + +def parse_object(instream, fline, file = sys.stdout, objects = {}, tabs = "", ending = ";"): + """Translates all Object instatiation into initialized C structs + Note that dict arguments in python are passed as reference + + Parameters: + instream (stream): Input stream of topology2 file we are decoding + fline (string): First input line that was read by the caller + file (stream): Where the C struct instance or definition is printed + objects (dict): Dict to store fist level contained objects with Docxyge docs + ending (string): Either ',' or ';' indication if this is an instance or a definition + tabs (string): Current level of indentation + + Returns: + string: The original code that was translated + """ + logging.debug("fline: %s", fline) + tok = fline.split(maxsplit = 2) + obj = tok[0].split(".") + cbsum = cbracket_count(fline) + sbsum = sbracket_count(fline) + name = "" + doxy = "" + raw_code = "" + if len(obj) == 4 and sbsum == 0 and cbsum == 0: + # Assume Object.Base.name.1 { } + name = obj[2] + name = trim_c_id(name) + doxy = print_doxy(doxy, file = file) + prefix = object_instance_prefix(name, ending) + print("%s%s = {}%s" % (prefix, name, ending), file = file) + objects[name] = { "count": 1, "doxy": [doxy] } + elif len(obj) == 4 and sbsum == 0 and cbsum == 1: + # Assume Object.Base.name.1 { + name = obj[2] + name = trim_c_id(name) + doxy = print_doxy(doxy, file = file) + prefix = object_instance_prefix(name, ending) + print("%s%s%s = {" % (tabs, prefix, name), file = file) + raw_code = raw_code + parse_members(instream, cbsum, tabs + "\t", file) + print("%s}%s" % (tabs, ending), file = file) + objects[name] = { "count": 1, "doxy": [doxy] } + elif len(obj) == 3 and sbsum == 1 and cbsum == 0: + # Assume Object.Base.name [ + name = obj[2] + name = trim_c_id(name) + doxy = print_doxy(doxy, file = file) + prefix = object_instance_prefix(name, ending) + print("%s%s%s[] = {" % (tabs, prefix, name), file = file) + objects[name] = { "count": 0, "doxy": [] } + for line in instream: + raw_code = raw_code + line + if parse_include(line): + continue + if (code := parse_include_by_key(line, instream, sys.stdout)): + raw_code = raw_code + code + continue + sbsum = sbsum + sbracket_count(line) + cbsum = cbsum + cbracket_count(line) + (doxy, line) = doxy_check_add(doxy, line) + if sbsum < 1: + print("%s}%s" % (tabs, ending), file = file) + break + if cbsum == 1: # Assume starting { on its own line + objects[name]["count"] = objects[name]["count"] + 1 + objects[name]["doxy"].append(doxy) + doxy = print_doxy(doxy, file = file) + print("%s\t{" % tabs, file = file) + raw_code = raw_code + parse_members(instream, cbsum, tabs + "\t\t", file) + cbsum = 0 + print("%s\t}," % tabs, file = file) + elif len(obj) == 2 and sbsum == 0 and cbsum == 1: + # Assume Object.Base { + for line in instream: + raw_code = raw_code + line + if parse_include(line): + continue + if (code := parse_include_by_key(line, instream, file)): + raw_code = raw_code + code + continue + sbsum = sbsum + sbracket_count(line) + cbsum = cbsum + cbracket_count(line) + (doxy, line) = doxy_check_add(doxy, line) + if cbsum < 1: # Ending } found + break + if sbsum == 1 and cbsum == 1 and sbracket_count(line) > 0: + # Assume Class_name [ + tok = line.split() + name = trim_c_id(tok[0]) + objects[name] = { "count": 0, "doxy": [] } + doxy = print_doxy(doxy, file = file) + prefix = object_instance_prefix(name, ending) + print("%s%s%s[] = {" % (tabs, prefix, name), file = file) + elif sbsum == 1 and cbsum == 2: + # Assume class_name [ \n { \n + objects[name]["count"] = objects[name]["count"] + 1 + objects[name]["doxy"].append(doxy) + doxy = print_doxy(doxy, file = file) + print("%s\t{" % tabs, file = file) + raw_code = raw_code + parse_members(instream, 1, tabs + "\t\t", file) + print("%s\t}," % tabs, file = file) + cbsum = 1 + elif sbsum == 0 and cbsum == 1 and sbracket_count(line) < 0: + # Assume ending ] of class table alone one its own line + print("%s}%s" % (tabs, ending), file = file) + elif sbsum == 0 and cbsum == 1 and line.count("}") == 1: + # Assume name."1" {} + # No init values, so no instantiation code needed, but we still need + # to store the object into objexts dict. + tok = line.split() + tok = tok[0].split(".") + name = trim_c_id(tok[0]) + if not objects.get(name): + objects[name] = { "count": 0, "doxy": [] } + objects[name]["count"] = objects[name]["count"] + 1 + objects[name]["doxy"].append(doxy) + doxy = print_doxy(doxy, file = file) + elif sbsum == 0 and cbsum == 2 and cbracket_count(line) == 1: + # Assume name."1" { + tok = line.split() + tok = tok[0].split(".") + name = trim_c_id(tok[0]) + mname = name + if len(tok) > 1: + idx = tok[1].strip(" \"\'") + if idx.isidentifier() or idx.isnumeric(): + mname = mname + "_" + idx + if not objects.get(name): + objects[name] = { "count": 0, "doxy": [] } + objects[name]["count"] = objects[name]["count"] + 1 + objects[name]["doxy"].append(doxy) + doxy = print_doxy(doxy, file = file) + prefix = object_instance_prefix(name, ending) + print("%s%s%s = {" % (tabs, prefix, mname), file = file) + raw_code = raw_code + parse_members(instream, 1, tabs + "\t", file) + cbsum = 1 + print("%s}%s" % (tabs, ending), file = file) + return raw_code + +def parse_object_and_make_raw_code_page(filename, index, instream, fline): + """Parses an object instance outputs its C equivalent, and creates a raw code page of + of it and prints a reference to it. Handles an "Object.... {}" instance completely + and produces possibly multiple initialized C structs, but always just one raw code + block containing the "Object.... {}" block completely. + + Parameters: + filename (stream): Name of the file we are paring + index (int): The index of the decoded Object block in this file we are handling + instream (stream): Input stream of topology2 file we are decoding + fline (string): First input line that was read by the caller + + """ + tok = filename.split("/") + filename = fname = tok[len(tok)-1] + fname = fname.replace("-", "_") + fname = fname.replace(".", "_") + c_instances = io.StringIO() + raw_code = fline + parse_object(instream, fline, c_instances) + print("/*! \\page %s_%d_rawcode The %s instances #%d in topology2 code\n\t\\code{.unparsed}" % + (fname, index, filename, index)) + print(raw_code) + print("\t\\endcode\n*/") + print("//! \\brief \\ref %s_%d_rawcode" % (fname, index)) + print(c_instances.getvalue()) + c_instances.close() + +# Main starts here, apart from debug file opening +filename = sys.argv[1] +logging.info("file: %s", filename) +with open(filename, "r+", encoding="ascii") as instream: + block_idx = 0 + + shortfname = filename[filename.find("/topology2/"):] + print("//! \\file %s" % shortfname[11:]) + print("//! Source file can be found " + + "<a href=\"https://github.com/thesofproject/sof/tree/main/tools/topology%s\">here</a>." + % shortfname) + for line in instream: + if parse_include(line): + continue + if parse_define_block(line, instream): + continue + if parse_include_by_key(line, instream, sys.stdout): + continue + if re.search(r"^\s*Class\.", line): + parse_class(instream, line) + elif re.search(r"^\s*Object\.", line): + parse_object_and_make_raw_code_page(filename, block_idx, instream, line) + block_idx = block_idx + 1 + elif line.find("##") >= 0: + sys.stdout.write(line.replace("##", "//!", 1)) + else: + sys.stdout.write("\n") diff --git a/tools/topology/topology2/doc/topology2-generate-contents.sh b/tools/topology/topology2/doc/topology2-generate-contents.sh new file mode 100755 index 000000000000..ea5b4ed059cb --- /dev/null +++ b/tools/topology/topology2/doc/topology2-generate-contents.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2023 Intel Corporation. All rights reserved. +# This script generates the contents page and stores it in extra-contents/contents.doxy + +set -e +cd "$(dirname "$0")" + +generate_contents () +{ + cat <<EOF +# This contents list is automatically generated by $0. +/*! \page doc_contents + \section doc_classes Classes +EOF + for ctype in Base Widget Control Dai Pipeline + do + echo " \subsection doc_${ctype,}_classes $ctype Classes" + find .. -name \*.conf -print0 | + xargs -0 awk "/^Class\.$ctype\./ "'{ + split($1, a, "\\."); + name = a[3]; gsub("\"", "", name); gsub("-", "_", name); + print "\t\\li \\ref " name + }' | sort -u + echo + done + + echo '*/' +} + +generate_contents diff --git a/tools/topology/topology2/include/bench/bench_comp_generate.sh b/tools/topology/topology2/include/bench/bench_comp_generate.sh new file mode 100755 index 000000000000..2fe84698360b --- /dev/null +++ b/tools/topology/topology2/include/bench/bench_comp_generate.sh @@ -0,0 +1,104 @@ +#!/bin/bash + +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2023 Intel Corporation. All rights reserved. + +set -e + +main () { + if [ "$#" -ne 1 ]; then + echo "Usage: $0 <component>" + exit 1 + fi + comp=$1 + FULL_CMD=( "$0" "$@" ) + generate_comp "s16" + generate_comp "s24" + generate_comp "s32" + generate_route + generate_playback_controls + generate_capture_controls +} + +generate_comp () +{ + format=$1 + fn=${comp}_${format}.conf + echo Creating file "$fn" + cat > "$fn" <<EOF_COMP + # Created with script "${FULL_CMD[@]}" + Object.Widget.${comp}.1 { + index 1 + <include/bench/one_input_output_format_${format}.conf> + <include/bench/${comp}_control_bytes_playback.conf> + } + Object.Widget.${comp}.2 { + index 3 + <include/bench/one_input_output_format_${format}.conf> + <include/bench/${comp}_control_bytes_capture.conf> + } + <include/bench/host_io_gateway_pipelines_${format}.conf> + <include/bench/${comp}_hda_route.conf> +EOF_COMP +} + +generate_route () +{ + fn=${comp}_hda_route.conf + echo Creating file "$fn" + cat > "$fn" <<EOF_ROUTE + # Created with script "${FULL_CMD[@]}" + Object.Base.route [ + { + sink 'dai-copier.HDA.\$HDA_ANALOG_DAI_NAME.playback' + source '${comp}.1.1' + } + { + sink '${comp}.1.1' + source 'host-copier.0.playback' + } + { + source 'dai-copier.HDA.\$HDA_ANALOG_DAI_NAME.capture' + sink '${comp}.3.2' + } + { + source '${comp}.3.2' + sink 'host-copier.0.capture' + } + ] +EOF_ROUTE +} + +generate_playback_controls () +{ + fn=${comp}_control_bytes_playback.conf + echo Creating file "$fn" + cat > "$fn" <<EOF_PLAYBACK_BYTES + # Created initially with script "${FULL_CMD[@]}" + # may need edits to modify controls + Object.Control.bytes."1" { + name '\$ANALOG_PLAYBACK_PCM ${comp^^} bytes' + IncludeByKey.BENCH_${comp^^}_PARAMS { + "default" "include/components/${comp}/default.conf" + } + } +EOF_PLAYBACK_BYTES +} + +generate_capture_controls () +{ + fn=${comp}_control_bytes_capture.conf + echo Creating file "$fn" + cat > "$fn" <<EOF_CAPTURE_BYTES + # Created initially with script "${FULL_CMD[@]}" + # may need edits to modify controls + Object.Control.bytes."1" { + name '\$ANALOG_CAPTURE_PCM ${comp^^} bytes' + IncludeByKey.BENCH_${comp^^}_PARAMS { + "default" "include/components/${comp}/default.conf" + } + } +EOF_CAPTURE_BYTES +} + +main "$@" diff --git a/tools/topology/topology2/include/bench/dcblock_control_bytes_capture.conf b/tools/topology/topology2/include/bench/dcblock_control_bytes_capture.conf new file mode 100644 index 000000000000..3d39d5cc8874 --- /dev/null +++ b/tools/topology/topology2/include/bench/dcblock_control_bytes_capture.conf @@ -0,0 +1,8 @@ + # Created initially with script "./bench_comp_generate.sh dcblock" + # may need edits to modify controls + Object.Control.bytes."1" { + name '$ANALOG_CAPTURE_PCM DCBLOCK bytes' + IncludeByKey.BENCH_DCBLOCK_PARAMS { + "default" "include/components/dcblock/default.conf" + } + } diff --git a/tools/topology/topology2/include/bench/dcblock_control_bytes_playback.conf b/tools/topology/topology2/include/bench/dcblock_control_bytes_playback.conf new file mode 100644 index 000000000000..09885bcf561f --- /dev/null +++ b/tools/topology/topology2/include/bench/dcblock_control_bytes_playback.conf @@ -0,0 +1,8 @@ + # Created initially with script "./bench_comp_generate.sh dcblock" + # may need edits to modify controls + Object.Control.bytes."1" { + name '$ANALOG_PLAYBACK_PCM DCBLOCK bytes' + IncludeByKey.BENCH_DCBLOCK_PARAMS { + "default" "include/components/dcblock/default.conf" + } + } diff --git a/tools/topology/topology2/include/bench/dcblock_hda_route.conf b/tools/topology/topology2/include/bench/dcblock_hda_route.conf new file mode 100644 index 000000000000..2b494c67e839 --- /dev/null +++ b/tools/topology/topology2/include/bench/dcblock_hda_route.conf @@ -0,0 +1,19 @@ + # Created with script "./bench_comp_generate.sh dcblock" + Object.Base.route [ + { + sink 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.playback' + source 'dcblock.1.1' + } + { + sink 'dcblock.1.1' + source 'host-copier.0.playback' + } + { + source 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.capture' + sink 'dcblock.3.2' + } + { + source 'dcblock.3.2' + sink 'host-copier.0.capture' + } + ] diff --git a/tools/topology/topology2/include/bench/dcblock_s16.conf b/tools/topology/topology2/include/bench/dcblock_s16.conf new file mode 100644 index 000000000000..ae90114a2a16 --- /dev/null +++ b/tools/topology/topology2/include/bench/dcblock_s16.conf @@ -0,0 +1,13 @@ + # Created with script "./bench_comp_generate.sh dcblock" + Object.Widget.dcblock.1 { + index 1 + <include/bench/one_input_output_format_s16.conf> + <include/bench/dcblock_control_bytes_playback.conf> + } + Object.Widget.dcblock.2 { + index 3 + <include/bench/one_input_output_format_s16.conf> + <include/bench/dcblock_control_bytes_capture.conf> + } + <include/bench/host_io_gateway_pipelines_s16.conf> + <include/bench/dcblock_hda_route.conf> diff --git a/tools/topology/topology2/include/bench/dcblock_s24.conf b/tools/topology/topology2/include/bench/dcblock_s24.conf new file mode 100644 index 000000000000..ae24936a05a9 --- /dev/null +++ b/tools/topology/topology2/include/bench/dcblock_s24.conf @@ -0,0 +1,13 @@ + # Created with script "./bench_comp_generate.sh dcblock" + Object.Widget.dcblock.1 { + index 1 + <include/bench/one_input_output_format_s24.conf> + <include/bench/dcblock_control_bytes_playback.conf> + } + Object.Widget.dcblock.2 { + index 3 + <include/bench/one_input_output_format_s24.conf> + <include/bench/dcblock_control_bytes_capture.conf> + } + <include/bench/host_io_gateway_pipelines_s24.conf> + <include/bench/dcblock_hda_route.conf> diff --git a/tools/topology/topology2/include/bench/dcblock_s32.conf b/tools/topology/topology2/include/bench/dcblock_s32.conf new file mode 100644 index 000000000000..37bea24dd7a3 --- /dev/null +++ b/tools/topology/topology2/include/bench/dcblock_s32.conf @@ -0,0 +1,13 @@ + # Created with script "./bench_comp_generate.sh dcblock" + Object.Widget.dcblock.1 { + index 1 + <include/bench/one_input_output_format_s32.conf> + <include/bench/dcblock_control_bytes_playback.conf> + } + Object.Widget.dcblock.2 { + index 3 + <include/bench/one_input_output_format_s32.conf> + <include/bench/dcblock_control_bytes_capture.conf> + } + <include/bench/host_io_gateway_pipelines_s32.conf> + <include/bench/dcblock_hda_route.conf> diff --git a/tools/topology/topology2/include/bench/drc_control_bytes_capture.conf b/tools/topology/topology2/include/bench/drc_control_bytes_capture.conf new file mode 100644 index 000000000000..f688576394ac --- /dev/null +++ b/tools/topology/topology2/include/bench/drc_control_bytes_capture.conf @@ -0,0 +1,10 @@ + # Created initially with script "./bench_comp_generate.sh drc" + # may need edits to modify controls + Object.Control.bytes."1" { + name '$ANALOG_CAPTURE_PCM DRC bytes' + IncludeByKey.BENCH_DRC_PARAMS { + "default" "include/components/drc/default.conf" + "enabled" "include/components/drc/enabled.conf" + "passthrough" "include/components/drc/passthrough.conf" + } + } diff --git a/tools/topology/topology2/include/bench/drc_control_bytes_playback.conf b/tools/topology/topology2/include/bench/drc_control_bytes_playback.conf new file mode 100644 index 000000000000..ce7438e91410 --- /dev/null +++ b/tools/topology/topology2/include/bench/drc_control_bytes_playback.conf @@ -0,0 +1,10 @@ + # Created initially with script "./bench_comp_generate.sh drc" + # may need edits to modify controls + Object.Control.bytes."1" { + name '$ANALOG_PLAYBACK_PCM DRC bytes' + IncludeByKey.BENCH_DRC_PARAMS { + "default" "include/components/drc/default.conf" + "enabled" "include/components/drc/enabled.conf" + "passthrough" "include/components/drc/passthrough.conf" + } + } diff --git a/tools/topology/topology2/include/bench/drc_hda_route.conf b/tools/topology/topology2/include/bench/drc_hda_route.conf new file mode 100644 index 000000000000..8e9f475bd777 --- /dev/null +++ b/tools/topology/topology2/include/bench/drc_hda_route.conf @@ -0,0 +1,19 @@ + # Created with script "./bench_comp_generate.sh drc" + Object.Base.route [ + { + sink 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.playback' + source 'drc.1.1' + } + { + sink 'drc.1.1' + source 'host-copier.0.playback' + } + { + source 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.capture' + sink 'drc.3.2' + } + { + source 'drc.3.2' + sink 'host-copier.0.capture' + } + ] diff --git a/tools/topology/topology2/include/bench/drc_s16.conf b/tools/topology/topology2/include/bench/drc_s16.conf new file mode 100644 index 000000000000..7d02416c1eac --- /dev/null +++ b/tools/topology/topology2/include/bench/drc_s16.conf @@ -0,0 +1,13 @@ + # Created with script "./bench_comp_generate.sh drc" + Object.Widget.drc.1 { + index 1 + <include/bench/one_input_output_format_s16.conf> + <include/bench/drc_control_bytes_playback.conf> + } + Object.Widget.drc.2 { + index 3 + <include/bench/one_input_output_format_s16.conf> + <include/bench/drc_control_bytes_capture.conf> + } + <include/bench/host_io_gateway_pipelines_s16.conf> + <include/bench/drc_hda_route.conf> diff --git a/tools/topology/topology2/include/bench/drc_s24.conf b/tools/topology/topology2/include/bench/drc_s24.conf new file mode 100644 index 000000000000..c0d9689a7908 --- /dev/null +++ b/tools/topology/topology2/include/bench/drc_s24.conf @@ -0,0 +1,13 @@ + # Created with script "./bench_comp_generate.sh drc" + Object.Widget.drc.1 { + index 1 + <include/bench/one_input_output_format_s24.conf> + <include/bench/drc_control_bytes_playback.conf> + } + Object.Widget.drc.2 { + index 3 + <include/bench/one_input_output_format_s24.conf> + <include/bench/drc_control_bytes_capture.conf> + } + <include/bench/host_io_gateway_pipelines_s24.conf> + <include/bench/drc_hda_route.conf> diff --git a/tools/topology/topology2/include/bench/drc_s32.conf b/tools/topology/topology2/include/bench/drc_s32.conf new file mode 100644 index 000000000000..0ca828c30ec4 --- /dev/null +++ b/tools/topology/topology2/include/bench/drc_s32.conf @@ -0,0 +1,13 @@ + # Created with script "./bench_comp_generate.sh drc" + Object.Widget.drc.1 { + index 1 + <include/bench/one_input_output_format_s32.conf> + <include/bench/drc_control_bytes_playback.conf> + } + Object.Widget.drc.2 { + index 3 + <include/bench/one_input_output_format_s32.conf> + <include/bench/drc_control_bytes_capture.conf> + } + <include/bench/host_io_gateway_pipelines_s32.conf> + <include/bench/drc_hda_route.conf> diff --git a/tools/topology/topology2/include/bench/eqfir_control_bytes_capture.conf b/tools/topology/topology2/include/bench/eqfir_control_bytes_capture.conf new file mode 100644 index 000000000000..a63e00c85ad9 --- /dev/null +++ b/tools/topology/topology2/include/bench/eqfir_control_bytes_capture.conf @@ -0,0 +1,10 @@ + # Created initially with script "./bench_comp_generate.sh eqfir" + # may need edits to modify controls + Object.Control.bytes."1" { + name '$ANALOG_CAPTURE_PCM EQFIR bytes' + IncludeByKey.BENCH_EQFIR_PARAMS { + "default" "include/components/eqfir/default.conf" + "loudness" "include/components/eqfir/loudness.conf" + "passthrough" "include/components/eqfir/passthrough.conf" + } + } diff --git a/tools/topology/topology2/include/bench/eqfir_control_bytes_playback.conf b/tools/topology/topology2/include/bench/eqfir_control_bytes_playback.conf new file mode 100644 index 000000000000..aa0c0c8da8ea --- /dev/null +++ b/tools/topology/topology2/include/bench/eqfir_control_bytes_playback.conf @@ -0,0 +1,10 @@ + # Created initially with script "./bench_comp_generate.sh eqfir" + # may need edits to modify controls + Object.Control.bytes."1" { + name '$ANALOG_PLAYBACK_PCM EQFIR bytes' + IncludeByKey.BENCH_EQFIR_PARAMS { + "default" "include/components/eqfir/default.conf" + "loudness" "include/components/eqfir/loudness.conf" + "passthrough" "include/components/eqfir/passthrough.conf" + } + } diff --git a/tools/topology/topology2/include/bench/eqfir_hda_route.conf b/tools/topology/topology2/include/bench/eqfir_hda_route.conf new file mode 100644 index 000000000000..fd30c793326c --- /dev/null +++ b/tools/topology/topology2/include/bench/eqfir_hda_route.conf @@ -0,0 +1,19 @@ + # Created with script "./bench_comp_generate.sh eqfir" + Object.Base.route [ + { + sink 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.playback' + source 'eqfir.1.1' + } + { + sink 'eqfir.1.1' + source 'host-copier.0.playback' + } + { + source 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.capture' + sink 'eqfir.3.2' + } + { + source 'eqfir.3.2' + sink 'host-copier.0.capture' + } + ] diff --git a/tools/topology/topology2/include/bench/eqfir_s16.conf b/tools/topology/topology2/include/bench/eqfir_s16.conf new file mode 100644 index 000000000000..461323944062 --- /dev/null +++ b/tools/topology/topology2/include/bench/eqfir_s16.conf @@ -0,0 +1,13 @@ + # Created with script "./bench_comp_generate.sh eqfir" + Object.Widget.eqfir.1 { + index 1 + <include/bench/one_input_output_format_s16.conf> + <include/bench/eqfir_control_bytes_playback.conf> + } + Object.Widget.eqfir.2 { + index 3 + <include/bench/one_input_output_format_s16.conf> + <include/bench/eqfir_control_bytes_capture.conf> + } + <include/bench/host_io_gateway_pipelines_s16.conf> + <include/bench/eqfir_hda_route.conf> diff --git a/tools/topology/topology2/include/bench/eqfir_s24.conf b/tools/topology/topology2/include/bench/eqfir_s24.conf new file mode 100644 index 000000000000..ce2b303fe8f3 --- /dev/null +++ b/tools/topology/topology2/include/bench/eqfir_s24.conf @@ -0,0 +1,13 @@ + # Created with script "./bench_comp_generate.sh eqfir" + Object.Widget.eqfir.1 { + index 1 + <include/bench/one_input_output_format_s24.conf> + <include/bench/eqfir_control_bytes_playback.conf> + } + Object.Widget.eqfir.2 { + index 3 + <include/bench/one_input_output_format_s24.conf> + <include/bench/eqfir_control_bytes_capture.conf> + } + <include/bench/host_io_gateway_pipelines_s24.conf> + <include/bench/eqfir_hda_route.conf> diff --git a/tools/topology/topology2/include/bench/eqfir_s32.conf b/tools/topology/topology2/include/bench/eqfir_s32.conf new file mode 100644 index 000000000000..0e3dfa3732b4 --- /dev/null +++ b/tools/topology/topology2/include/bench/eqfir_s32.conf @@ -0,0 +1,13 @@ + # Created with script "./bench_comp_generate.sh eqfir" + Object.Widget.eqfir.1 { + index 1 + <include/bench/one_input_output_format_s32.conf> + <include/bench/eqfir_control_bytes_playback.conf> + } + Object.Widget.eqfir.2 { + index 3 + <include/bench/one_input_output_format_s32.conf> + <include/bench/eqfir_control_bytes_capture.conf> + } + <include/bench/host_io_gateway_pipelines_s32.conf> + <include/bench/eqfir_hda_route.conf> diff --git a/tools/topology/topology2/include/bench/eqiir_control_bytes_capture.conf b/tools/topology/topology2/include/bench/eqiir_control_bytes_capture.conf new file mode 100644 index 000000000000..a8b72846b969 --- /dev/null +++ b/tools/topology/topology2/include/bench/eqiir_control_bytes_capture.conf @@ -0,0 +1,9 @@ + # Created initially with script "./bench_comp_generate.sh eqiir" + # may need edits to modify controls + Object.Control.bytes."1" { + name '$ANALOG_CAPTURE_PCM EQIIR bytes' + IncludeByKey.BENCH_EQIIR_PARAMS { + "default" "include/components/eqiir/default.conf" + "highpass_50hz_0db_48khz" "include/components/eqiir/highpass_50hz_0db_48khz.conf" + } + } diff --git a/tools/topology/topology2/include/bench/eqiir_control_bytes_playback.conf b/tools/topology/topology2/include/bench/eqiir_control_bytes_playback.conf new file mode 100644 index 000000000000..5ae6ad905ee4 --- /dev/null +++ b/tools/topology/topology2/include/bench/eqiir_control_bytes_playback.conf @@ -0,0 +1,9 @@ + # Created initially with script "./bench_comp_generate.sh eqiir" + # may need edits to modify controls + Object.Control.bytes."1" { + name '$ANALOG_PLAYBACK_PCM EQIIR bytes' + IncludeByKey.BENCH_EQIIR_PARAMS { + "default" "include/components/eqiir/default.conf" + "highpass_50hz_0db_48khz" "include/components/eqiir/highpass_50hz_0db_48khz.conf" + } + } diff --git a/tools/topology/topology2/include/bench/eqiir_hda_route.conf b/tools/topology/topology2/include/bench/eqiir_hda_route.conf new file mode 100644 index 000000000000..5f066b741969 --- /dev/null +++ b/tools/topology/topology2/include/bench/eqiir_hda_route.conf @@ -0,0 +1,19 @@ + # Created with script "./bench_comp_generate.sh eqiir" + Object.Base.route [ + { + sink 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.playback' + source 'eqiir.1.1' + } + { + sink 'eqiir.1.1' + source 'host-copier.0.playback' + } + { + source 'dai-copier.HDA.$HDA_ANALOG_DAI_NAME.capture' + sink 'eqiir.3.2' + } + { + source 'eqiir.3.2' + sink 'host-copier.0.capture' + } + ] diff --git a/tools/topology/topology2/include/bench/eqiir_s16.conf b/tools/topology/topology2/include/bench/eqiir_s16.conf new file mode 100644 index 000000000000..bcb01383e3d5 --- /dev/null +++ b/tools/topology/topology2/include/bench/eqiir_s16.conf @@ -0,0 +1,13 @@ + # Created with script "./bench_comp_generate.sh eqiir" + Object.Widget.eqiir.1 { + index 1 + <include/bench/one_input_output_format_s16.conf> + <include/bench/eqiir_control_bytes_playback.conf> + } + Object.Widget.eqiir.2 { + index 3 + <include/bench/one_input_output_format_s16.conf> + <include/bench/eqiir_control_bytes_capture.conf> + } + <include/bench/host_io_gateway_pipelines_s16.conf> + <include/bench/eqiir_hda_route.conf> diff --git a/tools/topology/topology2/include/bench/eqiir_s24.conf b/tools/topology/topology2/include/bench/eqiir_s24.conf new file mode 100644 index 000000000000..aa327545beec --- /dev/null +++ b/tools/topology/topology2/include/bench/eqiir_s24.conf @@ -0,0 +1,13 @@ + # Created with script "./bench_comp_generate.sh eqiir" + Object.Widget.eqiir.1 { + index 1 + <include/bench/one_input_output_format_s24.conf> + <include/bench/eqiir_control_bytes_playback.conf> + } + Object.Widget.eqiir.2 { + index 3 + <include/bench/one_input_output_format_s24.conf> + <include/bench/eqiir_control_bytes_capture.conf> + } + <include/bench/host_io_gateway_pipelines_s24.conf> + <include/bench/eqiir_hda_route.conf> diff --git a/tools/topology/topology2/include/bench/eqiir_s32.conf b/tools/topology/topology2/include/bench/eqiir_s32.conf new file mode 100644 index 000000000000..c6bf9b4e0fb7 --- /dev/null +++ b/tools/topology/topology2/include/bench/eqiir_s32.conf @@ -0,0 +1,13 @@ + # Created with script "./bench_comp_generate.sh eqiir" + Object.Widget.eqiir.1 { + index 1 + <include/bench/one_input_output_format_s32.conf> + <include/bench/eqiir_control_bytes_playback.conf> + } + Object.Widget.eqiir.2 { + index 3 + <include/bench/one_input_output_format_s32.conf> + <include/bench/eqiir_control_bytes_capture.conf> + } + <include/bench/host_io_gateway_pipelines_s32.conf> + <include/bench/eqiir_hda_route.conf> diff --git a/tools/topology/topology2/include/bench/host_io_gateway_pipelines_s16.conf b/tools/topology/topology2/include/bench/host_io_gateway_pipelines_s16.conf new file mode 100644 index 000000000000..b6ecea830367 --- /dev/null +++ b/tools/topology/topology2/include/bench/host_io_gateway_pipelines_s16.conf @@ -0,0 +1,126 @@ + Object.Pipeline { + host-gateway-playback [ + { + index 1 + + Object.Widget.host-copier.1 { + stream_name $ANALOG_PLAYBACK_PCM + pcm_id 0 + num_input_audio_formats 3 + num_output_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + { + in_bit_depth 32 + in_valid_bit_depth 24 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + ] + } + } + ] + + io-gateway [ + { + index 2 + direction playback + + Object.Widget.dai-copier.1 { + node_type $HDA_LINK_OUTPUT_CLASS + stream_name $HDA_ANALOG_DAI_NAME + dai_type "HDA" + copier_type "HDA" + num_input_pins 1 + num_input_audio_formats 1 + num_output_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + } + } + ] + + host-gateway-capture [ + { + index 3 + Object.Widget.host-copier.1 { + stream_name $ANALOG_CAPTURE_PCM + pcm_id 0 + num_input_audio_formats 1 + num_output_audio_formats 3 + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + { + out_bit_depth 32 + out_valid_bit_depth 24 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + } + } + ] + + io-gateway-capture [ + { + index 4 + direction capture + + Object.Widget.dai-copier."1" { + dai_type "HDA" + type "dai_out" + copier_type "HDA" + stream_name $HDA_ANALOG_DAI_NAME + node_type $HDA_LINK_INPUT_CLASS + num_output_pins 1 + num_input_audio_formats 1 + num_output_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + ] + } + } + ] + } + diff --git a/tools/topology/topology2/include/bench/host_io_gateway_pipelines_s24.conf b/tools/topology/topology2/include/bench/host_io_gateway_pipelines_s24.conf new file mode 100644 index 000000000000..4cac2acd2b8b --- /dev/null +++ b/tools/topology/topology2/include/bench/host_io_gateway_pipelines_s24.conf @@ -0,0 +1,126 @@ + Object.Pipeline { + host-gateway-playback [ + { + index 1 + + Object.Widget.host-copier.1 { + stream_name $ANALOG_PLAYBACK_PCM + pcm_id 0 + num_input_audio_formats 3 + num_output_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + { + in_bit_depth 32 + in_valid_bit_depth 24 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 24 + } + ] + } + } + ] + + io-gateway [ + { + index 2 + direction playback + + Object.Widget.dai-copier.1 { + node_type $HDA_LINK_OUTPUT_CLASS + stream_name $HDA_ANALOG_DAI_NAME + dai_type "HDA" + copier_type "HDA" + num_input_pins 1 + num_input_audio_formats 1 + num_output_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 24 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + } + } + ] + + host-gateway-capture [ + { + index 3 + Object.Widget.host-copier.1 { + stream_name $ANALOG_CAPTURE_PCM + pcm_id 0 + num_input_audio_formats 1 + num_output_audio_formats 3 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 24 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + { + out_bit_depth 32 + out_valid_bit_depth 24 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + } + } + ] + + io-gateway-capture [ + { + index 4 + direction capture + + Object.Widget.dai-copier."1" { + dai_type "HDA" + type "dai_out" + copier_type "HDA" + stream_name $HDA_ANALOG_DAI_NAME + node_type $HDA_LINK_INPUT_CLASS + num_output_pins 1 + num_input_audio_formats 1 + num_output_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 24 + } + ] + } + } + ] + } + diff --git a/tools/topology/topology2/include/bench/host_io_gateway_pipelines_s32.conf b/tools/topology/topology2/include/bench/host_io_gateway_pipelines_s32.conf new file mode 100644 index 000000000000..c598efcd3e06 --- /dev/null +++ b/tools/topology/topology2/include/bench/host_io_gateway_pipelines_s32.conf @@ -0,0 +1,126 @@ + Object.Pipeline { + host-gateway-playback [ + { + index 1 + + Object.Widget.host-copier.1 { + stream_name $ANALOG_PLAYBACK_PCM + pcm_id 0 + num_input_audio_formats 3 + num_output_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + { + in_bit_depth 32 + in_valid_bit_depth 24 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + } + } + ] + + io-gateway [ + { + index 2 + direction playback + + Object.Widget.dai-copier.1 { + node_type $HDA_LINK_OUTPUT_CLASS + stream_name $HDA_ANALOG_DAI_NAME + dai_type "HDA" + copier_type "HDA" + num_input_pins 1 + num_input_audio_formats 1 + num_output_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + } + } + ] + + host-gateway-capture [ + { + index 3 + Object.Widget.host-copier.1 { + stream_name $ANALOG_CAPTURE_PCM + pcm_id 0 + num_input_audio_formats 1 + num_output_audio_formats 3 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + { + out_bit_depth 32 + out_valid_bit_depth 24 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + } + } + ] + + io-gateway-capture [ + { + index 4 + direction capture + + Object.Widget.dai-copier."1" { + dai_type "HDA" + type "dai_out" + copier_type "HDA" + stream_name $HDA_ANALOG_DAI_NAME + node_type $HDA_LINK_INPUT_CLASS + num_output_pins 1 + num_input_audio_formats 1 + num_output_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + } + } + ] + } + diff --git a/tools/topology/topology2/include/bench/one_input_output_format_s16.conf b/tools/topology/topology2/include/bench/one_input_output_format_s16.conf new file mode 100644 index 000000000000..a309ceed07b4 --- /dev/null +++ b/tools/topology/topology2/include/bench/one_input_output_format_s16.conf @@ -0,0 +1,17 @@ + num_input_audio_formats 1 + num_output_audio_formats 1 + + # 16-bit 48KHz 2ch + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + ] + diff --git a/tools/topology/topology2/include/bench/one_input_output_format_s24.conf b/tools/topology/topology2/include/bench/one_input_output_format_s24.conf new file mode 100644 index 000000000000..081373a4b405 --- /dev/null +++ b/tools/topology/topology2/include/bench/one_input_output_format_s24.conf @@ -0,0 +1,17 @@ + num_input_audio_formats 1 + num_output_audio_formats 1 + + # 24-bit 48KHz 2ch + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 24 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 24 + } + ] + diff --git a/tools/topology/topology2/include/bench/one_input_output_format_s32.conf b/tools/topology/topology2/include/bench/one_input_output_format_s32.conf new file mode 100644 index 000000000000..adc4d2f47d40 --- /dev/null +++ b/tools/topology/topology2/include/bench/one_input_output_format_s32.conf @@ -0,0 +1,17 @@ + num_input_audio_formats 1 + num_output_audio_formats 1 + + # 32-bit 48KHz 2ch + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + diff --git a/tools/topology/topology2/include/common/audio_format.conf b/tools/topology/topology2/include/common/audio_format.conf index 8ee2e6bed86c..d572f3c00085 100644 --- a/tools/topology/topology2/include/common/audio_format.conf +++ b/tools/topology/topology2/include/common/audio_format.conf @@ -1,43 +1,44 @@ -# Class definition for audio format object -# audio_format objects can be instantiated as: -# -# Object.Base.audio_format."0" { -# in_rate 48000 -# in_sample_container_size 16 -# in_valid_bit_depth 16 -# in_interleaving_style "interleaved" -# out_rate 48000 -# out_sample_container_size 16 -# out_valid_bit_depth 16 -# out_interleaving_style "interleaved" - -# } -# +## \struct audio_format +## \brief Class definition for audio format object +## +## audio_format objects can be instantiated as: +## +## Object.Base.audio_format."0" { +## in_rate 48000 +## in_sample_container_size 16 +## in_valid_bit_depth 16 +## in_interleaving_style "interleaved" +## out_rate 48000 +## out_sample_container_size 16 +## out_valid_bit_depth 16 +## out_interleaving_style "interleaved" +## } +## Class.Base."audio_format" { DefineAttribute."instance" { } - # input sampling rate + ## input sampling rate DefineAttribute."in_rate" { # Token set reference name token_ref "cavs_audio_format.word" } - # input bit depth + # #input bit depth DefineAttribute."in_bit_depth" { # Token set reference name token_ref "cavs_audio_format.word" } - # input valid bit depth + ## input valid bit depth DefineAttribute."in_valid_bit_depth" { # Token set reference name token_ref "cavs_audio_format.word" } - # input channel count + ## input channel count DefineAttribute."in_channels" { # Token set reference name token_ref "cavs_audio_format.word" @@ -47,19 +48,19 @@ Class.Base."audio_format" { } } - # input channel map + ## input channel map DefineAttribute."in_ch_map" { # Token set reference name token_ref "cavs_audio_format.word" } - # input channel config + ## input channel config DefineAttribute."in_ch_cfg" { # Token set reference name token_ref "cavs_audio_format.word" } - # input interleaving style + ## input interleaving style DefineAttribute."in_interleaving_style" { type "string" # Token set reference name @@ -76,19 +77,20 @@ Class.Base."audio_format" { } } - # input format config + ## input format config DefineAttribute."in_fmt_cfg" { # Token set reference name token_ref "cavs_audio_format.word" } - # output sampling rate + ## output sampling rate DefineAttribute."out_rate" { # Token set reference name token_ref "cavs_audio_format.word" } - # input sample_type + ## Input sample_type. + ## Valid values for sample type are defined in common_definitions.conf. DefineAttribute."in_sample_type" { type string # Token set reference name @@ -104,19 +106,19 @@ Class.Base."audio_format" { } } - # output bit depth + ## output bit depth DefineAttribute."out_bit_depth" { # Token set reference name token_ref "cavs_audio_format.word" } - # output valid bit depth + ## output valid bit depth DefineAttribute."out_valid_bit_depth" { # Token set reference name token_ref "cavs_audio_format.word" } - # output channel count + ## output channel count DefineAttribute."out_channels" { # Token set reference name token_ref "cavs_audio_format.word" @@ -126,19 +128,19 @@ Class.Base."audio_format" { } } - # output channel map + ## output channel map DefineAttribute."out_ch_map" { # Token set reference name token_ref "cavs_audio_format.word" } - # output channel config + ## output channel config DefineAttribute."out_ch_cfg" { # Token set reference name token_ref "cavs_audio_format.word" } - # output interleaving style + ## output interleaving style DefineAttribute."out_interleaving_style" { type "string" # Token set reference name @@ -155,14 +157,14 @@ Class.Base."audio_format" { } } - # output format config + ## output format config DefineAttribute."out_fmt_cfg" { # Token set reference name token_ref "cavs_audio_format.word" } # - # input buffer size + ## input buffer size # DefineAttribute."ibs" { # Token set reference name and type @@ -170,14 +172,15 @@ Class.Base."audio_format" { } # - # output buffer size + ## output buffer size # DefineAttribute."obs" { # Token set reference name and type token_ref "cavs_audio_format.word" } - #output sample_type + ## Output sample_type. + ## Valid values for sample type are defined in common_definitions.conf. DefineAttribute."out_sample_type" { type string # Token set reference name diff --git a/tools/topology/topology2/include/common/data.conf b/tools/topology/topology2/include/common/data.conf index 84655302224e..02900ee192a4 100644 --- a/tools/topology/topology2/include/common/data.conf +++ b/tools/topology/topology2/include/common/data.conf @@ -1,10 +1,12 @@ -# Class definition for data object -# Data objects can be instantiated as: -# -# Object.Base.data."SOF ABI" { -# bytes "0x3, 0x12,0x1" -# } -# +## \struct data +## \brief Class definition for data object +## +## Data objects can be instantiated as: +## +## Object.Base.data."SOF ABI" { +## bytes "0x3, 0x12,0x1" +## } +## Class.Base."data" { DefineAttribute."instance" {} diff --git a/tools/topology/topology2/include/common/fe_dai.conf b/tools/topology/topology2/include/common/fe_dai.conf index 8310c298c73b..e67d8aa4d22b 100644 --- a/tools/topology/topology2/include/common/fe_dai.conf +++ b/tools/topology/topology2/include/common/fe_dai.conf @@ -1,15 +1,17 @@ -# -# FE DAI Class definition. All attributes defined herein are namespaced -# by alsatplg to "Object.Base.fe_dai.instance.attribute_name". -# -# Usage: FE DAI objects can be instantiated as -# -# Object.Base.fe_dai.1 { -# id 0 -# } -# -# where NAME is the unique instance name for the FE DAI object within the -# same alsaconf node. +## \struct fe_dai +## \brief FE DAI Class definition +## +## All attributes defined herein are namespaced by alsatplg to +## "Object.Base.fe_dai.instance.attribute_name". +## +## Usage: FE DAI objects can be instantiated as +## +## Object.Base.fe_dai.1 { +## id 0 +## } +## +## where NAME is the unique instance name for the FE DAI object within the +## same alsaconf node. Class.Base."fe_dai" { diff --git a/tools/topology/topology2/include/common/input_audio_format.conf b/tools/topology/topology2/include/common/input_audio_format.conf index f5b9956d841b..795f3cdb46b0 100644 --- a/tools/topology/topology2/include/common/input_audio_format.conf +++ b/tools/topology/topology2/include/common/input_audio_format.conf @@ -1,14 +1,16 @@ -# Class definition for input pin audio format object -# audio_format objects can be instantiated as: -# -# Object.Base.input_audio_format."0" { -# in_rate 48000 -# in_sample_container_size 16 -# in_valid_bit_depth 16 -# in_interleaving_style "interleaved" - -# } -# +## \struct input_audio_format +## \brief Volume playback pipeline +## +## Class definition for input pin audio format object +## audio_format objects can be instantiated as: +## +## Object.Base.input_audio_format."0" { +## in_rate 48000 +## in_sample_container_size 16 +## in_valid_bit_depth 16 +## in_interleaving_style "interleaved" +## } +## Class.Base."input_audio_format" { @@ -20,25 +22,25 @@ Class.Base."input_audio_format" { token_ref "cavs_audio_format.word" } - # input sampling rate + ## input sampling rate DefineAttribute."in_rate" { # Token set reference name token_ref "cavs_audio_format.word" } - # input bit depth + ## input bit depth DefineAttribute."in_bit_depth" { # Token set reference name token_ref "cavs_audio_format.word" } - # input valid bit depth + ## input valid bit depth DefineAttribute."in_valid_bit_depth" { # Token set reference name token_ref "cavs_audio_format.word" } - # input channel count + ## input channel count DefineAttribute."in_channels" { # Token set reference name token_ref "cavs_audio_format.word" @@ -48,19 +50,19 @@ Class.Base."input_audio_format" { } } - # input channel map + ## input channel map DefineAttribute."in_ch_map" { # Token set reference name token_ref "cavs_audio_format.word" } - # input channel config + ## input channel config DefineAttribute."in_ch_cfg" { # Token set reference name token_ref "cavs_audio_format.word" } - # input interleaving style + ## input interleaving style DefineAttribute."in_interleaving_style" { type "string" # Token set reference name @@ -77,13 +79,14 @@ Class.Base."input_audio_format" { } } - # input format config + ## input format config DefineAttribute."in_fmt_cfg" { # Token set reference name token_ref "cavs_audio_format.word" } - # input sample_type + ## Input sample_type. + ## Valid values for sample type are defined in common_definitions.conf. DefineAttribute."in_sample_type" { type string # Token set reference name @@ -100,7 +103,7 @@ Class.Base."input_audio_format" { } # - # input buffer size + ## input buffer size # DefineAttribute."ibs" { # Token set reference name and type diff --git a/tools/topology/topology2/include/components/dcblock.conf b/tools/topology/topology2/include/components/dcblock.conf new file mode 100644 index 000000000000..4b0815173db3 --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock.conf @@ -0,0 +1,65 @@ +# +# +# A generic dcblock component. All attributes defined herein are namespaced +# by alsatplg to "Object.Widget.dcblock.attribute_name" +# +# Usage: this component can be used by declaring in the parent object. i.e. +# +# Object.Widget.dcblock."N" { +# index 1 +# } +# } + +# +# Where M is pipeline ID and N is a unique integer in the parent object. + +Class.Widget."dcblock" { + # + # Pipeline ID + # + DefineAttribute."index" { + type "integer" + } + + # + # Unique instance for EQ IIR widget + # + DefineAttribute."instance" { + type "integer" + } + + # Include common widget attributes definition + <include/components/widget-common.conf> + + attributes { + !constructor [ + "index" + "instance" + ] + !mandatory [ + "num_input_pins" + "num_output_pins" + "num_input_audio_formats" + "num_output_audio_formats" + ] + + !immutable [ + "uuid" + "type" + ] + !deprecated [ + "preload_count" + ] + unique "instance" + } + + # + # Default attributes for dcblock + # + # b809efaf-5681-42b1-9ed6-04bb012dd384 + uuid "af:ef:09:b8:81:56:b1:42:9e:d6:04:bb:01:2d:d3:84" + type "effect" + no_pm "true" + num_input_pins 1 + num_output_pins 1 +} diff --git a/tools/topology/topology2/include/components/dcblock/100hz_16khz.conf b/tools/topology/topology2/include/components/dcblock/100hz_16khz.conf new file mode 100644 index 000000000000..9bda1ed41447 --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock/100hz_16khz.conf @@ -0,0 +1,13 @@ +# Exported with script example_dcblock.m 04-Oct-2023 +# cd tools/tune/dcblock; octave example_dcblock.m +Object.Base.data."dcblock_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x41,0xe3,0x6f,0x3d,0x41,0xe3,0x6f,0x3d, + 0x41,0xe3,0x6f,0x3d,0x41,0xe3,0x6f,0x3d, + 0x41,0xe3,0x6f,0x3d,0x41,0xe3,0x6f,0x3d, + 0x41,0xe3,0x6f,0x3d,0x41,0xe3,0x6f,0x3d" +} diff --git a/tools/topology/topology2/include/components/dcblock/100hz_48khz.conf b/tools/topology/topology2/include/components/dcblock/100hz_48khz.conf new file mode 100644 index 000000000000..82c09e90b9c3 --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock/100hz_48khz.conf @@ -0,0 +1,13 @@ +# Exported with script example_dcblock.m 04-Oct-2023 +# cd tools/tune/dcblock; octave example_dcblock.m +Object.Base.data."dcblock_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x92,0x20,0x28,0x3f,0x92,0x20,0x28,0x3f, + 0x92,0x20,0x28,0x3f,0x92,0x20,0x28,0x3f, + 0x92,0x20,0x28,0x3f,0x92,0x20,0x28,0x3f, + 0x92,0x20,0x28,0x3f,0x92,0x20,0x28,0x3f" +} diff --git a/tools/topology/topology2/include/components/dcblock/200hz_16khz.conf b/tools/topology/topology2/include/components/dcblock/200hz_16khz.conf new file mode 100644 index 000000000000..cc869bb12fd5 --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock/200hz_16khz.conf @@ -0,0 +1,13 @@ +# Exported with script example_dcblock.m 04-Oct-2023 +# cd tools/tune/dcblock; octave example_dcblock.m +Object.Base.data."dcblock_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x73,0x09,0xc6,0x3a,0x73,0x09,0xc6,0x3a, + 0x73,0x09,0xc6,0x3a,0x73,0x09,0xc6,0x3a, + 0x73,0x09,0xc6,0x3a,0x73,0x09,0xc6,0x3a, + 0x73,0x09,0xc6,0x3a,0x73,0x09,0xc6,0x3a" +} diff --git a/tools/topology/topology2/include/components/dcblock/200hz_48khz.conf b/tools/topology/topology2/include/components/dcblock/200hz_48khz.conf new file mode 100644 index 000000000000..c4c9046f82ea --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock/200hz_48khz.conf @@ -0,0 +1,13 @@ +# Exported with script example_dcblock.m 04-Oct-2023 +# cd tools/tune/dcblock; octave example_dcblock.m +Object.Base.data."dcblock_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xd4,0x6d,0x4d,0x3e,0xd4,0x6d,0x4d,0x3e, + 0xd4,0x6d,0x4d,0x3e,0xd4,0x6d,0x4d,0x3e, + 0xd4,0x6d,0x4d,0x3e,0xd4,0x6d,0x4d,0x3e, + 0xd4,0x6d,0x4d,0x3e,0xd4,0x6d,0x4d,0x3e" +} diff --git a/tools/topology/topology2/include/components/dcblock/20hz_16khz.conf b/tools/topology/topology2/include/components/dcblock/20hz_16khz.conf new file mode 100644 index 000000000000..165ae2968d23 --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock/20hz_16khz.conf @@ -0,0 +1,13 @@ +# Exported with script example_dcblock.m 04-Oct-2023 +# cd tools/tune/dcblock; octave example_dcblock.m +Object.Base.data."dcblock_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x7c,0xd0,0x7e,0x3f,0x7c,0xd0,0x7e,0x3f, + 0x7c,0xd0,0x7e,0x3f,0x7c,0xd0,0x7e,0x3f, + 0x7c,0xd0,0x7e,0x3f,0x7c,0xd0,0x7e,0x3f, + 0x7c,0xd0,0x7e,0x3f,0x7c,0xd0,0x7e,0x3f" +} diff --git a/tools/topology/topology2/include/components/dcblock/20hz_48khz.conf b/tools/topology/topology2/include/components/dcblock/20hz_48khz.conf new file mode 100644 index 000000000000..d7b8198218ad --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock/20hz_48khz.conf @@ -0,0 +1,13 @@ +# Exported with script example_dcblock.m 04-Oct-2023 +# cd tools/tune/dcblock; octave example_dcblock.m +Object.Base.data."dcblock_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf6,0x0c,0xd5,0x3f,0xf6,0x0c,0xd5,0x3f, + 0xf6,0x0c,0xd5,0x3f,0xf6,0x0c,0xd5,0x3f, + 0xf6,0x0c,0xd5,0x3f,0xf6,0x0c,0xd5,0x3f, + 0xf6,0x0c,0xd5,0x3f,0xf6,0x0c,0xd5,0x3f" +} diff --git a/tools/topology/topology2/include/components/dcblock/30hz_16khz.conf b/tools/topology/topology2/include/components/dcblock/30hz_16khz.conf new file mode 100644 index 000000000000..bc5013ac9acd --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock/30hz_16khz.conf @@ -0,0 +1,13 @@ +# Exported with script example_dcblock.m 04-Oct-2023 +# cd tools/tune/dcblock; octave example_dcblock.m +Object.Base.data."dcblock_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x63,0xd7,0x3d,0x3f,0x63,0xd7,0x3d,0x3f, + 0x63,0xd7,0x3d,0x3f,0x63,0xd7,0x3d,0x3f, + 0x63,0xd7,0x3d,0x3f,0x63,0xd7,0x3d,0x3f, + 0x63,0xd7,0x3d,0x3f,0x63,0xd7,0x3d,0x3f" +} diff --git a/tools/topology/topology2/include/components/dcblock/30hz_48khz.conf b/tools/topology/topology2/include/components/dcblock/30hz_48khz.conf new file mode 100644 index 000000000000..c4a21f83a10c --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock/30hz_48khz.conf @@ -0,0 +1,13 @@ +# Exported with script example_dcblock.m 04-Oct-2023 +# cd tools/tune/dcblock; octave example_dcblock.m +Object.Base.data."dcblock_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xa6,0x88,0xbf,0x3f,0xa6,0x88,0xbf,0x3f, + 0xa6,0x88,0xbf,0x3f,0xa6,0x88,0xbf,0x3f, + 0xa6,0x88,0xbf,0x3f,0xa6,0x88,0xbf,0x3f, + 0xa6,0x88,0xbf,0x3f,0xa6,0x88,0xbf,0x3f" +} diff --git a/tools/topology/topology2/include/components/dcblock/40hz_16khz.conf b/tools/topology/topology2/include/components/dcblock/40hz_16khz.conf new file mode 100644 index 000000000000..5552350b9da3 --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock/40hz_16khz.conf @@ -0,0 +1,13 @@ +# Exported with script example_dcblock.m 04-Oct-2023 +# cd tools/tune/dcblock; octave example_dcblock.m +Object.Base.data."dcblock_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x3c,0x9d,0xfc,0x3e,0x3c,0x9d,0xfc,0x3e, + 0x3c,0x9d,0xfc,0x3e,0x3c,0x9d,0xfc,0x3e, + 0x3c,0x9d,0xfc,0x3e,0x3c,0x9d,0xfc,0x3e, + 0x3c,0x9d,0xfc,0x3e,0x3c,0x9d,0xfc,0x3e" +} diff --git a/tools/topology/topology2/include/components/dcblock/40hz_48khz.conf b/tools/topology/topology2/include/components/dcblock/40hz_48khz.conf new file mode 100644 index 000000000000..77b497ba73a1 --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock/40hz_48khz.conf @@ -0,0 +1,13 @@ +# Exported with script example_dcblock.m 04-Oct-2023 +# cd tools/tune/dcblock; octave example_dcblock.m +Object.Base.data."dcblock_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x22,0xfd,0xa9,0x3f,0x22,0xfd,0xa9,0x3f, + 0x22,0xfd,0xa9,0x3f,0x22,0xfd,0xa9,0x3f, + 0x22,0xfd,0xa9,0x3f,0x22,0xfd,0xa9,0x3f, + 0x22,0xfd,0xa9,0x3f,0x22,0xfd,0xa9,0x3f" +} diff --git a/tools/topology/topology2/include/components/dcblock/50hz_16khz.conf b/tools/topology/topology2/include/components/dcblock/50hz_16khz.conf new file mode 100644 index 000000000000..81e6cf5db9ea --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock/50hz_16khz.conf @@ -0,0 +1,13 @@ +# Exported with script example_dcblock.m 04-Oct-2023 +# cd tools/tune/dcblock; octave example_dcblock.m +Object.Base.data."dcblock_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe6,0x21,0xbb,0x3e,0xe6,0x21,0xbb,0x3e, + 0xe6,0x21,0xbb,0x3e,0xe6,0x21,0xbb,0x3e, + 0xe6,0x21,0xbb,0x3e,0xe6,0x21,0xbb,0x3e, + 0xe6,0x21,0xbb,0x3e,0xe6,0x21,0xbb,0x3e" +} diff --git a/tools/topology/topology2/include/components/dcblock/50hz_48khz.conf b/tools/topology/topology2/include/components/dcblock/50hz_48khz.conf new file mode 100644 index 000000000000..ced86dd64d0e --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock/50hz_48khz.conf @@ -0,0 +1,13 @@ +# Exported with script example_dcblock.m 04-Oct-2023 +# cd tools/tune/dcblock; octave example_dcblock.m +Object.Base.data."dcblock_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x6a,0x6a,0x94,0x3f,0x6a,0x6a,0x94,0x3f, + 0x6a,0x6a,0x94,0x3f,0x6a,0x6a,0x94,0x3f, + 0x6a,0x6a,0x94,0x3f,0x6a,0x6a,0x94,0x3f, + 0x6a,0x6a,0x94,0x3f,0x6a,0x6a,0x94,0x3f" +} diff --git a/tools/topology/topology2/include/components/dcblock/80hz_16khz.conf b/tools/topology/topology2/include/components/dcblock/80hz_16khz.conf new file mode 100644 index 000000000000..0bb539df5288 --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock/80hz_16khz.conf @@ -0,0 +1,13 @@ +# Exported with script example_dcblock.m 04-Oct-2023 +# cd tools/tune/dcblock; octave example_dcblock.m +Object.Base.data."dcblock_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x96,0x27,0xf5,0x3d,0x96,0x27,0xf5,0x3d, + 0x96,0x27,0xf5,0x3d,0x96,0x27,0xf5,0x3d, + 0x96,0x27,0xf5,0x3d,0x96,0x27,0xf5,0x3d, + 0x96,0x27,0xf5,0x3d,0x96,0x27,0xf5,0x3d" +} diff --git a/tools/topology/topology2/include/components/dcblock/80hz_48khz.conf b/tools/topology/topology2/include/components/dcblock/80hz_48khz.conf new file mode 100644 index 000000000000..7be93fe17c22 --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock/80hz_48khz.conf @@ -0,0 +1,13 @@ +# Exported with script example_dcblock.m 04-Oct-2023 +# cd tools/tune/dcblock; octave example_dcblock.m +Object.Base.data."dcblock_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfa,0x86,0x53,0x3f,0xfa,0x86,0x53,0x3f, + 0xfa,0x86,0x53,0x3f,0xfa,0x86,0x53,0x3f, + 0xfa,0x86,0x53,0x3f,0xfa,0x86,0x53,0x3f, + 0xfa,0x86,0x53,0x3f,0xfa,0x86,0x53,0x3f" +} diff --git a/tools/topology/topology2/include/components/dcblock/default.conf b/tools/topology/topology2/include/components/dcblock/default.conf new file mode 100644 index 000000000000..cbadfc6c6cbd --- /dev/null +++ b/tools/topology/topology2/include/components/dcblock/default.conf @@ -0,0 +1,13 @@ +# Exported with script example_dcblock.m 04-Oct-2023 +# cd tools/tune/dcblock; octave example_dcblock.m +Object.Base.data."dcblock_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xec,0x51,0xb8,0x3e,0xec,0x51,0xb8,0x3e, + 0xec,0x51,0xb8,0x3e,0xec,0x51,0xb8,0x3e, + 0xec,0x51,0xb8,0x3e,0xec,0x51,0xb8,0x3e, + 0xec,0x51,0xb8,0x3e,0xec,0x51,0xb8,0x3e" +} diff --git a/tools/topology/topology2/include/components/gain.conf b/tools/topology/topology2/include/components/gain.conf index 395edb64ba94..3343365880fd 100644 --- a/tools/topology/topology2/include/components/gain.conf +++ b/tools/topology/topology2/include/components/gain.conf @@ -1,29 +1,29 @@ -# -# Common pipeline gain (volume) -# -# A generic gain (volume) widget. All attributes defined herein are namespaced -# by alsatplg to "Object.Widget.gain.N.attribute_name" -# -# Usage: this component can be used by declaring int a parent object. i.e. -# -# Object.Widget.gain."N" { -# index 1 -# format s24le -# no_pm "true" -# } -# -# Where N is the unique instance number for gain widget in the same alsaconf node. +## \struct gain +## \brief Common pipeline gain (volume) +## +## A generic gain (volume) widget. All attributes defined herein are namespaced +## by alsatplg to "Object.Widget.gain.N.attribute_name" +## +## Usage: this component can be used by declaring int a parent object. i.e. +## +## Object.Widget.gain."N" { +## index 1 +## format s24le +## no_pm "true" +## } +## +## Where N is the unique instance number for gain widget in the same alsaconf node. <include/controls/mixer.conf> Class.Widget."gain" { # - # Pipeline ID for the gain widget object + ## Pipeline ID for the gain widget object # DefineAttribute."index" {} # - # gain object instance + ## gain object instance # DefineAttribute."instance" {} @@ -35,9 +35,9 @@ Class.Widget."gain" { # # - # Gain curve type. The values provided will be translated to integer values - # as specified in the tuple_values array. - # For example: "linear" is translated to 0, "log" to 1 etc. + ## Gain curve type. The values provided will be translated to integer values + ## as specified in the tuple_values array. + ## For example: "linear" is translated to 0, "log" to 1 etc. # DefineAttribute."curve_type" { type "string" @@ -45,18 +45,26 @@ Class.Widget."gain" { token_ref "gain.word" constraints { !valid_values [ - "no_fade" - "fade" + "windows_no_fade" + "windows_fade" + "linear" + "log" + "linear_zc" + "log_zc" ] !tuple_values [ 0 1 + 2 + 3 + 4 + 5 ] } } # - # Gain curve in milliseconds + ## Gain curve in milliseconds # DefineAttribute."curve_duration" { # Token set reference name @@ -71,8 +79,8 @@ Class.Widget."gain" { # Attribute categories attributes { # - # The PGA widget name would be constructed using the index and instance attributes. - # For ex: "gain.1.1" or "gain.10.2" etc. + ## The PGA widget name would be constructed using the index and instance attributes. + ## For ex: "gain.1.1" or "gain.10.2" etc. # !constructor [ "index" @@ -114,9 +122,9 @@ Class.Widget."gain" { # gain widget mixer controls # Object.Control { - # gain mixer control + ## gain mixer control mixer."1" { - #Channel register and shift for Front Left/Right + ## Channel register and shift for Front Left/Right Object.Base.channel.1 { name "fl" shift 0 @@ -128,7 +136,7 @@ Class.Widget."gain" { Object.Base.ops.1 { name "ctl" info "volsw" - #256 binds the mixer control to volume get/put handlers + ## get = 256 binds the mixer control to volume get/put handlers get 256 put 256 } @@ -151,7 +159,7 @@ Class.Widget."gain" { uuid "A8:A9:BC:61:D0:18:18:4A:8E:7B:26:39:21:98:04:B7" no_pm "true" cpc 10183 - curve_type "fade" + curve_type "linear" curve_duration 200000 # 20 ms init_value 0x7fffffff num_input_pins 1 diff --git a/tools/topology/topology2/include/components/google-rtc-aec.conf b/tools/topology/topology2/include/components/google-rtc-aec.conf index e2df7a9dbeac..2d6ed613b469 100644 --- a/tools/topology/topology2/include/components/google-rtc-aec.conf +++ b/tools/topology/topology2/include/components/google-rtc-aec.conf @@ -87,35 +87,47 @@ Class.Widget."google-rtc-aec" { unique "instance" } - num_audio_formats 2 - num_input_audio_formats 2 - num_output_audio_formats 1 + num_input_audio_formats 3 + num_output_audio_formats 2 # pin0 is the data captured by DMIC and pin1 is the ref data from playback stream - Object.Base.input_audio_format { - 1 { + Object.Base.input_audio_format [ + # 2ch 16-bit on Pin 0 + { input_pin_index 0 in_bit_depth 16 in_valid_bit_depth 16 - out_bit_depth 16 - out_valid_bit_depth 16 } - 2 { + # 4ch 16-bit on Pin 0 + { + input_pin_index 0 + in_bit_depth 16 + in_valid_bit_depth 16 + in_channels 4 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + # 2ch 16-bit on Pin 1 + { input_pin_index 1 in_bit_depth 16 in_valid_bit_depth 16 + } + ] + + Object.Base.output_audio_format [ + { out_bit_depth 16 out_valid_bit_depth 16 } - } - - Object.Base.output_audio_format { - 1 { - in_bit_depth 16 - in_valid_bit_depth 16 + # 4ch 16-bit + { out_bit_depth 16 out_valid_bit_depth 16 + out_channels 4 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 } - } + ] # Default attribute values for google-rtc-aec widget # UUID: B780A0A6-269F-466F-B477-23DFA05AF758 diff --git a/tools/topology/topology2/include/components/google-rtc-aec/rtc-aec-blob.conf b/tools/topology/topology2/include/components/google-rtc-aec/rtc-aec-blob.conf deleted file mode 100644 index f31ed7a0a747..000000000000 --- a/tools/topology/topology2/include/components/google-rtc-aec/rtc-aec-blob.conf +++ /dev/null @@ -1,19 +0,0 @@ -# aec blob data - -Object.Base.data."google-rtc-aec_blob" { - bytes " - 0x53, 0x4f, 0x46, 0x34, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x80, 0xbb, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x10, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, - - 0x80, 0xbb, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x10, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, - - 0x00, 0x00, 0x00, 0x00" -} diff --git a/tools/topology/topology2/include/components/multiband_drc.conf b/tools/topology/topology2/include/components/multiband_drc.conf new file mode 100644 index 000000000000..d363e930e77b --- /dev/null +++ b/tools/topology/topology2/include/components/multiband_drc.conf @@ -0,0 +1,85 @@ +# +# +# A generic MULTIBAND_DRC component. All attributes defined herein are namespaced +# by alsatplg to "Object.Widget.multiband_drc.attribute_name" +# +# Usage: this component can be used by declaring in the parent object. i.e. +# +# Object.Widget.multiband_drc."N" { +# index 1 +# } +# } + +# +# Where M is pipeline ID and N is a unique integer in the parent object. + +Class.Widget."multiband_drc" { + # + # Pipeline ID + # + DefineAttribute."index" { + type "integer" + } + + # + # Unique instance for MULTIBAND_DRC widget + # + DefineAttribute."instance" { + type "integer" + } + + # Include common widget attributes definition + <include/components/widget-common.conf> + + attributes { + !constructor [ + "index" + "instance" + ] + !mandatory [ + "num_input_pins" + "num_output_pins" + "num_input_audio_formats" + "num_output_audio_formats" + ] + + !immutable [ + "uuid" + "type" + ] + !deprecated [ + "preload_count" + ] + unique "instance" + } + + # + # multiband_drc widget switch control + # + Object.Control { + mixer."1" { + Object.Base.channel.1 { + name "fc" + shift 0 + } + Object.Base.ops.1 { + name "ctl" + info "volsw" + #259 binds the mixer control to switch get/put handlers + get 259 + put 259 + } + max 1 + } + } + + # + # Default attributes for multiband_drc + # + + uuid "56:22:9f:0d:4f:8e:b3:47:84:48:23:9a:33:4f:11:91" + type "effect" + no_pm "true" + num_input_pins 1 + num_output_pins 1 +} diff --git a/tools/topology/topology2/include/components/multiband_drc/default.conf b/tools/topology/topology2/include/components/multiband_drc/default.conf new file mode 100644 index 000000000000..e42467528301 --- /dev/null +++ b/tools/topology/topology2/include/components/multiband_drc/default.conf @@ -0,0 +1,82 @@ +# Exported with script example_multiband_drc.m 01-Sep-2023 +Object.Base.data."multiband_drc_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x4c,0x02,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x4c,0x02,0x00,0x00,0x03,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x7b,0x8e,0x88,0xfe, + 0x36,0x79,0x57,0x17,0x5f,0x19,0x6f,0x06, + 0xe8,0x79,0x67,0xd4,0x00,0x00,0x00,0x40, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x5f,0x6d,0x19,0xe7,0x39,0xc4,0xd4,0x50, + 0x0c,0x9b,0x09,0x24,0xad,0x76,0x82,0x9f, + 0x00,0x00,0x00,0x40,0xff,0xff,0xff,0xff, + 0x43,0x72,0x00,0x00,0xa1,0xe6,0x90,0xf9, + 0x18,0x86,0x98,0x2b,0xe3,0x32,0xef,0x00, + 0x4b,0xf7,0x20,0xf1,0x18,0x69,0xc6,0x28, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0xf4,0x64,0xf6,0xdb,0x53,0x89,0x7d,0x60, + 0x5c,0x14,0xf2,0x0a,0x84,0x0d,0x78,0xdc, + 0xda,0xef,0x21,0x1c,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x6f,0x82,0x53,0xc2, + 0x3e,0x77,0xa1,0x7d,0x95,0xc1,0x02,0x00, + 0x2a,0x83,0x05,0x00,0x95,0xc1,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x6f,0x82,0x53,0xc2,0x3e,0x77,0xa1,0x7d, + 0x34,0x7d,0xd3,0x3e,0x99,0x05,0x59,0x82, + 0x34,0x7d,0xd3,0x3e,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x2d,0x3a,0xcd,0xd3, + 0xc0,0xf5,0x82,0x68,0x05,0xf4,0xeb,0x00, + 0x0a,0xe8,0xd7,0x01,0x05,0xf4,0xeb,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x2d,0x3a,0xcd,0xd3,0xc0,0xf5,0x82,0x68, + 0xe5,0x6e,0x2d,0x35,0x36,0x22,0xa5,0x95, + 0xe5,0x6e,0x2d,0x35,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x2d,0x3a,0xcd,0xd3, + 0xc0,0xf5,0x82,0x68,0x05,0xf4,0xeb,0x00, + 0x0a,0xe8,0xd7,0x01,0x05,0xf4,0xeb,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x2d,0x3a,0xcd,0xd3,0xc0,0xf5,0x82,0x68, + 0xe5,0x6e,0x2d,0x35,0x36,0x22,0xa5,0x95, + 0xe5,0x6e,0x2d,0x35,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe8,0x00,0x00,0x00,0x1e, + 0x00,0x00,0x00,0x0c,0xd3,0x4d,0x62,0x00, + 0xb1,0xc2,0x09,0x04,0x55,0x55,0x55,0x05, + 0x50,0xfa,0x1e,0x00,0x55,0x60,0x94,0x00, + 0x7e,0x98,0x6a,0xff,0x83,0xc9,0xfe,0x01, + 0x64,0x47,0x47,0x22,0x17,0x56,0x74,0x01, + 0x1c,0xc7,0x71,0x00,0x77,0x77,0x77,0xff, + 0xd8,0x77,0x1f,0x00,0x05,0x00,0x00,0x00, + 0x00,0x00,0x36,0x00,0xdf,0x97,0x03,0x00, + 0xe7,0x3e,0x1e,0x00,0xdf,0x97,0x07,0x00, + 0x5b,0x91,0x00,0x00,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe8,0x00,0x00,0x00,0x1e, + 0x00,0x00,0x00,0x0c,0xd3,0x4d,0x62,0x00, + 0xb1,0xc2,0x09,0x04,0x55,0x55,0x55,0x05, + 0x50,0xfa,0x1e,0x00,0x55,0x60,0x94,0x00, + 0x7e,0x98,0x6a,0xff,0x83,0xc9,0xfe,0x01, + 0x64,0x47,0x47,0x22,0x17,0x56,0x74,0x01, + 0x1c,0xc7,0x71,0x00,0x77,0x77,0x77,0xff, + 0xd8,0x77,0x1f,0x00,0x05,0x00,0x00,0x00, + 0x00,0x00,0x36,0x00,0xdf,0x97,0x03,0x00, + 0xe7,0x3e,0x1e,0x00,0xdf,0x97,0x07,0x00, + 0x5b,0x91,0x00,0x00,0x03,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe8,0x00,0x00,0x00,0x1e, + 0x00,0x00,0x00,0x0c,0xd3,0x4d,0x62,0x00, + 0xb1,0xc2,0x09,0x04,0x55,0x55,0x55,0x05, + 0x50,0xfa,0x1e,0x00,0x55,0x60,0x94,0x00, + 0x7e,0x98,0x6a,0xff,0x83,0xc9,0xfe,0x01, + 0x64,0x47,0x47,0x22,0x17,0x56,0x74,0x01, + 0x1c,0xc7,0x71,0x00,0x77,0x77,0x77,0xff, + 0xd8,0x77,0x1f,0x00,0x05,0x00,0x00,0x00, + 0x00,0x00,0x36,0x00,0xdf,0x97,0x03,0x00, + 0xe7,0x3e,0x1e,0x00,0xdf,0x97,0x07,0x00, + 0x5b,0x91,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/multiband_drc/passthrough.conf b/tools/topology/topology2/include/components/multiband_drc/passthrough.conf new file mode 100644 index 000000000000..09cb3c4f4ac8 --- /dev/null +++ b/tools/topology/topology2/include/components/multiband_drc/passthrough.conf @@ -0,0 +1,71 @@ +# Exported with script example_multiband_drc.m 01-Sep-2023 +Object.Base.data."multiband_drc_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0xf4,0x01,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf4,0x01,0x00,0x00,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x7b,0x8e,0x88,0xfe, + 0x36,0x79,0x57,0x17,0x5f,0x19,0x6f,0x06, + 0xe8,0x79,0x67,0xd4,0x00,0x00,0x00,0x40, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x5f,0x6d,0x19,0xe7,0x39,0xc4,0xd4,0x50, + 0x0c,0x9b,0x09,0x24,0xad,0x76,0x82,0x9f, + 0x00,0x00,0x00,0x40,0xff,0xff,0xff,0xff, + 0x43,0x72,0x00,0x00,0xa1,0xe6,0x90,0xf9, + 0x18,0x86,0x98,0x2b,0xe3,0x32,0xef,0x00, + 0x4b,0xf7,0x20,0xf1,0x18,0x69,0xc6,0x28, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0xf4,0x64,0xf6,0xdb,0x53,0x89,0x7d,0x60, + 0x5c,0x14,0xf2,0x0a,0x84,0x0d,0x78,0xdc, + 0xda,0xef,0x21,0x1c,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x6f,0x82,0x53,0xc2, + 0x3e,0x77,0xa1,0x7d,0x95,0xc1,0x02,0x00, + 0x2a,0x83,0x05,0x00,0x95,0xc1,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x6f,0x82,0x53,0xc2,0x3e,0x77,0xa1,0x7d, + 0x34,0x7d,0xd3,0x3e,0x99,0x05,0x59,0x82, + 0x34,0x7d,0xd3,0x3e,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe8,0x00,0x00,0x00,0x1e, + 0x00,0x00,0x00,0x0c,0xd3,0x4d,0x62,0x00, + 0xb1,0xc2,0x09,0x04,0x55,0x55,0x55,0x05, + 0x50,0xfa,0x1e,0x00,0x55,0x60,0x94,0x00, + 0x7e,0x98,0x6a,0xff,0x83,0xc9,0xfe,0x01, + 0x64,0x47,0x47,0x22,0x17,0x56,0x74,0x01, + 0x1c,0xc7,0x71,0x00,0x77,0x77,0x77,0xff, + 0xd8,0x77,0x1f,0x00,0x05,0x00,0x00,0x00, + 0x00,0x00,0x36,0x00,0xdf,0x97,0x03,0x00, + 0xe7,0x3e,0x1e,0x00,0xdf,0x97,0x07,0x00, + 0x5b,0x91,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe8,0x00,0x00,0x00,0x1e, + 0x00,0x00,0x00,0x0c,0xd3,0x4d,0x62,0x00, + 0xb1,0xc2,0x09,0x04,0x55,0x55,0x55,0x05, + 0x50,0xfa,0x1e,0x00,0x55,0x60,0x94,0x00, + 0x7e,0x98,0x6a,0xff,0x83,0xc9,0xfe,0x01, + 0x64,0x47,0x47,0x22,0x17,0x56,0x74,0x01, + 0x1c,0xc7,0x71,0x00,0x77,0x77,0x77,0xff, + 0xd8,0x77,0x1f,0x00,0x05,0x00,0x00,0x00, + 0x00,0x00,0x36,0x00,0xdf,0x97,0x03,0x00, + 0xe7,0x3e,0x1e,0x00,0xdf,0x97,0x07,0x00, + 0x5b,0x91,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/src_format_s32_convert_from_48k.conf b/tools/topology/topology2/include/components/src_format_s32_convert_from_48k.conf index 2185581258dc..c1e450c776d1 100644 --- a/tools/topology/topology2/include/components/src_format_s32_convert_from_48k.conf +++ b/tools/topology/topology2/include/components/src_format_s32_convert_from_48k.conf @@ -1,95 +1,34 @@ #src format array num_output_audio_formats 14 - Object.Base.output_audio_format [ - # 8khz output - { - out_rate 8000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 11.025 khz output - { - out_rate 11025 - out_bit_depth 32 - out_valid_bit_depth 32 - obs "$[($out_channels * (($[($out_rate + 999)] / 1000) + 4)) * ($out_bit_depth / 8)]" - } - # 12khz output - { - out_rate 12000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 16khz output - { - out_rate 16000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 22.05khz output - { - out_rate 22050 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 24khz output - { - out_rate 24000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 32khz output - { - out_rate 32000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 44.1khz output - { - out_rate 44100 - out_bit_depth 32 - out_valid_bit_depth 32 - obs "$[($out_channels * (($[($out_rate + 999)] / 1000) + 4)) * ($out_bit_depth / 8)]" - } - # 48khz output - { - out_rate 48000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 64khz output - { - out_rate 64000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 88.2khz output - { - out_rate 88200 - out_bit_depth 32 - out_valid_bit_depth 32 + CombineArrays.Object.Base.output_audio_format [ + { + out_rate [ + 8000 + 12000 + 16000 + 22050 + 24000 + 32000 + 48000 + 64000 + 96000 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 32 ] + } + { + out_rate [ + 11025 + 44100 + 88200 + 176400 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 32 ] obs "$[($out_channels * (($[($out_rate + 999)] / 1000) + 4)) * ($out_bit_depth / 8)]" } - # 96khz output - { - out_rate 96000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 176.4khz output - { - out_rate 176400 - out_bit_depth 32 - out_valid_bit_depth 32 - obs "$[($out_channels * (($[($out_rate + 999)] / 1000) + 4)) * ($out_bit_depth / 8)]" - } - # 192khz output - { - out_rate 192000 - out_bit_depth 32 - out_valid_bit_depth 32 - } ] num_input_audio_formats 1 diff --git a/tools/topology/topology2/include/components/src_format_s32_convert_to_48k.conf b/tools/topology/topology2/include/components/src_format_s32_convert_to_48k.conf index f20af68b3c3a..9b47223ec555 100644 --- a/tools/topology/topology2/include/components/src_format_s32_convert_to_48k.conf +++ b/tools/topology/topology2/include/components/src_format_s32_convert_to_48k.conf @@ -1,90 +1,26 @@ #src format array num_input_audio_formats 14 - Object.Base.input_audio_format [ - # 8khz input - { - in_rate 8000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 11.025 khz input - { - in_rate 11025 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 12khz input - { - in_rate 12000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 16khz input - { - in_rate 16000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 22.05khz input - { - in_rate 22050 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 24khz input - { - in_rate 24000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 32khz input - { - in_rate 32000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 44.1khz input - { - in_rate 44100 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 48khz input - { - in_rate 48000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 64khz input - { - in_rate 64000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 88.2khz input - { - in_rate 88200 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 96khz input - { - in_rate 96000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 176.4khz input - { - in_rate 176400 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 192khz input - { - in_rate 192000 - in_bit_depth 32 - in_valid_bit_depth 32 + CombineArrays.Object.Base.input_audio_format [ + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 32 ] } ] diff --git a/tools/topology/topology2/include/components/src_format_s32_passthrough.conf b/tools/topology/topology2/include/components/src_format_s32_passthrough.conf index adc8a391ef6b..97d87c9b24c4 100644 --- a/tools/topology/topology2/include/components/src_format_s32_passthrough.conf +++ b/tools/topology/topology2/include/components/src_format_s32_passthrough.conf @@ -1,178 +1,50 @@ #src format array num_input_audio_formats 14 - Object.Base.input_audio_format [ - # 8khz input - { - in_rate 8000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 11.025 khz input - { - in_rate 11025 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 12khz input - { - in_rate 12000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 16khz input - { - in_rate 16000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 22.05khz input - { - in_rate 22050 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 24khz input - { - in_rate 24000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 32khz input - { - in_rate 32000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 44.1khz input - { - in_rate 44100 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 48khz input - { - in_rate 48000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 64khz input - { - in_rate 64000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 88.2khz input - { - in_rate 88200 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 96khz input - { - in_rate 96000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 176.4khz input - { - in_rate 176400 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 192khz input - { - in_rate 192000 - in_bit_depth 32 - in_valid_bit_depth 32 + CombineArrays.Object.Base.input_audio_format [ + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 32 ] } ] num_output_audio_formats 14 - Object.Base.output_audio_format [ - # 8khz output - { - out_rate 8000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 11.025 khz output - { - out_rate 11025 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 12khz output - { - out_rate 12000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 16khz output - { - out_rate 16000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 22.05khz output - { - out_rate 22050 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 24khz output - { - out_rate 24000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 32khz output - { - out_rate 32000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 44.1khz output - { - out_rate 44100 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 48khz output - { - out_rate 48000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 64khz output - { - out_rate 64000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 88.2khz output - { - out_rate 88200 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 96khz output - { - out_rate 96000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 176.4khz output - { - out_rate 176400 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 192khz output - { - out_rate 192000 - out_bit_depth 32 - out_valid_bit_depth 32 + CombineArrays.Object.Base.output_audio_format [ + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 32 ] } ] diff --git a/tools/topology/topology2/include/components/src_format_s32_to_sxx_convert.conf b/tools/topology/topology2/include/components/src_format_s32_to_sxx_convert.conf index a76ba74ab2de..3f57456d836f 100644 --- a/tools/topology/topology2/include/components/src_format_s32_to_sxx_convert.conf +++ b/tools/topology/topology2/include/components/src_format_s32_to_sxx_convert.conf @@ -1,346 +1,73 @@ #src format array num_input_audio_formats 14 - Object.Base.input_audio_format [ - # 8khz input - { - in_rate 8000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 11.025 khz input - { - in_rate 11025 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 12khz input - { - in_rate 12000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 16khz input - { - in_rate 16000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 22.05khz input - { - in_rate 22050 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 24khz input - { - in_rate 24000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 32khz input - { - in_rate 32000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 44.1khz input - { - in_rate 44100 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 48khz input - { - in_rate 48000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 64khz input - { - in_rate 64000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 88.2khz input - { - in_rate 88200 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 96khz input - { - in_rate 96000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 176.4khz input - { - in_rate 176400 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 192khz input - { - in_rate 192000 - in_bit_depth 32 - in_valid_bit_depth 32 + CombineArrays.Object.Base.input_audio_format [ + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 32 ] } ] num_output_audio_formats 42 - Object.Base.output_audio_format [ - # 8khz output - { - out_rate 8000 - out_bit_depth 16 - out_valid_bit_depth 16 - } - # 11.025 khz output - { - out_rate 11025 - out_bit_depth 16 - out_valid_bit_depth 16 - } - # 12khz output - { - out_rate 12000 - out_bit_depth 16 - out_valid_bit_depth 16 - } - # 16khz output - { - out_rate 16000 - out_bit_depth 16 - out_valid_bit_depth 16 - } - # 22.05khz output - { - out_rate 22050 - out_bit_depth 16 - out_valid_bit_depth 16 - } - # 24khz output - { - out_rate 24000 - out_bit_depth 16 - out_valid_bit_depth 16 - } - # 32khz output - { - out_rate 32000 - out_bit_depth 16 - out_valid_bit_depth 16 - } - # 44.1khz output - { - out_rate 44100 - out_bit_depth 16 - out_valid_bit_depth 16 - } - # 48khz output - { - out_rate 48000 - out_bit_depth 16 - out_valid_bit_depth 16 - } - # 64khz output - { - out_rate 64000 - out_bit_depth 16 - out_valid_bit_depth 16 - } - # 88.2khz output - { - out_rate 88200 - out_bit_depth 16 - out_valid_bit_depth 16 - } - # 96khz output - { - out_rate 96000 - out_bit_depth 16 - out_valid_bit_depth 16 - } - # 176.4khz output - { - out_rate 176400 - out_bit_depth 16 - out_valid_bit_depth 16 - } - # 192khz output - { - out_rate 192000 - out_bit_depth 16 - out_valid_bit_depth 16 - } - # 8khz output - { - out_rate 8000 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 11.025 khz output - { - out_rate 11025 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 12khz output - { - out_rate 12000 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 16khz output - { - out_rate 16000 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 22.05khz output - { - out_rate 22050 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 24khz output - { - out_rate 24000 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 32khz output - { - out_rate 32000 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 44.1khz output - { - out_rate 44100 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 48khz output - { - out_rate 48000 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 64khz output - { - out_rate 64000 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 88.2khz output - { - out_rate 88200 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 96khz output - { - out_rate 96000 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 176.4khz output - { - out_rate 176400 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 192khz output - { - out_rate 192000 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 8khz output - { - out_rate 8000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 11.025 khz output - { - out_rate 11025 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 12khz output - { - out_rate 12000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 16khz output - { - out_rate 16000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 22.05khz output - { - out_rate 22050 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 24khz output - { - out_rate 24000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 32khz output - { - out_rate 32000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 44.1khz output - { - out_rate 44100 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 48khz output - { - out_rate 48000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 64khz output - { - out_rate 64000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 88.2khz output - { - out_rate 88200 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 96khz output - { - out_rate 96000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 176.4khz output - { - out_rate 176400 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 192khz output - { - out_rate 192000 - out_bit_depth 32 - out_valid_bit_depth 32 + CombineArrays.Object.Base.output_audio_format [ + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 176400 + 192000 + ] + out_bit_depth [ 16 ] + out_valid_bit_depth [ 16 ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ + 24 + 32 + ] } ] diff --git a/tools/topology/topology2/include/components/src_format_sxx_to_s32_convert.conf b/tools/topology/topology2/include/components/src_format_sxx_to_s32_convert.conf index 0518fb2d2a6f..941bf69f30bf 100644 --- a/tools/topology/topology2/include/components/src_format_sxx_to_s32_convert.conf +++ b/tools/topology/topology2/include/components/src_format_sxx_to_s32_convert.conf @@ -1,346 +1,73 @@ #src format array num_input_audio_formats 42 - Object.Base.input_audio_format [ - # 8khz input - { - in_rate 8000 - in_bit_depth 16 - in_valid_bit_depth 16 - } - # 11.025 khz input - { - in_rate 11025 - in_bit_depth 16 - in_valid_bit_depth 16 - } - # 12khz input - { - in_rate 12000 - in_bit_depth 16 - in_valid_bit_depth 16 - } - # 16khz input - { - in_rate 16000 - in_bit_depth 16 - in_valid_bit_depth 16 - } - # 22.05khz input - { - in_rate 22050 - in_bit_depth 16 - in_valid_bit_depth 16 - } - # 24khz input - { - in_rate 24000 - in_bit_depth 16 - in_valid_bit_depth 16 - } - # 32khz input - { - in_rate 32000 - in_bit_depth 16 - in_valid_bit_depth 16 - } - # 44.1khz input - { - in_rate 44100 - in_bit_depth 16 - in_valid_bit_depth 16 - } - # 48khz input - { - in_rate 48000 - in_bit_depth 16 - in_valid_bit_depth 16 - } - # 64khz input - { - in_rate 64000 - in_bit_depth 16 - in_valid_bit_depth 16 - } - # 88.2khz input - { - in_rate 88200 - in_bit_depth 16 - in_valid_bit_depth 16 - } - # 96khz input - { - in_rate 96000 - in_bit_depth 16 - in_valid_bit_depth 16 - } - # 176.4khz input - { - in_rate 176400 - in_bit_depth 16 - in_valid_bit_depth 16 - } - # 192khz input - { - in_rate 192000 - in_bit_depth 16 - in_valid_bit_depth 16 - } - # 8khz input - { - in_rate 8000 - in_bit_depth 32 - in_valid_bit_depth 24 - } - # 11.025 khz input - { - in_rate 11025 - in_bit_depth 32 - in_valid_bit_depth 24 - } - # 12khz input - { - in_rate 12000 - in_bit_depth 32 - in_valid_bit_depth 24 - } - # 16khz input - { - in_rate 16000 - in_bit_depth 32 - in_valid_bit_depth 24 - } - # 22.05khz input - { - in_rate 22050 - in_bit_depth 32 - in_valid_bit_depth 24 - } - # 24khz input - { - in_rate 24000 - in_bit_depth 32 - in_valid_bit_depth 24 - } - # 32khz input - { - in_rate 32000 - in_bit_depth 32 - in_valid_bit_depth 24 - } - # 44.1khz input - { - in_rate 44100 - in_bit_depth 32 - in_valid_bit_depth 24 - } - # 48khz input - { - in_rate 48000 - in_bit_depth 32 - in_valid_bit_depth 24 - } - # 64khz input - { - in_rate 64000 - in_bit_depth 32 - in_valid_bit_depth 24 - } - # 88.2khz input - { - in_rate 88200 - in_bit_depth 32 - in_valid_bit_depth 24 - } - # 96khz input - { - in_rate 96000 - in_bit_depth 32 - in_valid_bit_depth 24 - } - # 176.4khz input - { - in_rate 176400 - in_bit_depth 32 - in_valid_bit_depth 24 - } - # 192khz input - { - in_rate 192000 - in_bit_depth 32 - in_valid_bit_depth 24 - } - # 8khz input - { - in_rate 8000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 11.025 khz input - { - in_rate 11025 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 12khz input - { - in_rate 12000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 16khz input - { - in_rate 16000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 22.05khz input - { - in_rate 22050 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 24khz input - { - in_rate 24000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 32khz input - { - in_rate 32000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 44.1khz input - { - in_rate 44100 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 48khz input - { - in_rate 48000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 64khz input - { - in_rate 64000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 88.2khz input - { - in_rate 88200 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 96khz input - { - in_rate 96000 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 176.4khz input - { - in_rate 176400 - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 192khz input - { - in_rate 192000 - in_bit_depth 32 - in_valid_bit_depth 32 + CombineArrays.Object.Base.input_audio_format [ + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 176400 + 192000 + ] + in_bit_depth [ 16 ] + in_valid_bit_depth [ 16 ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ + 24 + 32 + ] } ] num_output_audio_formats 14 - Object.Base.output_audio_format [ - # 8khz output - { - out_rate 8000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 11.025 khz output - { - out_rate 11025 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 12khz output - { - out_rate 12000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 16khz output - { - out_rate 16000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 22.05khz output - { - out_rate 22050 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 24khz output - { - out_rate 24000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 32khz output - { - out_rate 32000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 44.1khz output - { - out_rate 44100 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 48khz output - { - out_rate 48000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 64khz output - { - out_rate 64000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 88.2khz output - { - out_rate 88200 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 96khz output - { - out_rate 96000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 176.4khz output - { - out_rate 176400 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 192khz output - { - out_rate 192000 - out_bit_depth 32 - out_valid_bit_depth 32 + CombineArrays.Object.Base.output_audio_format [ + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 32 ] } ] diff --git a/tools/topology/topology2/include/components/tdfb.conf b/tools/topology/topology2/include/components/tdfb.conf new file mode 100644 index 000000000000..aa8a39a82b3c --- /dev/null +++ b/tools/topology/topology2/include/components/tdfb.conf @@ -0,0 +1,175 @@ +# +# +# A generic Time Domain Fixed Beamformer (TDFB) component. All attributes +# defined herein are namespaced by alsatplg to +# "Object.Widget.tdfb.attribute_name" +# +# Usage: this component can be used by declaring in the parent object. i.e. +# +# Object.Widget.tdfb."N" { +# index 1 +# } +# } + +# +# Where M is pipeline ID and N is a unique integer in the parent object. + +<include/controls/mixer.conf> +<include/controls/enum.conf> + +Class.Widget."tdfb" { + # + # Pipeline ID + # + DefineAttribute."index" { + type "integer" + } + + # + # Unique instance for TDFB widget + # + DefineAttribute."instance" { + type "integer" + } + + # Include common widget attributes definition + <include/components/widget-common.conf> + + attributes { + !constructor [ + "index" + "instance" + ] + !mandatory [ + "num_input_pins" + "num_output_pins" + "num_input_audio_formats" + "num_output_audio_formats" + ] + + !immutable [ + "uuid" + "type" + ] + !deprecated [ + "preload_count" + ] + unique "instance" + } + + # + # tdfb widget switch control + # + Object.Control { + # Switch controls + mixer."1" { + Object.Base.channel.1 { + name "fc" + shift 0 + } + Object.Base.ops.1 { + name "ctl" + info "volsw" + #259 binds the mixer control to switch get/put handlers + get 259 + put 259 + } + max 1 + } + mixer."2" { + Object.Base.channel.1 { + name "fc" + shift 0 + } + Object.Base.ops.1 { + name "ctl" + info "volsw" + #259 binds the mixer control to switch get/put handlers + get 259 + put 259 + } + max 1 + } + + # Enum controls + enum."1" { + Object.Base { + channel.1 { + name "fc" + reg 3 + shift 0 + } + text.0 { + name "tdfb_enum_plus_minus_90_text" + !values [ + "-90" + "-75" + "-60" + "-45" + "-30" + "-15" + "0" + "15" + "30" + "45" + "60" + "75" + "90" + ] + } + ops.1 { + name "ctl" + info "enum" + #257 binds the mixer control to enum get/put handlers + get 257 + put 257 + } + } + } + enum."2" { + Object.Base { + channel.1 { + name "fc" + reg 3 + shift 0 + } + text.0 { + name "mytext" + !values [ + "-90" + "-75" + "-60" + "-45" + "-30" + "-15" + "0" + "15" + "30" + "45" + "60" + "75" + "90" + ] + } + ops.1 { + name "ctl" + info "enum" + #257 binds the mixer control to enum get/put handlers + get 257 + put 257 + } + } + } + } + + # + # Default attributes for tdfb + # + + # dd511749-d9fa-455c-b3a7-13585693f1af + uuid "49:17:51:dd:fa:d9:5c:45:b3:a7:13:58:56:93:f1:af" + type "effect" + no_pm "true" + num_input_pins 1 + num_output_pins 1 +} diff --git a/tools/topology/topology2/include/components/tdfb/line2_50mm_azm90_90_13_16khz.conf b/tools/topology/topology2/include/components/tdfb/line2_50mm_azm90_90_13_16khz.conf new file mode 100644 index 000000000000..45b7f92588a8 --- /dev/null +++ b/tools/topology/topology2/include/components/tdfb/line2_50mm_azm90_90_13_16khz.conf @@ -0,0 +1,362 @@ +# Created with script example_line_array.m 23-Oct-2023 +# cd tools/tune/tdfb; octave --no-window-system example_line_array.m +Object.Base.data."tdfb_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x04,0x0b,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x0b,0x00,0x00,0x02,0x00,0x02,0x00, + 0x01,0x00,0x02,0x00,0x0d,0x00,0x01,0x00, + 0x00,0x00,0x0f,0x00,0xa6,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x0a,0x00,0x42,0x00,0x59,0x00, + 0x12,0x01,0xef,0x00,0x6b,0x02,0xa9,0x01, + 0x1c,0x04,0x02,0x03,0xa7,0x08,0x38,0x04, + 0x30,0x0b,0x40,0x03,0x58,0x0b,0x31,0xfb, + 0x52,0x0f,0x92,0xed,0xe6,0x34,0x51,0x69, + 0x07,0xe4,0x0b,0x0c,0x08,0xf2,0xc7,0x02, + 0x01,0xf2,0x51,0xfb,0xe9,0xf3,0x75,0xfa, + 0xc7,0xf6,0x63,0xfd,0xdb,0xfa,0xee,0xfd, + 0xce,0xfc,0xb5,0xfe,0x61,0xfe,0x68,0xff, + 0x70,0xff,0xdb,0xff,0xf1,0xff,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf4,0xff,0xcd,0xff,0x8e,0xff,0x2d,0xff, + 0xbd,0xfe,0x24,0xfe,0x99,0xfd,0xd3,0xfc, + 0x61,0xfc,0x29,0xfb,0x9b,0xf8,0xda,0xf7, + 0x9b,0xf7,0xe7,0xf6,0x19,0xf9,0xf1,0xfb, + 0x5e,0xfc,0xad,0xfd,0xbb,0xfe,0xcb,0x7f, + 0x41,0x01,0x43,0x02,0x7e,0x03,0xd9,0x03, + 0x71,0x06,0x5c,0x08,0x95,0x07,0x38,0x07, + 0x69,0x06,0x17,0x04,0xf9,0x02,0x83,0x02, + 0xd1,0x01,0x53,0x01,0xd3,0x00,0x79,0x00, + 0x33,0x00,0x0d,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x0a,0x00,0x3e,0x00,0x5c,0x00, + 0x02,0x01,0xfa,0x00,0x47,0x02,0xc4,0x01, + 0xdc,0x03,0xf2,0x02,0x2a,0x08,0xb0,0x04, + 0x73,0x0a,0x16,0x04,0x24,0x0a,0xde,0xfc, + 0xec,0x0c,0xf9,0xf1,0x4e,0x27,0x6c,0x72, + 0x53,0xe7,0x10,0x0a,0xa3,0xf3,0xec,0x01, + 0xa0,0xf3,0x9e,0xfa,0xb2,0xf4,0x13,0xfa, + 0x4b,0xf7,0x29,0xfd,0x2b,0xfb,0xce,0xfd, + 0xfc,0xfc,0xa6,0xfe,0x78,0xfe,0x63,0xff, + 0x78,0xff,0xda,0xff,0xf2,0xff,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf4,0xff,0xcf,0xff,0x90,0xff,0x32,0xff, + 0xc3,0xfe,0x2f,0xfe,0xa2,0xfd,0xe7,0xfc, + 0x68,0xfc,0x63,0xfb,0xcb,0xf8,0xea,0xf7, + 0xb9,0xf7,0xff,0xf6,0x81,0xf9,0xf9,0xfb, + 0x6b,0xfc,0xb2,0xfd,0xbf,0xfe,0xcb,0x7f, + 0x3d,0x01,0x3e,0x02,0x71,0x03,0xd1,0x03, + 0x11,0x06,0x46,0x08,0x79,0x07,0x2a,0x07, + 0x40,0x06,0xe7,0x03,0xf3,0x02,0x74,0x02, + 0xca,0x01,0x4b,0x01,0xcf,0x00,0x76,0x00, + 0x32,0x00,0x0c,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x0b,0x00,0x30,0x00,0x6a,0x00, + 0xc7,0x00,0x29,0x01,0xbe,0x01,0x32,0x02, + 0xf1,0x02,0x48,0x03,0xd9,0x05,0xbd,0x06, + 0x6e,0x07,0x7c,0x07,0x52,0x05,0x34,0x03, + 0x00,0x04,0xf1,0x00,0xb2,0x03,0xb1,0x7f, + 0x4e,0xfc,0xfa,0xfe,0xcb,0xfb,0x9b,0xfc, + 0x2a,0xfa,0xc5,0xf7,0xcb,0xf7,0x58,0xf8, + 0x57,0xf9,0x26,0xfc,0x68,0xfc,0x3b,0xfd, + 0xb2,0xfd,0x5f,0xfe,0xcf,0xfe,0x47,0xff, + 0x95,0xff,0xd4,0xff,0xf5,0xff,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf5,0xff,0xd3,0xff,0x97,0xff,0x43,0xff, + 0xd6,0xfe,0x54,0xfe,0xc0,0xfd,0x27,0xfd, + 0x84,0xfc,0x01,0xfc,0x77,0xf9,0x28,0xf8, + 0x0e,0xf8,0x77,0xf7,0xae,0xfa,0x06,0xfc, + 0xa1,0xfc,0xc1,0xfd,0xd2,0xfe,0xcb,0x7f, + 0x2a,0x01,0x31,0x02,0x3e,0x03,0xc4,0x03, + 0xf8,0x04,0xd8,0x07,0x2d,0x07,0xf3,0x06, + 0xaa,0x05,0x61,0x03,0xdc,0x02,0x41,0x02, + 0xb3,0x01,0x30,0x01,0xc3,0x00,0x6c,0x00, + 0x2f,0x00,0x0b,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x0d,0x00,0x1a,0x00,0x7b,0x00, + 0x6a,0x00,0x67,0x01,0xe3,0x00,0xca,0x02, + 0x5f,0x01,0x71,0x04,0xb4,0x01,0xf4,0x08, + 0x70,0x03,0x9b,0x0b,0x08,0xff,0xb7,0x0a, + 0x50,0xf9,0x18,0x11,0x01,0xe7,0xb4,0x67, + 0x58,0x37,0x6b,0xe8,0xaf,0x0a,0x2c,0xf3, + 0x73,0x03,0xfd,0xf4,0x8f,0xfc,0xd5,0xf5, + 0x90,0xfc,0xba,0xfa,0x6e,0xfe,0x6d,0xfc, + 0xd5,0xfe,0xfd,0xfd,0x5b,0xff,0x22,0xff, + 0xc5,0xff,0xcc,0xff,0xfa,0xff,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf6,0xff,0xda,0xff,0xa6,0xff,0x61,0xff, + 0xfb,0xfe,0x96,0xfe,0x01,0xfe,0x95,0xfd, + 0xd9,0xfc,0xc7,0xfc,0xd9,0xfa,0xcf,0xf8, + 0x7e,0xf8,0xe5,0xf8,0x30,0xfc,0x45,0xfc, + 0x12,0xfd,0xe1,0xfd,0xf7,0xfe,0xcb,0x7f, + 0x05,0x01,0x11,0x02,0xd0,0x02,0x89,0x03, + 0x90,0x03,0x87,0x06,0xc8,0x06,0x5f,0x06, + 0x77,0x04,0xb9,0x02,0x96,0x02,0xea,0x01, + 0x83,0x01,0x02,0x01,0xab,0x00,0x5b,0x00, + 0x29,0x00,0x09,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x05,0x00,0x26,0x00,0x31,0x00, + 0xa3,0x00,0x8a,0x00,0x7d,0x01,0xf8,0x00, + 0x97,0x02,0x2c,0x01,0x24,0x04,0xc0,0x03, + 0xd3,0x07,0xe4,0x00,0xf9,0x05,0xf7,0xfd, + 0xad,0x08,0xf6,0xf6,0xb1,0x18,0xf1,0x79, + 0x96,0xed,0x60,0x07,0x7e,0xf7,0x9d,0x01, + 0xbc,0xf9,0xcf,0xfd,0xea,0xf6,0x58,0xfc, + 0xb7,0xfb,0x70,0xfe,0xe8,0xfc,0xba,0xfe, + 0x12,0xfe,0x3c,0xff,0x0c,0xff,0xaa,0xff, + 0xad,0xff,0xeb,0xff,0xf7,0xff,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xf9,0xff, + 0xe4,0xff,0xbe,0xff,0x8a,0xff,0x3e,0xff, + 0xed,0xfe,0x7f,0xfe,0x25,0xfe,0xaf,0xfd, + 0x79,0xfd,0xdb,0xfc,0x4f,0xfa,0x40,0xf9, + 0xae,0xfb,0x41,0xfd,0x2c,0xfd,0xc3,0xfd, + 0x3d,0xfe,0x26,0xff,0xcb,0x7f,0xd7,0x00, + 0xb8,0x01,0x27,0x02,0xae,0x02,0x91,0x02, + 0xf8,0x03,0x19,0x06,0x0b,0x05,0xba,0x02, + 0x23,0x02,0xe7,0x01,0x78,0x01,0x23,0x01, + 0xc3,0x00,0x7f,0x00,0x43,0x00,0x1e,0x00, + 0x07,0x00,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x07,0x00,0x01,0x00,0x46,0x00, + 0x00,0x00,0xd5,0x00,0xfd,0xff,0xb5,0x01, + 0xc9,0xff,0xda,0x02,0x39,0xff,0x7d,0x04, + 0xf2,0x00,0xda,0x06,0x8c,0xfb,0x4e,0x09, + 0xb1,0xf6,0xa6,0x10,0x6b,0xe5,0x9e,0x61, + 0x55,0x3f,0x91,0xe7,0xf2,0x0c,0xf4,0xf4, + 0x8b,0x05,0x22,0xf9,0x4a,0x01,0x4f,0xf8, + 0x52,0x01,0x67,0xfc,0x74,0x00,0xbd,0xfd, + 0x17,0x00,0xc2,0xfe,0x01,0x00,0x7f,0xff, + 0xff,0xff,0xe2,0xff,0x00,0x00,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff, + 0xf0,0xff,0xde,0xff,0xbe,0xff,0x9f,0xff, + 0x5e,0xff,0x3b,0xff,0xe8,0xfe,0xe2,0xfe, + 0x68,0xfe,0xc2,0xfe,0xd6,0xfc,0x87,0xfb, + 0x8f,0xfe,0x32,0xfe,0xa8,0xfe,0xae,0xfe, + 0x11,0xff,0x5f,0xff,0xcb,0x7f,0x9f,0x00, + 0xe9,0x00,0x45,0x01,0x46,0x01,0xaf,0x01, + 0x53,0x01,0x0a,0x04,0xcd,0x02,0x13,0x01, + 0x59,0x01,0xeb,0x00,0xde,0x00,0x95,0x00, + 0x73,0x00,0x3f,0x00,0x26,0x00,0x0f,0x00, + 0x04,0x00,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xcb,0x7f,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xcb,0x7f,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xfc,0xff,0xf0,0xff,0xde,0xff, + 0xbe,0xff,0x9f,0xff,0x5e,0xff,0x3b,0xff, + 0xe8,0xfe,0xe2,0xfe,0x68,0xfe,0xc2,0xfe, + 0xd6,0xfc,0x87,0xfb,0x8f,0xfe,0x32,0xfe, + 0xa8,0xfe,0xae,0xfe,0x11,0xff,0x5f,0xff, + 0xcb,0x7f,0x9f,0x00,0xe9,0x00,0x45,0x01, + 0x46,0x01,0xaf,0x01,0x53,0x01,0x0a,0x04, + 0xcd,0x02,0x13,0x01,0x59,0x01,0xeb,0x00, + 0xde,0x00,0x95,0x00,0x73,0x00,0x3f,0x00, + 0x26,0x00,0x0f,0x00,0x04,0x00,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00, + 0x01,0x00,0x46,0x00,0x00,0x00,0xd5,0x00, + 0xfd,0xff,0xb5,0x01,0xc9,0xff,0xda,0x02, + 0x39,0xff,0x7d,0x04,0xf2,0x00,0xda,0x06, + 0x8c,0xfb,0x4e,0x09,0xb1,0xf6,0xa6,0x10, + 0x6b,0xe5,0x9e,0x61,0x55,0x3f,0x91,0xe7, + 0xf2,0x0c,0xf4,0xf4,0x8b,0x05,0x22,0xf9, + 0x4a,0x01,0x4f,0xf8,0x52,0x01,0x67,0xfc, + 0x74,0x00,0xbd,0xfd,0x17,0x00,0xc2,0xfe, + 0x01,0x00,0x7f,0xff,0xff,0xff,0xe2,0xff, + 0x00,0x00,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xf9,0xff,0xe4,0xff,0xbe,0xff, + 0x8a,0xff,0x3e,0xff,0xed,0xfe,0x7f,0xfe, + 0x25,0xfe,0xaf,0xfd,0x79,0xfd,0xdb,0xfc, + 0x4f,0xfa,0x40,0xf9,0xae,0xfb,0x41,0xfd, + 0x2c,0xfd,0xc3,0xfd,0x3d,0xfe,0x26,0xff, + 0xcb,0x7f,0xd7,0x00,0xb8,0x01,0x27,0x02, + 0xae,0x02,0x91,0x02,0xf8,0x03,0x19,0x06, + 0x0b,0x05,0xba,0x02,0x23,0x02,0xe7,0x01, + 0x78,0x01,0x23,0x01,0xc3,0x00,0x7f,0x00, + 0x43,0x00,0x1e,0x00,0x07,0x00,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00, + 0x26,0x00,0x31,0x00,0xa3,0x00,0x8a,0x00, + 0x7d,0x01,0xf8,0x00,0x97,0x02,0x2c,0x01, + 0x24,0x04,0xc0,0x03,0xd3,0x07,0xe4,0x00, + 0xf9,0x05,0xf7,0xfd,0xad,0x08,0xf6,0xf6, + 0xb1,0x18,0xf1,0x79,0x96,0xed,0x60,0x07, + 0x7e,0xf7,0x9d,0x01,0xbc,0xf9,0xcf,0xfd, + 0xea,0xf6,0x58,0xfc,0xb7,0xfb,0x70,0xfe, + 0xe8,0xfc,0xba,0xfe,0x12,0xfe,0x3c,0xff, + 0x0c,0xff,0xaa,0xff,0xad,0xff,0xeb,0xff, + 0xf7,0xff,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf6,0xff,0xda,0xff, + 0xa6,0xff,0x61,0xff,0xfb,0xfe,0x96,0xfe, + 0x01,0xfe,0x95,0xfd,0xd9,0xfc,0xc7,0xfc, + 0xd9,0xfa,0xcf,0xf8,0x7e,0xf8,0xe5,0xf8, + 0x30,0xfc,0x45,0xfc,0x12,0xfd,0xe1,0xfd, + 0xf7,0xfe,0xcb,0x7f,0x05,0x01,0x11,0x02, + 0xd0,0x02,0x89,0x03,0x90,0x03,0x87,0x06, + 0xc8,0x06,0x5f,0x06,0x77,0x04,0xb9,0x02, + 0x96,0x02,0xea,0x01,0x83,0x01,0x02,0x01, + 0xab,0x00,0x5b,0x00,0x29,0x00,0x09,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00, + 0x1a,0x00,0x7b,0x00,0x6a,0x00,0x67,0x01, + 0xe3,0x00,0xca,0x02,0x5f,0x01,0x71,0x04, + 0xb4,0x01,0xf4,0x08,0x70,0x03,0x9b,0x0b, + 0x08,0xff,0xb7,0x0a,0x50,0xf9,0x18,0x11, + 0x01,0xe7,0xb4,0x67,0x58,0x37,0x6b,0xe8, + 0xaf,0x0a,0x2c,0xf3,0x73,0x03,0xfd,0xf4, + 0x8f,0xfc,0xd5,0xf5,0x90,0xfc,0xba,0xfa, + 0x6e,0xfe,0x6d,0xfc,0xd5,0xfe,0xfd,0xfd, + 0x5b,0xff,0x22,0xff,0xc5,0xff,0xcc,0xff, + 0xfa,0xff,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf5,0xff,0xd3,0xff, + 0x97,0xff,0x43,0xff,0xd6,0xfe,0x54,0xfe, + 0xc0,0xfd,0x27,0xfd,0x84,0xfc,0x01,0xfc, + 0x77,0xf9,0x28,0xf8,0x0e,0xf8,0x77,0xf7, + 0xae,0xfa,0x06,0xfc,0xa1,0xfc,0xc1,0xfd, + 0xd2,0xfe,0xcb,0x7f,0x2a,0x01,0x31,0x02, + 0x3e,0x03,0xc4,0x03,0xf8,0x04,0xd8,0x07, + 0x2d,0x07,0xf3,0x06,0xaa,0x05,0x61,0x03, + 0xdc,0x02,0x41,0x02,0xb3,0x01,0x30,0x01, + 0xc3,0x00,0x6c,0x00,0x2f,0x00,0x0b,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x00, + 0x30,0x00,0x6a,0x00,0xc7,0x00,0x29,0x01, + 0xbe,0x01,0x32,0x02,0xf1,0x02,0x48,0x03, + 0xd9,0x05,0xbd,0x06,0x6e,0x07,0x7c,0x07, + 0x52,0x05,0x34,0x03,0x00,0x04,0xf1,0x00, + 0xb2,0x03,0xb1,0x7f,0x4e,0xfc,0xfa,0xfe, + 0xcb,0xfb,0x9b,0xfc,0x2a,0xfa,0xc5,0xf7, + 0xcb,0xf7,0x58,0xf8,0x57,0xf9,0x26,0xfc, + 0x68,0xfc,0x3b,0xfd,0xb2,0xfd,0x5f,0xfe, + 0xcf,0xfe,0x47,0xff,0x95,0xff,0xd4,0xff, + 0xf5,0xff,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf4,0xff,0xcf,0xff, + 0x90,0xff,0x32,0xff,0xc3,0xfe,0x2f,0xfe, + 0xa2,0xfd,0xe7,0xfc,0x68,0xfc,0x63,0xfb, + 0xcb,0xf8,0xea,0xf7,0xb9,0xf7,0xff,0xf6, + 0x81,0xf9,0xf9,0xfb,0x6b,0xfc,0xb2,0xfd, + 0xbf,0xfe,0xcb,0x7f,0x3d,0x01,0x3e,0x02, + 0x71,0x03,0xd1,0x03,0x11,0x06,0x46,0x08, + 0x79,0x07,0x2a,0x07,0x40,0x06,0xe7,0x03, + 0xf3,0x02,0x74,0x02,0xca,0x01,0x4b,0x01, + 0xcf,0x00,0x76,0x00,0x32,0x00,0x0c,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00, + 0x3e,0x00,0x5c,0x00,0x02,0x01,0xfa,0x00, + 0x47,0x02,0xc4,0x01,0xdc,0x03,0xf2,0x02, + 0x2a,0x08,0xb0,0x04,0x73,0x0a,0x16,0x04, + 0x24,0x0a,0xde,0xfc,0xec,0x0c,0xf9,0xf1, + 0x4e,0x27,0x6c,0x72,0x53,0xe7,0x10,0x0a, + 0xa3,0xf3,0xec,0x01,0xa0,0xf3,0x9e,0xfa, + 0xb2,0xf4,0x13,0xfa,0x4b,0xf7,0x29,0xfd, + 0x2b,0xfb,0xce,0xfd,0xfc,0xfc,0xa6,0xfe, + 0x78,0xfe,0x63,0xff,0x78,0xff,0xda,0xff, + 0xf2,0xff,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf4,0xff,0xcd,0xff, + 0x8e,0xff,0x2d,0xff,0xbd,0xfe,0x24,0xfe, + 0x99,0xfd,0xd3,0xfc,0x61,0xfc,0x29,0xfb, + 0x9b,0xf8,0xda,0xf7,0x9b,0xf7,0xe7,0xf6, + 0x19,0xf9,0xf1,0xfb,0x5e,0xfc,0xad,0xfd, + 0xbb,0xfe,0xcb,0x7f,0x41,0x01,0x43,0x02, + 0x7e,0x03,0xd9,0x03,0x71,0x06,0x5c,0x08, + 0x95,0x07,0x38,0x07,0x69,0x06,0x17,0x04, + 0xf9,0x02,0x83,0x02,0xd1,0x01,0x53,0x01, + 0xd3,0x00,0x79,0x00,0x33,0x00,0x0d,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00, + 0x42,0x00,0x59,0x00,0x12,0x01,0xef,0x00, + 0x6b,0x02,0xa9,0x01,0x1c,0x04,0x02,0x03, + 0xa7,0x08,0x38,0x04,0x30,0x0b,0x40,0x03, + 0x58,0x0b,0x31,0xfb,0x52,0x0f,0x92,0xed, + 0xe6,0x34,0x51,0x69,0x07,0xe4,0x0b,0x0c, + 0x08,0xf2,0xc7,0x02,0x01,0xf2,0x51,0xfb, + 0xe9,0xf3,0x75,0xfa,0xc7,0xf6,0x63,0xfd, + 0xdb,0xfa,0xee,0xfd,0xce,0xfc,0xb5,0xfe, + 0x61,0xfe,0x68,0xff,0x70,0xff,0xdb,0xff, + 0xf1,0xff,0x00,0x00,0x04,0x00,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00, + 0x01,0x00,0x02,0x00,0xa6,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0xb5,0xff,0x00,0x00, + 0x02,0x00,0x00,0x00,0xc4,0xff,0x00,0x00, + 0x04,0x00,0x00,0x00,0xd3,0xff,0x00,0x00, + 0x06,0x00,0x00,0x00,0xe2,0xff,0x00,0x00, + 0x08,0x00,0x00,0x00,0xf1,0xff,0x00,0x00, + 0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x0c,0x00,0x00,0x00,0x0f,0x00,0x00,0x00, + 0x0e,0x00,0x00,0x00,0x1e,0x00,0x00,0x00, + 0x10,0x00,0x00,0x00,0x2d,0x00,0x00,0x00, + 0x12,0x00,0x00,0x00,0x3c,0x00,0x00,0x00, + 0x14,0x00,0x00,0x00,0x4b,0x00,0x00,0x00, + 0x16,0x00,0x00,0x00,0x5a,0x00,0x00,0x00, + 0x18,0x00,0x00,0x00,0x00,0x00,0x66,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x9a,0xff, + 0x00,0x00,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/tdfb/line2_50mm_azm90_90_13_48khz.conf b/tools/topology/topology2/include/components/tdfb/line2_50mm_azm90_90_13_48khz.conf new file mode 100644 index 000000000000..1d0afd1c83d7 --- /dev/null +++ b/tools/topology/topology2/include/components/tdfb/line2_50mm_azm90_90_13_48khz.conf @@ -0,0 +1,518 @@ +# Created with script example_line_array.m 23-Oct-2023 +# cd tools/tune/tdfb; octave --no-window-system example_line_array.m +Object.Base.data."tdfb_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0xe4,0x0f,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe4,0x0f,0x00,0x00,0x02,0x00,0x02,0x00, + 0x01,0x00,0x02,0x00,0x0d,0x00,0x01,0x00, + 0x00,0x00,0x0f,0x00,0xa6,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x19,0x00,0x29,0x00,0x41,0x00,0x58,0x00, + 0x79,0x00,0x95,0x00,0xbd,0x00,0xdb,0x00, + 0x08,0x01,0x24,0x01,0x56,0x01,0x68,0x01, + 0xaa,0x01,0x58,0x01,0xf9,0x00,0x10,0x01, + 0x0a,0x01,0x06,0x01,0x04,0x01,0xef,0x00, + 0xed,0x00,0xc8,0x00,0xc8,0x00,0x91,0x00, + 0x9b,0x00,0x48,0x00,0x74,0x00,0xc5,0xff, + 0xeb,0x7f,0x3c,0x00,0x8b,0xff,0xb7,0xff, + 0x62,0xff,0x6b,0xff,0x32,0xff,0x30,0xff, + 0x09,0xff,0x05,0xff,0xee,0xfe,0xe9,0xfe, + 0xe3,0xfe,0xdb,0xfe,0xf1,0xfe,0x88,0xfe, + 0x28,0xfe,0x6d,0xfe,0x7c,0xfe,0xb1,0xfe, + 0xcc,0xfe,0xfc,0xfe,0x1b,0xff,0x46,0xff, + 0x64,0xff,0x89,0xff,0xa4,0xff,0xc1,0xff, + 0xd5,0xff,0xec,0xff,0xf9,0xff,0xfe,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfe,0xff,0xf9,0xff, + 0xec,0xff,0xd5,0xff,0xc1,0xff,0xa4,0xff, + 0x89,0xff,0x65,0xff,0x45,0xff,0x1c,0xff, + 0xfb,0xfe,0xcd,0xfe,0xaf,0xfe,0x7e,0xfe, + 0x6a,0xfe,0x2b,0xfe,0x84,0xfe,0xf6,0xfe, + 0xd6,0xfe,0xe9,0xfe,0xe3,0xfe,0xf6,0xfe, + 0xfc,0xfe,0x14,0xff,0x24,0xff,0x40,0xff, + 0x59,0xff,0x79,0xff,0x98,0xff,0xba,0xff, + 0xdd,0xff,0xec,0x7f,0x23,0x00,0x45,0x00, + 0x67,0x00,0x84,0x00,0xa3,0x00,0xba,0x00, + 0xd4,0x00,0xe3,0x00,0xf8,0x00,0xfc,0x00, + 0x0c,0x01,0x05,0x01,0x14,0x01,0xf5,0x00, + 0x5a,0x01,0xa7,0x01,0x6a,0x01,0x55,0x01, + 0x25,0x01,0x07,0x01,0xdc,0x00,0xbc,0x00, + 0x96,0x00,0x78,0x00,0x58,0x00,0x41,0x00, + 0x29,0x00,0x19,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x1d,0x00,0x1f,0x00,0x50,0x00,0x40,0x00, + 0x99,0x00,0x67,0x00,0xf6,0x00,0x8e,0x00, + 0x64,0x01,0xae,0x00,0xe0,0x01,0xbe,0x00, + 0x6f,0x02,0x69,0x00,0x0c,0x02,0xcd,0xff, + 0x86,0x02,0x4f,0xff,0x0a,0x03,0x97,0xfe, + 0xb7,0x03,0x81,0xfd,0xc5,0x04,0xb8,0xfb, + 0xce,0x06,0x0f,0xf8,0x97,0x0c,0xbd,0xe9, + 0x08,0x74,0xd1,0x24,0xe9,0xef,0xa4,0x09, + 0x44,0xf8,0xff,0x04,0xc4,0xfa,0xec,0x02, + 0xf7,0xfb,0xb3,0x01,0xb3,0xfc,0xe6,0x00, + 0x3b,0xfd,0x5b,0x00,0xaf,0xfd,0xf7,0xff, + 0x62,0xfd,0x2e,0xff,0xe2,0xfd,0x3d,0xff, + 0x61,0xfe,0x5b,0xff,0xd5,0xfe,0x83,0xff, + 0x3a,0xff,0xac,0xff,0x8d,0xff,0xd2,0xff, + 0xcb,0xff,0xf2,0xff,0xf7,0xff,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfe,0xff,0xf9,0xff, + 0xef,0xff,0xd6,0xff,0xc1,0xff,0xa5,0xff, + 0x8a,0xff,0x67,0xff,0x47,0xff,0x1f,0xff, + 0xfd,0xfe,0xd2,0xfe,0xb2,0xfe,0x84,0xfe, + 0x6c,0xfe,0x36,0xfe,0xb9,0xfe,0xf6,0xfe, + 0xdc,0xfe,0xeb,0xfe,0xe7,0xfe,0xf8,0xfe, + 0x00,0xff,0x16,0xff,0x27,0xff,0x42,0xff, + 0x5b,0xff,0x7b,0xff,0x99,0xff,0xbb,0xff, + 0xdd,0xff,0xec,0x7f,0x23,0x00,0x44,0x00, + 0x66,0x00,0x83,0x00,0xa1,0x00,0xb8,0x00, + 0xd1,0x00,0xe1,0x00,0xf4,0x00,0xfa,0x00, + 0x08,0x01,0x03,0x01,0x0f,0x01,0xf4,0x00, + 0x2a,0x01,0x9d,0x01,0x69,0x01,0x4f,0x01, + 0x23,0x01,0x03,0x01,0xda,0x00,0xb9,0x00, + 0x94,0x00,0x77,0x00,0x58,0x00,0x3f,0x00, + 0x28,0x00,0x18,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x07,0x00,0x12,0x00,0x2b,0x00,0x36,0x00, + 0x5d,0x00,0x66,0x00,0x9e,0x00,0x9d,0x00, + 0xeb,0x00,0xd8,0x00,0x40,0x01,0x0f,0x01, + 0x9f,0x01,0xf6,0x00,0x18,0x01,0xaa,0x00, + 0x4e,0x01,0x95,0x00,0x73,0x01,0x62,0x00, + 0x90,0x01,0x0f,0x00,0xb6,0x01,0x8c,0xff, + 0x02,0x02,0xa9,0xfe,0xdf,0x02,0x66,0xfc, + 0x25,0x08,0x2b,0x7f,0xb5,0xf8,0x66,0x03, + 0x2b,0xfd,0x4d,0x01,0xf5,0xfd,0x6f,0x00, + 0x3a,0xfe,0xeb,0xff,0x5b,0xfe,0x94,0xff, + 0x74,0xfe,0x5d,0xff,0x96,0xfe,0x46,0xff, + 0xca,0xfe,0xd8,0xfe,0x30,0xfe,0xcc,0xfe, + 0x90,0xfe,0x03,0xff,0xe9,0xfe,0x40,0xff, + 0x3b,0xff,0x7d,0xff,0x83,0xff,0xb2,0xff, + 0xbd,0xff,0xe3,0xff,0xf1,0xff,0xfa,0xff, + 0xfe,0xff,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfe,0xff,0xf9,0xff, + 0xf2,0xff,0xdf,0xff,0xc1,0xff,0xac,0xff, + 0x8c,0xff,0x71,0xff,0x4a,0xff,0x2c,0xff, + 0x02,0xff,0xe5,0xfe,0xb5,0xfe,0xa0,0xfe, + 0x64,0xfe,0xa5,0xfe,0x14,0xff,0xf2,0xfe, + 0xfa,0xfe,0xec,0xfe,0xf9,0xfe,0xfd,0xfe, + 0x0f,0xff,0x1b,0xff,0x33,0xff,0x47,0xff, + 0x64,0xff,0x7f,0xff,0x9f,0xff,0xbe,0xff, + 0xdf,0xff,0xec,0x7f,0x21,0x00,0x42,0x00, + 0x60,0x00,0x7f,0x00,0x98,0x00,0xb3,0x00, + 0xc6,0x00,0xdb,0x00,0xe6,0x00,0xf6,0x00, + 0xf7,0x00,0x01,0x01,0xf3,0x00,0xf8,0x00, + 0xd7,0x00,0x39,0x01,0x70,0x01,0x36,0x01, + 0x20,0x01,0xf3,0x00,0xd6,0x00,0xae,0x00, + 0x91,0x00,0x6f,0x00,0x56,0x00,0x3b,0x00, + 0x29,0x00,0x13,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x05,0x00,0x0d,0x00,0x18,0x00,0x3d,0x00, + 0x46,0x00,0x72,0x00,0x77,0x00,0xb4,0x00, + 0xad,0x00,0xff,0x00,0xe2,0x00,0x56,0x01, + 0xd3,0x00,0xdf,0x00,0x95,0x00,0x10,0x01, + 0x8c,0x00,0x37,0x01,0x74,0x00,0x5b,0x01, + 0x41,0x00,0x76,0x01,0xe6,0xff,0x9f,0x01, + 0x54,0xff,0x03,0x02,0x3b,0xfe,0x6f,0x03, + 0xd2,0xf9,0x5a,0x7f,0xec,0x06,0x5e,0xfc, + 0xe3,0x01,0xea,0xfd,0xba,0x00,0x52,0xfe, + 0x21,0x00,0x7a,0xfe,0xc0,0xff,0x92,0xfe, + 0x88,0xff,0xb4,0xfe,0x6b,0xff,0xd9,0xfe, + 0x5f,0xff,0x08,0xff,0x27,0xff,0x7d,0xfe, + 0xfe,0xfe,0xd6,0xfe,0x33,0xff,0x26,0xff, + 0x6c,0xff,0x6d,0xff,0xa2,0xff,0xa8,0xff, + 0xd8,0xff,0xe9,0xff,0xf4,0xff,0xfa,0xff, + 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0xff,0xfa,0xff,0xf3,0xff, + 0xeb,0xff,0xd5,0xff,0xae,0xff,0x9a,0xff, + 0x78,0xff,0x5e,0xff,0x37,0xff,0x1d,0xff, + 0xf1,0xfe,0xdd,0xfe,0xa3,0xfe,0xef,0xfe, + 0x3f,0xff,0x1e,0xff,0x23,0xff,0x14,0xff, + 0x18,0xff,0x12,0xff,0x19,0xff,0x20,0xff, + 0x33,0xff,0x43,0xff,0x5b,0xff,0x71,0xff, + 0x8c,0xff,0xa7,0xff,0xc4,0xff,0xe2,0xff, + 0xec,0x7f,0x1e,0x00,0x3b,0x00,0x58,0x00, + 0x72,0x00,0x8c,0x00,0xa0,0x00,0xb6,0x00, + 0xc4,0x00,0xd5,0x00,0xdb,0x00,0xe0,0x00, + 0xd9,0x00,0xdb,0x00,0xcb,0x00,0xce,0x00, + 0xae,0x00,0xf4,0x00,0x34,0x01,0xfe,0x00, + 0xe8,0x00,0xbf,0x00,0xa5,0x00,0x82,0x00, + 0x6a,0x00,0x4c,0x00,0x39,0x00,0x1c,0x00, + 0x0c,0x00,0x06,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x08,0x00,0x01,0x00,0x1e,0x00, + 0x0b,0x00,0x6a,0x00,0x23,0x00,0xb7,0x00, + 0x30,0x00,0x19,0x01,0x39,0x00,0x5c,0x01, + 0x8f,0xff,0x90,0x01,0x4b,0xff,0x0a,0x02, + 0xe0,0xfe,0xa2,0x02,0x44,0xfe,0x64,0x03, + 0x62,0xfd,0x6e,0x04,0x0d,0xfc,0x00,0x06, + 0xcc,0xf9,0xd2,0x08,0x3d,0xf5,0x0f,0x10, + 0x67,0xe5,0xde,0x50,0x9a,0x51,0xb6,0xe4, + 0xf2,0x0f,0x3a,0xf4,0x55,0x08,0x7b,0xf8, + 0x33,0x05,0x83,0xfa,0x76,0x03,0xc7,0xfb, + 0x57,0x02,0xa9,0xfc,0x8f,0x01,0x58,0xfd, + 0x00,0x01,0xe8,0xfd,0x97,0x00,0x69,0xfe, + 0x0c,0x00,0x2f,0xfe,0xbd,0xff,0xb3,0xfe, + 0xbe,0xff,0x21,0xff,0xc9,0xff,0x8c,0xff, + 0x02,0x00,0xce,0xff,0xfe,0xff,0xee,0xff, + 0xff,0xff,0xfe,0xff,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xfc,0xff,0xf7,0xff,0xf0,0xff, + 0xe7,0xff,0xdb,0xff,0xa9,0xff,0x8c,0xff, + 0x73,0xff,0x56,0xff,0x39,0xff,0x1a,0xff, + 0x04,0xff,0x6c,0xff,0x6f,0xff,0x62,0xff, + 0x5c,0xff,0x55,0xff,0x52,0xff,0x4f,0xff, + 0x50,0xff,0x51,0xff,0x56,0xff,0x5c,0xff, + 0x65,0xff,0x76,0xff,0x8a,0xff,0x9f,0xff, + 0xb7,0xff,0xce,0xff,0xe7,0xff,0xec,0x7f, + 0x19,0x00,0x31,0x00,0x48,0x00,0x5f,0x00, + 0x73,0x00,0x86,0x00,0x95,0x00,0x9d,0x00, + 0xa2,0x00,0xa5,0x00,0xa6,0x00,0xa5,0x00, + 0xa1,0x00,0x9d,0x00,0x95,0x00,0x8f,0x00, + 0x81,0x00,0x83,0x00,0xdb,0x00,0xc5,0x00, + 0xa7,0x00,0x8c,0x00,0x71,0x00,0x5a,0x00, + 0x40,0x00,0x1a,0x00,0x10,0x00,0x09,0x00, + 0x04,0x00,0x01,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x01,0x00,0x00,0x00,0x0a,0x00, + 0x00,0x00,0x1b,0x00,0xfe,0xff,0x3a,0x00, + 0x33,0x00,0x9a,0x00,0x4b,0x00,0xb7,0x00, + 0xd1,0xff,0xbd,0x00,0xb7,0xff,0xf8,0x00, + 0x8a,0xff,0x40,0x01,0x47,0xff,0x98,0x01, + 0xe8,0xfe,0x0a,0x02,0x5f,0xfe,0xa9,0x02, + 0x90,0xfd,0x9f,0x03,0x33,0xfc,0x70,0x05, + 0x45,0xf9,0x69,0x0a,0x01,0xed,0x8e,0x78, + 0x09,0x1c,0x5e,0xf3,0xca,0x07,0xf6,0xf9, + 0x39,0x04,0x12,0xfc,0xae,0x02,0x23,0xfd, + 0xca,0x01,0xce,0xfd,0x35,0x01,0x46,0xfe, + 0xce,0x00,0xa3,0xfe,0x84,0x00,0xef,0xfe, + 0x51,0x00,0x2e,0xff,0x30,0x00,0x56,0xff, + 0xad,0xff,0x46,0xff,0xbc,0xff,0xa1,0xff, + 0x06,0x00,0xd8,0xff,0x00,0x00,0xef,0xff, + 0x00,0x00,0xfc,0xff,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xfe,0xff,0xfb,0xff,0xf7,0xff, + 0xf3,0xff,0xec,0xff,0xe9,0xff,0xd0,0xff, + 0x8d,0xff,0x84,0xff,0x5c,0xff,0x9e,0xff, + 0xc4,0xff,0xb1,0xff,0xb3,0xff,0xa9,0xff, + 0xa8,0xff,0xa2,0xff,0xa3,0xff,0xa0,0xff, + 0xa2,0xff,0xa1,0xff,0xa5,0xff,0xa7,0xff, + 0xad,0xff,0xb1,0xff,0xb9,0xff,0xbf,0xff, + 0xcc,0xff,0xdd,0xff,0xef,0xff,0xec,0x7f, + 0x11,0x00,0x22,0x00,0x33,0x00,0x40,0x00, + 0x46,0x00,0x4c,0x00,0x50,0x00,0x55,0x00, + 0x57,0x00,0x5a,0x00,0x59,0x00,0x5a,0x00, + 0x56,0x00,0x56,0x00,0x50,0x00,0x4f,0x00, + 0x45,0x00,0x46,0x00,0x34,0x00,0x54,0x00, + 0x8a,0x00,0x66,0x00,0x5c,0x00,0x25,0x00, + 0x11,0x00,0x0e,0x00,0x09,0x00,0x05,0x00, + 0x02,0x00,0x01,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xec,0x7f,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xec,0x7f,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xff,0xff,0xfe,0xff, + 0xfb,0xff,0xf7,0xff,0xf3,0xff,0xec,0xff, + 0xe9,0xff,0xd0,0xff,0x8d,0xff,0x84,0xff, + 0x5c,0xff,0x9e,0xff,0xc4,0xff,0xb1,0xff, + 0xb3,0xff,0xa9,0xff,0xa8,0xff,0xa2,0xff, + 0xa3,0xff,0xa0,0xff,0xa2,0xff,0xa1,0xff, + 0xa5,0xff,0xa7,0xff,0xad,0xff,0xb1,0xff, + 0xb9,0xff,0xbf,0xff,0xcc,0xff,0xdd,0xff, + 0xef,0xff,0xec,0x7f,0x11,0x00,0x22,0x00, + 0x33,0x00,0x40,0x00,0x46,0x00,0x4c,0x00, + 0x50,0x00,0x55,0x00,0x57,0x00,0x5a,0x00, + 0x59,0x00,0x5a,0x00,0x56,0x00,0x56,0x00, + 0x50,0x00,0x4f,0x00,0x45,0x00,0x46,0x00, + 0x34,0x00,0x54,0x00,0x8a,0x00,0x66,0x00, + 0x5c,0x00,0x25,0x00,0x11,0x00,0x0e,0x00, + 0x09,0x00,0x05,0x00,0x02,0x00,0x01,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0x00,0x00,0x0a,0x00,0x00,0x00,0x1b,0x00, + 0xfe,0xff,0x3a,0x00,0x33,0x00,0x9a,0x00, + 0x4b,0x00,0xb7,0x00,0xd1,0xff,0xbd,0x00, + 0xb7,0xff,0xf8,0x00,0x8a,0xff,0x40,0x01, + 0x47,0xff,0x98,0x01,0xe8,0xfe,0x0a,0x02, + 0x5f,0xfe,0xa9,0x02,0x90,0xfd,0x9f,0x03, + 0x33,0xfc,0x70,0x05,0x45,0xf9,0x69,0x0a, + 0x01,0xed,0x8e,0x78,0x09,0x1c,0x5e,0xf3, + 0xca,0x07,0xf6,0xf9,0x39,0x04,0x12,0xfc, + 0xae,0x02,0x23,0xfd,0xca,0x01,0xce,0xfd, + 0x35,0x01,0x46,0xfe,0xce,0x00,0xa3,0xfe, + 0x84,0x00,0xef,0xfe,0x51,0x00,0x2e,0xff, + 0x30,0x00,0x56,0xff,0xad,0xff,0x46,0xff, + 0xbc,0xff,0xa1,0xff,0x06,0x00,0xd8,0xff, + 0x00,0x00,0xef,0xff,0x00,0x00,0xfc,0xff, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xff,0xff,0xfc,0xff, + 0xf7,0xff,0xf0,0xff,0xe7,0xff,0xdb,0xff, + 0xa9,0xff,0x8c,0xff,0x73,0xff,0x56,0xff, + 0x39,0xff,0x1a,0xff,0x04,0xff,0x6c,0xff, + 0x6f,0xff,0x62,0xff,0x5c,0xff,0x55,0xff, + 0x52,0xff,0x4f,0xff,0x50,0xff,0x51,0xff, + 0x56,0xff,0x5c,0xff,0x65,0xff,0x76,0xff, + 0x8a,0xff,0x9f,0xff,0xb7,0xff,0xce,0xff, + 0xe7,0xff,0xec,0x7f,0x19,0x00,0x31,0x00, + 0x48,0x00,0x5f,0x00,0x73,0x00,0x86,0x00, + 0x95,0x00,0x9d,0x00,0xa2,0x00,0xa5,0x00, + 0xa6,0x00,0xa5,0x00,0xa1,0x00,0x9d,0x00, + 0x95,0x00,0x8f,0x00,0x81,0x00,0x83,0x00, + 0xdb,0x00,0xc5,0x00,0xa7,0x00,0x8c,0x00, + 0x71,0x00,0x5a,0x00,0x40,0x00,0x1a,0x00, + 0x10,0x00,0x09,0x00,0x04,0x00,0x01,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00, + 0x01,0x00,0x1e,0x00,0x0b,0x00,0x6a,0x00, + 0x23,0x00,0xb7,0x00,0x30,0x00,0x19,0x01, + 0x39,0x00,0x5c,0x01,0x8f,0xff,0x90,0x01, + 0x4b,0xff,0x0a,0x02,0xe0,0xfe,0xa2,0x02, + 0x44,0xfe,0x64,0x03,0x62,0xfd,0x6e,0x04, + 0x0d,0xfc,0x00,0x06,0xcc,0xf9,0xd2,0x08, + 0x3d,0xf5,0x0f,0x10,0x67,0xe5,0xde,0x50, + 0x9a,0x51,0xb6,0xe4,0xf2,0x0f,0x3a,0xf4, + 0x55,0x08,0x7b,0xf8,0x33,0x05,0x83,0xfa, + 0x76,0x03,0xc7,0xfb,0x57,0x02,0xa9,0xfc, + 0x8f,0x01,0x58,0xfd,0x00,0x01,0xe8,0xfd, + 0x97,0x00,0x69,0xfe,0x0c,0x00,0x2f,0xfe, + 0xbd,0xff,0xb3,0xfe,0xbe,0xff,0x21,0xff, + 0xc9,0xff,0x8c,0xff,0x02,0x00,0xce,0xff, + 0xfe,0xff,0xee,0xff,0xff,0xff,0xfe,0xff, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, + 0xfa,0xff,0xf3,0xff,0xeb,0xff,0xd5,0xff, + 0xae,0xff,0x9a,0xff,0x78,0xff,0x5e,0xff, + 0x37,0xff,0x1d,0xff,0xf1,0xfe,0xdd,0xfe, + 0xa3,0xfe,0xef,0xfe,0x3f,0xff,0x1e,0xff, + 0x23,0xff,0x14,0xff,0x18,0xff,0x12,0xff, + 0x19,0xff,0x20,0xff,0x33,0xff,0x43,0xff, + 0x5b,0xff,0x71,0xff,0x8c,0xff,0xa7,0xff, + 0xc4,0xff,0xe2,0xff,0xec,0x7f,0x1e,0x00, + 0x3b,0x00,0x58,0x00,0x72,0x00,0x8c,0x00, + 0xa0,0x00,0xb6,0x00,0xc4,0x00,0xd5,0x00, + 0xdb,0x00,0xe0,0x00,0xd9,0x00,0xdb,0x00, + 0xcb,0x00,0xce,0x00,0xae,0x00,0xf4,0x00, + 0x34,0x01,0xfe,0x00,0xe8,0x00,0xbf,0x00, + 0xa5,0x00,0x82,0x00,0x6a,0x00,0x4c,0x00, + 0x39,0x00,0x1c,0x00,0x0c,0x00,0x06,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x05,0x00,0x0d,0x00, + 0x18,0x00,0x3d,0x00,0x46,0x00,0x72,0x00, + 0x77,0x00,0xb4,0x00,0xad,0x00,0xff,0x00, + 0xe2,0x00,0x56,0x01,0xd3,0x00,0xdf,0x00, + 0x95,0x00,0x10,0x01,0x8c,0x00,0x37,0x01, + 0x74,0x00,0x5b,0x01,0x41,0x00,0x76,0x01, + 0xe6,0xff,0x9f,0x01,0x54,0xff,0x03,0x02, + 0x3b,0xfe,0x6f,0x03,0xd2,0xf9,0x5a,0x7f, + 0xec,0x06,0x5e,0xfc,0xe3,0x01,0xea,0xfd, + 0xba,0x00,0x52,0xfe,0x21,0x00,0x7a,0xfe, + 0xc0,0xff,0x92,0xfe,0x88,0xff,0xb4,0xfe, + 0x6b,0xff,0xd9,0xfe,0x5f,0xff,0x08,0xff, + 0x27,0xff,0x7d,0xfe,0xfe,0xfe,0xd6,0xfe, + 0x33,0xff,0x26,0xff,0x6c,0xff,0x6d,0xff, + 0xa2,0xff,0xa8,0xff,0xd8,0xff,0xe9,0xff, + 0xf4,0xff,0xfa,0xff,0xff,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0xff,0xf9,0xff,0xf2,0xff,0xdf,0xff, + 0xc1,0xff,0xac,0xff,0x8c,0xff,0x71,0xff, + 0x4a,0xff,0x2c,0xff,0x02,0xff,0xe5,0xfe, + 0xb5,0xfe,0xa0,0xfe,0x64,0xfe,0xa5,0xfe, + 0x14,0xff,0xf2,0xfe,0xfa,0xfe,0xec,0xfe, + 0xf9,0xfe,0xfd,0xfe,0x0f,0xff,0x1b,0xff, + 0x33,0xff,0x47,0xff,0x64,0xff,0x7f,0xff, + 0x9f,0xff,0xbe,0xff,0xdf,0xff,0xec,0x7f, + 0x21,0x00,0x42,0x00,0x60,0x00,0x7f,0x00, + 0x98,0x00,0xb3,0x00,0xc6,0x00,0xdb,0x00, + 0xe6,0x00,0xf6,0x00,0xf7,0x00,0x01,0x01, + 0xf3,0x00,0xf8,0x00,0xd7,0x00,0x39,0x01, + 0x70,0x01,0x36,0x01,0x20,0x01,0xf3,0x00, + 0xd6,0x00,0xae,0x00,0x91,0x00,0x6f,0x00, + 0x56,0x00,0x3b,0x00,0x29,0x00,0x13,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x07,0x00,0x12,0x00, + 0x2b,0x00,0x36,0x00,0x5d,0x00,0x66,0x00, + 0x9e,0x00,0x9d,0x00,0xeb,0x00,0xd8,0x00, + 0x40,0x01,0x0f,0x01,0x9f,0x01,0xf6,0x00, + 0x18,0x01,0xaa,0x00,0x4e,0x01,0x95,0x00, + 0x73,0x01,0x62,0x00,0x90,0x01,0x0f,0x00, + 0xb6,0x01,0x8c,0xff,0x02,0x02,0xa9,0xfe, + 0xdf,0x02,0x66,0xfc,0x25,0x08,0x2b,0x7f, + 0xb5,0xf8,0x66,0x03,0x2b,0xfd,0x4d,0x01, + 0xf5,0xfd,0x6f,0x00,0x3a,0xfe,0xeb,0xff, + 0x5b,0xfe,0x94,0xff,0x74,0xfe,0x5d,0xff, + 0x96,0xfe,0x46,0xff,0xca,0xfe,0xd8,0xfe, + 0x30,0xfe,0xcc,0xfe,0x90,0xfe,0x03,0xff, + 0xe9,0xfe,0x40,0xff,0x3b,0xff,0x7d,0xff, + 0x83,0xff,0xb2,0xff,0xbd,0xff,0xe3,0xff, + 0xf1,0xff,0xfa,0xff,0xfe,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0xff,0xf9,0xff,0xef,0xff,0xd6,0xff, + 0xc1,0xff,0xa5,0xff,0x8a,0xff,0x67,0xff, + 0x47,0xff,0x1f,0xff,0xfd,0xfe,0xd2,0xfe, + 0xb2,0xfe,0x84,0xfe,0x6c,0xfe,0x36,0xfe, + 0xb9,0xfe,0xf6,0xfe,0xdc,0xfe,0xeb,0xfe, + 0xe7,0xfe,0xf8,0xfe,0x00,0xff,0x16,0xff, + 0x27,0xff,0x42,0xff,0x5b,0xff,0x7b,0xff, + 0x99,0xff,0xbb,0xff,0xdd,0xff,0xec,0x7f, + 0x23,0x00,0x44,0x00,0x66,0x00,0x83,0x00, + 0xa1,0x00,0xb8,0x00,0xd1,0x00,0xe1,0x00, + 0xf4,0x00,0xfa,0x00,0x08,0x01,0x03,0x01, + 0x0f,0x01,0xf4,0x00,0x2a,0x01,0x9d,0x01, + 0x69,0x01,0x4f,0x01,0x23,0x01,0x03,0x01, + 0xda,0x00,0xb9,0x00,0x94,0x00,0x77,0x00, + 0x58,0x00,0x3f,0x00,0x28,0x00,0x18,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x1d,0x00,0x1f,0x00, + 0x50,0x00,0x40,0x00,0x99,0x00,0x67,0x00, + 0xf6,0x00,0x8e,0x00,0x64,0x01,0xae,0x00, + 0xe0,0x01,0xbe,0x00,0x6f,0x02,0x69,0x00, + 0x0c,0x02,0xcd,0xff,0x86,0x02,0x4f,0xff, + 0x0a,0x03,0x97,0xfe,0xb7,0x03,0x81,0xfd, + 0xc5,0x04,0xb8,0xfb,0xce,0x06,0x0f,0xf8, + 0x97,0x0c,0xbd,0xe9,0x08,0x74,0xd1,0x24, + 0xe9,0xef,0xa4,0x09,0x44,0xf8,0xff,0x04, + 0xc4,0xfa,0xec,0x02,0xf7,0xfb,0xb3,0x01, + 0xb3,0xfc,0xe6,0x00,0x3b,0xfd,0x5b,0x00, + 0xaf,0xfd,0xf7,0xff,0x62,0xfd,0x2e,0xff, + 0xe2,0xfd,0x3d,0xff,0x61,0xfe,0x5b,0xff, + 0xd5,0xfe,0x83,0xff,0x3a,0xff,0xac,0xff, + 0x8d,0xff,0xd2,0xff,0xcb,0xff,0xf2,0xff, + 0xf7,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0xff,0xf9,0xff,0xec,0xff,0xd5,0xff, + 0xc1,0xff,0xa4,0xff,0x89,0xff,0x65,0xff, + 0x45,0xff,0x1c,0xff,0xfb,0xfe,0xcd,0xfe, + 0xaf,0xfe,0x7e,0xfe,0x6a,0xfe,0x2b,0xfe, + 0x84,0xfe,0xf6,0xfe,0xd6,0xfe,0xe9,0xfe, + 0xe3,0xfe,0xf6,0xfe,0xfc,0xfe,0x14,0xff, + 0x24,0xff,0x40,0xff,0x59,0xff,0x79,0xff, + 0x98,0xff,0xba,0xff,0xdd,0xff,0xec,0x7f, + 0x23,0x00,0x45,0x00,0x67,0x00,0x84,0x00, + 0xa3,0x00,0xba,0x00,0xd4,0x00,0xe3,0x00, + 0xf8,0x00,0xfc,0x00,0x0c,0x01,0x05,0x01, + 0x14,0x01,0xf5,0x00,0x5a,0x01,0xa7,0x01, + 0x6a,0x01,0x55,0x01,0x25,0x01,0x07,0x01, + 0xdc,0x00,0xbc,0x00,0x96,0x00,0x78,0x00, + 0x58,0x00,0x41,0x00,0x29,0x00,0x19,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x19,0x00,0x29,0x00, + 0x41,0x00,0x58,0x00,0x79,0x00,0x95,0x00, + 0xbd,0x00,0xdb,0x00,0x08,0x01,0x24,0x01, + 0x56,0x01,0x68,0x01,0xaa,0x01,0x58,0x01, + 0xf9,0x00,0x10,0x01,0x0a,0x01,0x06,0x01, + 0x04,0x01,0xef,0x00,0xed,0x00,0xc8,0x00, + 0xc8,0x00,0x91,0x00,0x9b,0x00,0x48,0x00, + 0x74,0x00,0xc5,0xff,0xeb,0x7f,0x3c,0x00, + 0x8b,0xff,0xb7,0xff,0x62,0xff,0x6b,0xff, + 0x32,0xff,0x30,0xff,0x09,0xff,0x05,0xff, + 0xee,0xfe,0xe9,0xfe,0xe3,0xfe,0xdb,0xfe, + 0xf1,0xfe,0x88,0xfe,0x28,0xfe,0x6d,0xfe, + 0x7c,0xfe,0xb1,0xfe,0xcc,0xfe,0xfc,0xfe, + 0x1b,0xff,0x46,0xff,0x64,0xff,0x89,0xff, + 0xa4,0xff,0xc1,0xff,0xd5,0xff,0xec,0xff, + 0xf9,0xff,0xfe,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x04,0x00,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00, + 0x01,0x00,0x02,0x00,0xa6,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0xb5,0xff,0x00,0x00, + 0x02,0x00,0x00,0x00,0xc4,0xff,0x00,0x00, + 0x04,0x00,0x00,0x00,0xd3,0xff,0x00,0x00, + 0x06,0x00,0x00,0x00,0xe2,0xff,0x00,0x00, + 0x08,0x00,0x00,0x00,0xf1,0xff,0x00,0x00, + 0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x0c,0x00,0x00,0x00,0x0f,0x00,0x00,0x00, + 0x0e,0x00,0x00,0x00,0x1e,0x00,0x00,0x00, + 0x10,0x00,0x00,0x00,0x2d,0x00,0x00,0x00, + 0x12,0x00,0x00,0x00,0x3c,0x00,0x00,0x00, + 0x14,0x00,0x00,0x00,0x4b,0x00,0x00,0x00, + 0x16,0x00,0x00,0x00,0x5a,0x00,0x00,0x00, + 0x18,0x00,0x00,0x00,0x00,0x00,0x66,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x9a,0xff, + 0x00,0x00,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/tdfb/line2_50mm_pm0_30_90deg_16khz.conf b/tools/topology/topology2/include/components/tdfb/line2_50mm_pm0_30_90deg_16khz.conf new file mode 100644 index 000000000000..c2e9b2003684 --- /dev/null +++ b/tools/topology/topology2/include/components/tdfb/line2_50mm_pm0_30_90deg_16khz.conf @@ -0,0 +1,258 @@ +# Created with script example_two_beams.m 23-Oct-2023 +# cd tools/tune/tdfb; matlab -nodisplay -nosplash -nodesktop -r example_two_beams +Object.Base.data."tdfb_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0xc4,0x07,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xc4,0x07,0x00,0x00,0x04,0x00,0x02,0x00, + 0x01,0x00,0x02,0x00,0x03,0x00,0x01,0x00, + 0x00,0x00,0x0f,0x00,0xa6,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xec,0x7f,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xec,0x7f,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xec,0x7f,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xec,0x7f,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xfe,0xff,0xf9,0xff,0xee,0xff, + 0xe1,0xff,0xcd,0xff,0xb6,0xff,0x97,0xff, + 0x77,0xff,0x4b,0xff,0x22,0xff,0xe9,0xfe, + 0xb7,0xfe,0x72,0xfe,0x3b,0xfe,0xea,0xfd, + 0xa4,0xfd,0x3a,0xfd,0xf7,0xfc,0x87,0xfc, + 0x5f,0xfc,0x0c,0xfc,0x27,0xfc,0xa5,0xfb, + 0xb7,0xf8,0xe9,0xf7,0x18,0xfb,0x03,0xfd, + 0x07,0xfd,0xb4,0xfd,0x39,0xfe,0x26,0xff, + 0xec,0x7f,0xd9,0x00,0xc3,0x01,0x43,0x02, + 0xea,0x02,0xe9,0x02,0xc2,0x04,0xcd,0x07, + 0xfc,0x06,0x26,0x04,0xa5,0x03,0xb8,0x03, + 0x64,0x03,0x38,0x03,0xcb,0x02,0x87,0x02, + 0x21,0x02,0xdd,0x01,0x90,0x01,0x5a,0x01, + 0x1a,0x01,0xea,0x00,0xb7,0x00,0x91,0x00, + 0x6a,0x00,0x4e,0x00,0x34,0x00,0x21,0x00, + 0x12,0x00,0x08,0x00,0x02,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0x0a,0x00,0x0e,0x00,0x29,0x00,0x28,0x00, + 0x61,0x00,0x52,0x00,0xb4,0x00,0x8b,0x00, + 0x25,0x01,0xd4,0x00,0xb4,0x01,0x27,0x01, + 0x60,0x02,0x8d,0x01,0x40,0x03,0xfa,0x01, + 0x36,0x04,0x3d,0x02,0x10,0x05,0xff,0x01, + 0x4e,0x06,0x31,0x05,0x03,0x0a,0x11,0x01, + 0xc8,0x06,0xc9,0xfd,0x1f,0x09,0xbb,0xf6, + 0xeb,0x18,0x10,0x7a,0x91,0xed,0x71,0x07, + 0x47,0xf7,0xb2,0x01,0x30,0xf9,0x83,0xfd, + 0x1e,0xf5,0x52,0xfb,0x11,0xfa,0x9e,0xfd, + 0xb9,0xfa,0x83,0xfd,0x8d,0xfb,0xd6,0xfd, + 0x82,0xfc,0x4b,0xfe,0x64,0xfd,0xb1,0xfe, + 0x13,0xfe,0x09,0xff,0xa9,0xfe,0x58,0xff, + 0x23,0xff,0x97,0xff,0x80,0xff,0xc7,0xff, + 0xc1,0xff,0xe8,0xff,0xeb,0xff,0xfa,0xff, + 0xfe,0xff,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x01,0x00,0x0a,0x00,0x0e,0x00, + 0x29,0x00,0x28,0x00,0x61,0x00,0x52,0x00, + 0xb4,0x00,0x8b,0x00,0x25,0x01,0xd4,0x00, + 0xb4,0x01,0x27,0x01,0x60,0x02,0x8d,0x01, + 0x40,0x03,0xfa,0x01,0x36,0x04,0x3d,0x02, + 0x10,0x05,0xff,0x01,0x4e,0x06,0x31,0x05, + 0x03,0x0a,0x11,0x01,0xc8,0x06,0xc9,0xfd, + 0x1f,0x09,0xbb,0xf6,0xeb,0x18,0x10,0x7a, + 0x91,0xed,0x71,0x07,0x47,0xf7,0xb2,0x01, + 0x30,0xf9,0x83,0xfd,0x1e,0xf5,0x52,0xfb, + 0x11,0xfa,0x9e,0xfd,0xb9,0xfa,0x83,0xfd, + 0x8d,0xfb,0xd6,0xfd,0x82,0xfc,0x4b,0xfe, + 0x64,0xfd,0xb1,0xfe,0x13,0xfe,0x09,0xff, + 0xa9,0xfe,0x58,0xff,0x23,0xff,0x97,0xff, + 0x80,0xff,0xc7,0xff,0xc1,0xff,0xe8,0xff, + 0xeb,0xff,0xfa,0xff,0xfe,0xff,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff, + 0xf9,0xff,0xee,0xff,0xe1,0xff,0xcd,0xff, + 0xb6,0xff,0x97,0xff,0x77,0xff,0x4b,0xff, + 0x22,0xff,0xe9,0xfe,0xb7,0xfe,0x72,0xfe, + 0x3b,0xfe,0xea,0xfd,0xa4,0xfd,0x3a,0xfd, + 0xf7,0xfc,0x87,0xfc,0x5f,0xfc,0x0c,0xfc, + 0x27,0xfc,0xa5,0xfb,0xb7,0xf8,0xe9,0xf7, + 0x18,0xfb,0x03,0xfd,0x07,0xfd,0xb4,0xfd, + 0x39,0xfe,0x26,0xff,0xec,0x7f,0xd9,0x00, + 0xc3,0x01,0x43,0x02,0xea,0x02,0xe9,0x02, + 0xc2,0x04,0xcd,0x07,0xfc,0x06,0x26,0x04, + 0xa5,0x03,0xb8,0x03,0x64,0x03,0x38,0x03, + 0xcb,0x02,0x87,0x02,0x21,0x02,0xdd,0x01, + 0x90,0x01,0x5a,0x01,0x1a,0x01,0xea,0x00, + 0xb7,0x00,0x91,0x00,0x6a,0x00,0x4e,0x00, + 0x34,0x00,0x21,0x00,0x12,0x00,0x08,0x00, + 0x02,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfd,0xff,0xf2,0xff, + 0xe1,0xff,0xc7,0xff,0xa6,0xff,0x7a,0xff, + 0x49,0xff,0x08,0xff,0xc8,0xfe,0x72,0xfe, + 0x23,0xfe,0xba,0xfd,0x5d,0xfd,0xd1,0xfc, + 0x66,0xfc,0xc9,0xfb,0x63,0xfb,0xbc,0xfa, + 0x74,0xfa,0xca,0xf9,0xd3,0xf9,0xa2,0xf8, + 0xc2,0xf5,0x93,0xf5,0xf1,0xf5,0xac,0xf5, + 0x7f,0xf8,0xbc,0xfb,0x46,0xfc,0xa8,0xfd, + 0xba,0xfe,0xec,0x7f,0x44,0x01,0x52,0x02, + 0xab,0x03,0x2f,0x04,0x51,0x07,0x04,0x0a, + 0xb3,0x09,0xff,0x09,0xc3,0x09,0xfb,0x06, + 0xd0,0x05,0xcd,0x05,0x25,0x05,0xd8,0x04, + 0x35,0x04,0xce,0x03,0x38,0x03,0xcf,0x02, + 0x4c,0x02,0xf3,0x01,0x91,0x01,0x48,0x01, + 0xfa,0x00,0xc0,0x00,0x88,0x00,0x5e,0x00, + 0x3a,0x00,0x20,0x00,0x0e,0x00,0x03,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00, + 0x11,0x00,0x19,0x00,0x48,0x00,0x4a,0x00, + 0xa9,0x00,0x95,0x00,0x39,0x01,0xfc,0x00, + 0xf9,0x01,0x7a,0x01,0xee,0x02,0x1c,0x02, + 0x21,0x04,0xcc,0x02,0x78,0x05,0x6b,0x03, + 0xd8,0x06,0xd5,0x03,0x09,0x08,0x21,0x05, + 0x2c,0x0d,0xd7,0x05,0x50,0x0e,0xe5,0x03, + 0xe1,0x0c,0xc6,0xfa,0x1b,0x10,0x19,0xed, + 0x61,0x35,0x6c,0x69,0x00,0xe4,0x27,0x0c, + 0xad,0xf1,0xeb,0x02,0xc9,0xf0,0xaf,0xfa, + 0x84,0xf1,0xe8,0xf8,0x3b,0xf3,0x06,0xfc, + 0x3a,0xf7,0xf3,0xfb,0xa0,0xf8,0x57,0xfc, + 0x13,0xfa,0xf9,0xfc,0x76,0xfb,0xae,0xfd, + 0xb5,0xfc,0x4f,0xfe,0xb1,0xfd,0xd5,0xfe, + 0x80,0xfe,0x44,0xff,0x20,0xff,0x99,0xff, + 0x92,0xff,0xd4,0xff,0xda,0xff,0xf6,0xff, + 0xfc,0xff,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x03,0x00,0x11,0x00,0x19,0x00, + 0x48,0x00,0x4a,0x00,0xa9,0x00,0x95,0x00, + 0x39,0x01,0xfc,0x00,0xf9,0x01,0x7a,0x01, + 0xee,0x02,0x1c,0x02,0x21,0x04,0xcc,0x02, + 0x78,0x05,0x6b,0x03,0xd8,0x06,0xd5,0x03, + 0x09,0x08,0x21,0x05,0x2c,0x0d,0xd7,0x05, + 0x50,0x0e,0xe5,0x03,0xe1,0x0c,0xc6,0xfa, + 0x1b,0x10,0x19,0xed,0x61,0x35,0x6c,0x69, + 0x00,0xe4,0x27,0x0c,0xad,0xf1,0xeb,0x02, + 0xc9,0xf0,0xaf,0xfa,0x84,0xf1,0xe8,0xf8, + 0x3b,0xf3,0x06,0xfc,0x3a,0xf7,0xf3,0xfb, + 0xa0,0xf8,0x57,0xfc,0x13,0xfa,0xf9,0xfc, + 0x76,0xfb,0xae,0xfd,0xb5,0xfc,0x4f,0xfe, + 0xb1,0xfd,0xd5,0xfe,0x80,0xfe,0x44,0xff, + 0x20,0xff,0x99,0xff,0x92,0xff,0xd4,0xff, + 0xda,0xff,0xf6,0xff,0xfc,0xff,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfd,0xff,0xf2,0xff,0xe1,0xff,0xc7,0xff, + 0xa6,0xff,0x7a,0xff,0x49,0xff,0x08,0xff, + 0xc8,0xfe,0x72,0xfe,0x23,0xfe,0xba,0xfd, + 0x5d,0xfd,0xd1,0xfc,0x66,0xfc,0xc9,0xfb, + 0x63,0xfb,0xbc,0xfa,0x74,0xfa,0xca,0xf9, + 0xd3,0xf9,0xa2,0xf8,0xc2,0xf5,0x93,0xf5, + 0xf1,0xf5,0xac,0xf5,0x7f,0xf8,0xbc,0xfb, + 0x46,0xfc,0xa8,0xfd,0xba,0xfe,0xec,0x7f, + 0x44,0x01,0x52,0x02,0xab,0x03,0x2f,0x04, + 0x51,0x07,0x04,0x0a,0xb3,0x09,0xff,0x09, + 0xc3,0x09,0xfb,0x06,0xd0,0x05,0xcd,0x05, + 0x25,0x05,0xd8,0x04,0x35,0x04,0xce,0x03, + 0x38,0x03,0xcf,0x02,0x4c,0x02,0xf3,0x01, + 0x91,0x01,0x48,0x01,0xfa,0x00,0xc0,0x00, + 0x88,0x00,0x5e,0x00,0x3a,0x00,0x20,0x00, + 0x0e,0x00,0x03,0x00,0x04,0x00,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x04,0x00,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00, + 0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x1e,0x00,0x00,0x00, + 0x04,0x00,0x00,0x00,0x5a,0x00,0x00,0x00, + 0x08,0x00,0x00,0x00,0x00,0x00,0x66,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x9a,0xff, + 0x00,0x00,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/tdfb/line2_50mm_pm0_30_90deg_48khz.conf b/tools/topology/topology2/include/components/tdfb/line2_50mm_pm0_30_90deg_48khz.conf new file mode 100644 index 000000000000..339d281c2f27 --- /dev/null +++ b/tools/topology/topology2/include/components/tdfb/line2_50mm_pm0_30_90deg_48khz.conf @@ -0,0 +1,258 @@ +# Created with script example_two_beams.m 23-Oct-2023 +# cd tools/tune/tdfb; matlab -nodisplay -nosplash -nodesktop -r example_two_beams +Object.Base.data."tdfb_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0xc4,0x07,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xc4,0x07,0x00,0x00,0x04,0x00,0x02,0x00, + 0x01,0x00,0x02,0x00,0x03,0x00,0x01,0x00, + 0x00,0x00,0x0f,0x00,0xa6,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xec,0x7f,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xec,0x7f,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xec,0x7f,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xec,0x7f,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xff,0xff,0xfc,0xff, + 0xf7,0xff,0xf0,0xff,0xe7,0xff,0xdb,0xff, + 0xa9,0xff,0x8c,0xff,0x73,0xff,0x56,0xff, + 0x39,0xff,0x1a,0xff,0x04,0xff,0x6c,0xff, + 0x6f,0xff,0x62,0xff,0x5c,0xff,0x55,0xff, + 0x52,0xff,0x4f,0xff,0x50,0xff,0x51,0xff, + 0x56,0xff,0x5c,0xff,0x65,0xff,0x76,0xff, + 0x8a,0xff,0x9f,0xff,0xb7,0xff,0xce,0xff, + 0xe7,0xff,0xec,0x7f,0x19,0x00,0x31,0x00, + 0x48,0x00,0x5f,0x00,0x73,0x00,0x86,0x00, + 0x95,0x00,0x9d,0x00,0xa2,0x00,0xa5,0x00, + 0xa6,0x00,0xa5,0x00,0xa1,0x00,0x9d,0x00, + 0x95,0x00,0x8f,0x00,0x81,0x00,0x83,0x00, + 0xdb,0x00,0xc5,0x00,0xa7,0x00,0x8c,0x00, + 0x71,0x00,0x5a,0x00,0x40,0x00,0x1a,0x00, + 0x10,0x00,0x09,0x00,0x04,0x00,0x01,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00, + 0x01,0x00,0x1e,0x00,0x0b,0x00,0x6a,0x00, + 0x23,0x00,0xb7,0x00,0x30,0x00,0x19,0x01, + 0x39,0x00,0x5c,0x01,0x8f,0xff,0x90,0x01, + 0x4b,0xff,0x0a,0x02,0xe0,0xfe,0xa2,0x02, + 0x44,0xfe,0x64,0x03,0x62,0xfd,0x6e,0x04, + 0x0d,0xfc,0x00,0x06,0xcc,0xf9,0xd2,0x08, + 0x3d,0xf5,0x0f,0x10,0x67,0xe5,0xde,0x50, + 0x9a,0x51,0xb6,0xe4,0xf2,0x0f,0x3a,0xf4, + 0x55,0x08,0x7b,0xf8,0x33,0x05,0x83,0xfa, + 0x76,0x03,0xc7,0xfb,0x57,0x02,0xa9,0xfc, + 0x8f,0x01,0x58,0xfd,0x00,0x01,0xe8,0xfd, + 0x97,0x00,0x69,0xfe,0x0c,0x00,0x2f,0xfe, + 0xbd,0xff,0xb3,0xfe,0xbe,0xff,0x21,0xff, + 0xc9,0xff,0x8c,0xff,0x02,0x00,0xce,0xff, + 0xfe,0xff,0xee,0xff,0xff,0xff,0xfe,0xff, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x08,0x00,0x01,0x00,0x1e,0x00, + 0x0b,0x00,0x6a,0x00,0x23,0x00,0xb7,0x00, + 0x30,0x00,0x19,0x01,0x39,0x00,0x5c,0x01, + 0x8f,0xff,0x90,0x01,0x4b,0xff,0x0a,0x02, + 0xe0,0xfe,0xa2,0x02,0x44,0xfe,0x64,0x03, + 0x62,0xfd,0x6e,0x04,0x0d,0xfc,0x00,0x06, + 0xcc,0xf9,0xd2,0x08,0x3d,0xf5,0x0f,0x10, + 0x67,0xe5,0xde,0x50,0x9a,0x51,0xb6,0xe4, + 0xf2,0x0f,0x3a,0xf4,0x55,0x08,0x7b,0xf8, + 0x33,0x05,0x83,0xfa,0x76,0x03,0xc7,0xfb, + 0x57,0x02,0xa9,0xfc,0x8f,0x01,0x58,0xfd, + 0x00,0x01,0xe8,0xfd,0x97,0x00,0x69,0xfe, + 0x0c,0x00,0x2f,0xfe,0xbd,0xff,0xb3,0xfe, + 0xbe,0xff,0x21,0xff,0xc9,0xff,0x8c,0xff, + 0x02,0x00,0xce,0xff,0xfe,0xff,0xee,0xff, + 0xff,0xff,0xfe,0xff,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xfc,0xff,0xf7,0xff,0xf0,0xff, + 0xe7,0xff,0xdb,0xff,0xa9,0xff,0x8c,0xff, + 0x73,0xff,0x56,0xff,0x39,0xff,0x1a,0xff, + 0x04,0xff,0x6c,0xff,0x6f,0xff,0x62,0xff, + 0x5c,0xff,0x55,0xff,0x52,0xff,0x4f,0xff, + 0x50,0xff,0x51,0xff,0x56,0xff,0x5c,0xff, + 0x65,0xff,0x76,0xff,0x8a,0xff,0x9f,0xff, + 0xb7,0xff,0xce,0xff,0xe7,0xff,0xec,0x7f, + 0x19,0x00,0x31,0x00,0x48,0x00,0x5f,0x00, + 0x73,0x00,0x86,0x00,0x95,0x00,0x9d,0x00, + 0xa2,0x00,0xa5,0x00,0xa6,0x00,0xa5,0x00, + 0xa1,0x00,0x9d,0x00,0x95,0x00,0x8f,0x00, + 0x81,0x00,0x83,0x00,0xdb,0x00,0xc5,0x00, + 0xa7,0x00,0x8c,0x00,0x71,0x00,0x5a,0x00, + 0x40,0x00,0x1a,0x00,0x10,0x00,0x09,0x00, + 0x04,0x00,0x01,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0xff,0xf9,0xff,0xec,0xff,0xd5,0xff, + 0xc1,0xff,0xa4,0xff,0x89,0xff,0x65,0xff, + 0x45,0xff,0x1c,0xff,0xfb,0xfe,0xcd,0xfe, + 0xaf,0xfe,0x7e,0xfe,0x6a,0xfe,0x2b,0xfe, + 0x84,0xfe,0xf6,0xfe,0xd6,0xfe,0xe9,0xfe, + 0xe3,0xfe,0xf6,0xfe,0xfc,0xfe,0x14,0xff, + 0x24,0xff,0x40,0xff,0x59,0xff,0x79,0xff, + 0x98,0xff,0xba,0xff,0xdd,0xff,0xec,0x7f, + 0x23,0x00,0x45,0x00,0x67,0x00,0x84,0x00, + 0xa3,0x00,0xba,0x00,0xd4,0x00,0xe3,0x00, + 0xf8,0x00,0xfc,0x00,0x0c,0x01,0x05,0x01, + 0x14,0x01,0xf5,0x00,0x5a,0x01,0xa7,0x01, + 0x6a,0x01,0x55,0x01,0x25,0x01,0x07,0x01, + 0xdc,0x00,0xbc,0x00,0x96,0x00,0x78,0x00, + 0x58,0x00,0x41,0x00,0x29,0x00,0x19,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x19,0x00,0x29,0x00, + 0x41,0x00,0x58,0x00,0x79,0x00,0x95,0x00, + 0xbd,0x00,0xdb,0x00,0x08,0x01,0x24,0x01, + 0x56,0x01,0x68,0x01,0xaa,0x01,0x58,0x01, + 0xf9,0x00,0x10,0x01,0x0a,0x01,0x06,0x01, + 0x04,0x01,0xef,0x00,0xed,0x00,0xc8,0x00, + 0xc8,0x00,0x91,0x00,0x9b,0x00,0x48,0x00, + 0x74,0x00,0xc5,0xff,0xeb,0x7f,0x3c,0x00, + 0x8b,0xff,0xb7,0xff,0x62,0xff,0x6b,0xff, + 0x32,0xff,0x30,0xff,0x09,0xff,0x05,0xff, + 0xee,0xfe,0xe9,0xfe,0xe3,0xfe,0xdb,0xfe, + 0xf1,0xfe,0x88,0xfe,0x28,0xfe,0x6d,0xfe, + 0x7c,0xfe,0xb1,0xfe,0xcc,0xfe,0xfc,0xfe, + 0x1b,0xff,0x46,0xff,0x64,0xff,0x89,0xff, + 0xa4,0xff,0xc1,0xff,0xd5,0xff,0xec,0xff, + 0xf9,0xff,0xfe,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x19,0x00,0x29,0x00,0x41,0x00,0x58,0x00, + 0x79,0x00,0x95,0x00,0xbd,0x00,0xdb,0x00, + 0x08,0x01,0x24,0x01,0x56,0x01,0x68,0x01, + 0xaa,0x01,0x58,0x01,0xf9,0x00,0x10,0x01, + 0x0a,0x01,0x06,0x01,0x04,0x01,0xef,0x00, + 0xed,0x00,0xc8,0x00,0xc8,0x00,0x91,0x00, + 0x9b,0x00,0x48,0x00,0x74,0x00,0xc5,0xff, + 0xeb,0x7f,0x3c,0x00,0x8b,0xff,0xb7,0xff, + 0x62,0xff,0x6b,0xff,0x32,0xff,0x30,0xff, + 0x09,0xff,0x05,0xff,0xee,0xfe,0xe9,0xfe, + 0xe3,0xfe,0xdb,0xfe,0xf1,0xfe,0x88,0xfe, + 0x28,0xfe,0x6d,0xfe,0x7c,0xfe,0xb1,0xfe, + 0xcc,0xfe,0xfc,0xfe,0x1b,0xff,0x46,0xff, + 0x64,0xff,0x89,0xff,0xa4,0xff,0xc1,0xff, + 0xd5,0xff,0xec,0xff,0xf9,0xff,0xfe,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfe,0xff,0xf9,0xff, + 0xec,0xff,0xd5,0xff,0xc1,0xff,0xa4,0xff, + 0x89,0xff,0x65,0xff,0x45,0xff,0x1c,0xff, + 0xfb,0xfe,0xcd,0xfe,0xaf,0xfe,0x7e,0xfe, + 0x6a,0xfe,0x2b,0xfe,0x84,0xfe,0xf6,0xfe, + 0xd6,0xfe,0xe9,0xfe,0xe3,0xfe,0xf6,0xfe, + 0xfc,0xfe,0x14,0xff,0x24,0xff,0x40,0xff, + 0x59,0xff,0x79,0xff,0x98,0xff,0xba,0xff, + 0xdd,0xff,0xec,0x7f,0x23,0x00,0x45,0x00, + 0x67,0x00,0x84,0x00,0xa3,0x00,0xba,0x00, + 0xd4,0x00,0xe3,0x00,0xf8,0x00,0xfc,0x00, + 0x0c,0x01,0x05,0x01,0x14,0x01,0xf5,0x00, + 0x5a,0x01,0xa7,0x01,0x6a,0x01,0x55,0x01, + 0x25,0x01,0x07,0x01,0xdc,0x00,0xbc,0x00, + 0x96,0x00,0x78,0x00,0x58,0x00,0x41,0x00, + 0x29,0x00,0x19,0x00,0x04,0x00,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x04,0x00,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00, + 0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x1e,0x00,0x00,0x00, + 0x04,0x00,0x00,0x00,0x5a,0x00,0x00,0x00, + 0x08,0x00,0x00,0x00,0x00,0x00,0x66,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x9a,0xff, + 0x00,0x00,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/tdfb/line2_50mm_pm90deg_16khz.conf b/tools/topology/topology2/include/components/tdfb/line2_50mm_pm90deg_16khz.conf new file mode 100644 index 000000000000..9547488b9d83 --- /dev/null +++ b/tools/topology/topology2/include/components/tdfb/line2_50mm_pm90deg_16khz.conf @@ -0,0 +1,93 @@ +# Created with script example_two_beams.m 23-Oct-2023 +# cd tools/tune/tdfb; matlab -nodisplay -nosplash -nodesktop -r example_two_beams +Object.Base.data."tdfb_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x9c,0x02,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x02,0x00,0x00,0x04,0x00,0x02,0x00, + 0x01,0x00,0x02,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x0f,0x00,0xa6,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfd,0xff,0xf2,0xff, + 0xe1,0xff,0xc7,0xff,0xa6,0xff,0x7a,0xff, + 0x49,0xff,0x08,0xff,0xc8,0xfe,0x72,0xfe, + 0x23,0xfe,0xba,0xfd,0x5d,0xfd,0xd1,0xfc, + 0x66,0xfc,0xc9,0xfb,0x63,0xfb,0xbc,0xfa, + 0x74,0xfa,0xca,0xf9,0xd3,0xf9,0xa2,0xf8, + 0xc2,0xf5,0x93,0xf5,0xf1,0xf5,0xac,0xf5, + 0x7f,0xf8,0xbc,0xfb,0x46,0xfc,0xa8,0xfd, + 0xba,0xfe,0xec,0x7f,0x44,0x01,0x52,0x02, + 0xab,0x03,0x2f,0x04,0x51,0x07,0x04,0x0a, + 0xb3,0x09,0xff,0x09,0xc3,0x09,0xfb,0x06, + 0xd0,0x05,0xcd,0x05,0x25,0x05,0xd8,0x04, + 0x35,0x04,0xce,0x03,0x38,0x03,0xcf,0x02, + 0x4c,0x02,0xf3,0x01,0x91,0x01,0x48,0x01, + 0xfa,0x00,0xc0,0x00,0x88,0x00,0x5e,0x00, + 0x3a,0x00,0x20,0x00,0x0e,0x00,0x03,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00, + 0x11,0x00,0x19,0x00,0x48,0x00,0x4a,0x00, + 0xa9,0x00,0x95,0x00,0x39,0x01,0xfc,0x00, + 0xf9,0x01,0x7a,0x01,0xee,0x02,0x1c,0x02, + 0x21,0x04,0xcc,0x02,0x78,0x05,0x6b,0x03, + 0xd8,0x06,0xd5,0x03,0x09,0x08,0x21,0x05, + 0x2c,0x0d,0xd7,0x05,0x50,0x0e,0xe5,0x03, + 0xe1,0x0c,0xc6,0xfa,0x1b,0x10,0x19,0xed, + 0x61,0x35,0x6c,0x69,0x00,0xe4,0x27,0x0c, + 0xad,0xf1,0xeb,0x02,0xc9,0xf0,0xaf,0xfa, + 0x84,0xf1,0xe8,0xf8,0x3b,0xf3,0x06,0xfc, + 0x3a,0xf7,0xf3,0xfb,0xa0,0xf8,0x57,0xfc, + 0x13,0xfa,0xf9,0xfc,0x76,0xfb,0xae,0xfd, + 0xb5,0xfc,0x4f,0xfe,0xb1,0xfd,0xd5,0xfe, + 0x80,0xfe,0x44,0xff,0x20,0xff,0x99,0xff, + 0x92,0xff,0xd4,0xff,0xda,0xff,0xf6,0xff, + 0xfc,0xff,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x03,0x00,0x11,0x00,0x19,0x00, + 0x48,0x00,0x4a,0x00,0xa9,0x00,0x95,0x00, + 0x39,0x01,0xfc,0x00,0xf9,0x01,0x7a,0x01, + 0xee,0x02,0x1c,0x02,0x21,0x04,0xcc,0x02, + 0x78,0x05,0x6b,0x03,0xd8,0x06,0xd5,0x03, + 0x09,0x08,0x21,0x05,0x2c,0x0d,0xd7,0x05, + 0x50,0x0e,0xe5,0x03,0xe1,0x0c,0xc6,0xfa, + 0x1b,0x10,0x19,0xed,0x61,0x35,0x6c,0x69, + 0x00,0xe4,0x27,0x0c,0xad,0xf1,0xeb,0x02, + 0xc9,0xf0,0xaf,0xfa,0x84,0xf1,0xe8,0xf8, + 0x3b,0xf3,0x06,0xfc,0x3a,0xf7,0xf3,0xfb, + 0xa0,0xf8,0x57,0xfc,0x13,0xfa,0xf9,0xfc, + 0x76,0xfb,0xae,0xfd,0xb5,0xfc,0x4f,0xfe, + 0xb1,0xfd,0xd5,0xfe,0x80,0xfe,0x44,0xff, + 0x20,0xff,0x99,0xff,0x92,0xff,0xd4,0xff, + 0xda,0xff,0xf6,0xff,0xfc,0xff,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfd,0xff,0xf2,0xff,0xe1,0xff,0xc7,0xff, + 0xa6,0xff,0x7a,0xff,0x49,0xff,0x08,0xff, + 0xc8,0xfe,0x72,0xfe,0x23,0xfe,0xba,0xfd, + 0x5d,0xfd,0xd1,0xfc,0x66,0xfc,0xc9,0xfb, + 0x63,0xfb,0xbc,0xfa,0x74,0xfa,0xca,0xf9, + 0xd3,0xf9,0xa2,0xf8,0xc2,0xf5,0x93,0xf5, + 0xf1,0xf5,0xac,0xf5,0x7f,0xf8,0xbc,0xfb, + 0x46,0xfc,0xa8,0xfd,0xba,0xfe,0xec,0x7f, + 0x44,0x01,0x52,0x02,0xab,0x03,0x2f,0x04, + 0x51,0x07,0x04,0x0a,0xb3,0x09,0xff,0x09, + 0xc3,0x09,0xfb,0x06,0xd0,0x05,0xcd,0x05, + 0x25,0x05,0xd8,0x04,0x35,0x04,0xce,0x03, + 0x38,0x03,0xcf,0x02,0x4c,0x02,0xf3,0x01, + 0x91,0x01,0x48,0x01,0xfa,0x00,0xc0,0x00, + 0x88,0x00,0x5e,0x00,0x3a,0x00,0x20,0x00, + 0x0e,0x00,0x03,0x00,0x00,0x00,0x01,0x00, + 0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00, + 0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x5a,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x9a,0xff, + 0x00,0x00,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/tdfb/line2_50mm_pm90deg_48khz.conf b/tools/topology/topology2/include/components/tdfb/line2_50mm_pm90deg_48khz.conf new file mode 100644 index 000000000000..0fc17a7bb3a6 --- /dev/null +++ b/tools/topology/topology2/include/components/tdfb/line2_50mm_pm90deg_48khz.conf @@ -0,0 +1,93 @@ +# Created with script example_two_beams.m 23-Oct-2023 +# cd tools/tune/tdfb; matlab -nodisplay -nosplash -nodesktop -r example_two_beams +Object.Base.data."tdfb_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x9c,0x02,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x02,0x00,0x00,0x04,0x00,0x02,0x00, + 0x01,0x00,0x02,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x0f,0x00,0xa6,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0xff,0xf9,0xff,0xec,0xff,0xd5,0xff, + 0xc1,0xff,0xa4,0xff,0x89,0xff,0x65,0xff, + 0x45,0xff,0x1c,0xff,0xfb,0xfe,0xcd,0xfe, + 0xaf,0xfe,0x7e,0xfe,0x6a,0xfe,0x2b,0xfe, + 0x84,0xfe,0xf6,0xfe,0xd6,0xfe,0xe9,0xfe, + 0xe3,0xfe,0xf6,0xfe,0xfc,0xfe,0x14,0xff, + 0x24,0xff,0x40,0xff,0x59,0xff,0x79,0xff, + 0x98,0xff,0xba,0xff,0xdd,0xff,0xec,0x7f, + 0x23,0x00,0x45,0x00,0x67,0x00,0x84,0x00, + 0xa3,0x00,0xba,0x00,0xd4,0x00,0xe3,0x00, + 0xf8,0x00,0xfc,0x00,0x0c,0x01,0x05,0x01, + 0x14,0x01,0xf5,0x00,0x5a,0x01,0xa7,0x01, + 0x6a,0x01,0x55,0x01,0x25,0x01,0x07,0x01, + 0xdc,0x00,0xbc,0x00,0x96,0x00,0x78,0x00, + 0x58,0x00,0x41,0x00,0x29,0x00,0x19,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x19,0x00,0x29,0x00, + 0x41,0x00,0x58,0x00,0x79,0x00,0x95,0x00, + 0xbd,0x00,0xdb,0x00,0x08,0x01,0x24,0x01, + 0x56,0x01,0x68,0x01,0xaa,0x01,0x58,0x01, + 0xf9,0x00,0x10,0x01,0x0a,0x01,0x06,0x01, + 0x04,0x01,0xef,0x00,0xed,0x00,0xc8,0x00, + 0xc8,0x00,0x91,0x00,0x9b,0x00,0x48,0x00, + 0x74,0x00,0xc5,0xff,0xeb,0x7f,0x3c,0x00, + 0x8b,0xff,0xb7,0xff,0x62,0xff,0x6b,0xff, + 0x32,0xff,0x30,0xff,0x09,0xff,0x05,0xff, + 0xee,0xfe,0xe9,0xfe,0xe3,0xfe,0xdb,0xfe, + 0xf1,0xfe,0x88,0xfe,0x28,0xfe,0x6d,0xfe, + 0x7c,0xfe,0xb1,0xfe,0xcc,0xfe,0xfc,0xfe, + 0x1b,0xff,0x46,0xff,0x64,0xff,0x89,0xff, + 0xa4,0xff,0xc1,0xff,0xd5,0xff,0xec,0xff, + 0xf9,0xff,0xfe,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x19,0x00,0x29,0x00,0x41,0x00,0x58,0x00, + 0x79,0x00,0x95,0x00,0xbd,0x00,0xdb,0x00, + 0x08,0x01,0x24,0x01,0x56,0x01,0x68,0x01, + 0xaa,0x01,0x58,0x01,0xf9,0x00,0x10,0x01, + 0x0a,0x01,0x06,0x01,0x04,0x01,0xef,0x00, + 0xed,0x00,0xc8,0x00,0xc8,0x00,0x91,0x00, + 0x9b,0x00,0x48,0x00,0x74,0x00,0xc5,0xff, + 0xeb,0x7f,0x3c,0x00,0x8b,0xff,0xb7,0xff, + 0x62,0xff,0x6b,0xff,0x32,0xff,0x30,0xff, + 0x09,0xff,0x05,0xff,0xee,0xfe,0xe9,0xfe, + 0xe3,0xfe,0xdb,0xfe,0xf1,0xfe,0x88,0xfe, + 0x28,0xfe,0x6d,0xfe,0x7c,0xfe,0xb1,0xfe, + 0xcc,0xfe,0xfc,0xfe,0x1b,0xff,0x46,0xff, + 0x64,0xff,0x89,0xff,0xa4,0xff,0xc1,0xff, + 0xd5,0xff,0xec,0xff,0xf9,0xff,0xfe,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfe,0xff,0xf9,0xff, + 0xec,0xff,0xd5,0xff,0xc1,0xff,0xa4,0xff, + 0x89,0xff,0x65,0xff,0x45,0xff,0x1c,0xff, + 0xfb,0xfe,0xcd,0xfe,0xaf,0xfe,0x7e,0xfe, + 0x6a,0xfe,0x2b,0xfe,0x84,0xfe,0xf6,0xfe, + 0xd6,0xfe,0xe9,0xfe,0xe3,0xfe,0xf6,0xfe, + 0xfc,0xfe,0x14,0xff,0x24,0xff,0x40,0xff, + 0x59,0xff,0x79,0xff,0x98,0xff,0xba,0xff, + 0xdd,0xff,0xec,0x7f,0x23,0x00,0x45,0x00, + 0x67,0x00,0x84,0x00,0xa3,0x00,0xba,0x00, + 0xd4,0x00,0xe3,0x00,0xf8,0x00,0xfc,0x00, + 0x0c,0x01,0x05,0x01,0x14,0x01,0xf5,0x00, + 0x5a,0x01,0xa7,0x01,0x6a,0x01,0x55,0x01, + 0x25,0x01,0x07,0x01,0xdc,0x00,0xbc,0x00, + 0x96,0x00,0x78,0x00,0x58,0x00,0x41,0x00, + 0x29,0x00,0x19,0x00,0x00,0x00,0x01,0x00, + 0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00, + 0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x5a,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x9a,0xff, + 0x00,0x00,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/tdfb/line2_pass.conf b/tools/topology/topology2/include/components/tdfb/line2_pass.conf new file mode 100644 index 000000000000..4e83bb50c401 --- /dev/null +++ b/tools/topology/topology2/include/components/tdfb/line2_pass.conf @@ -0,0 +1,14 @@ +# Exported with script example_pass_config.m 23-Oct-2023 +# cd tools/tune/tdfb; octave --no-window-system example_pass_config.m +Object.Base.data."tdfb_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x28,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x28,0x00,0x00,0x00,0x02,0x00,0x02,0x00, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/tdfb/line4_28mm_azm90_90_13_16khz.conf b/tools/topology/topology2/include/components/tdfb/line4_28mm_azm90_90_13_16khz.conf new file mode 100644 index 000000000000..0912b10d7410 --- /dev/null +++ b/tools/topology/topology2/include/components/tdfb/line4_28mm_azm90_90_13_16khz.conf @@ -0,0 +1,698 @@ +# Created with script example_line_array.m 23-Oct-2023 +# cd tools/tune/tdfb; octave --no-window-system example_line_array.m +Object.Base.data."tdfb_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x84,0x15,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x84,0x15,0x00,0x00,0x04,0x00,0x02,0x00, + 0x01,0x00,0x04,0x00,0x0d,0x00,0x01,0x00, + 0x00,0x00,0x0f,0x00,0xa6,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xf6,0xff,0xee,0xff,0xc8,0xff, + 0xae,0xff,0x51,0xff,0x2a,0xff,0xf8,0xfe, + 0x36,0x00,0xa3,0x00,0x23,0x02,0x96,0x03, + 0xf7,0x07,0xde,0x0c,0xaa,0x14,0xbf,0x14, + 0x1f,0x1a,0x77,0x13,0x9a,0x56,0x9e,0x19, + 0x26,0x0e,0x39,0x0a,0xbf,0x00,0xc2,0x00, + 0x04,0xfd,0xa4,0xfd,0x96,0xfc,0x7b,0xfd, + 0x20,0xfd,0xa5,0xfe,0xda,0xfe,0x14,0xff, + 0xf5,0xfe,0x21,0xff,0x42,0xff,0xa1,0xff, + 0xca,0xff,0xf2,0xff,0x00,0x00,0x00,0x00, + 0x28,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x00, + 0x7b,0x00,0x7e,0x01,0x62,0x02,0x8b,0x04, + 0x14,0x05,0xda,0x07,0x03,0x06,0xd5,0x08, + 0x11,0x01,0x3d,0xff,0xfd,0xee,0x34,0xeb, + 0x39,0xd0,0xd4,0xce,0x02,0xb6,0x00,0xca, + 0x60,0xa5,0x39,0x2e,0xe2,0x1a,0x1f,0xd6, + 0x64,0x0d,0x5f,0x03,0x8a,0x1a,0x90,0x0f, + 0x6b,0x15,0xed,0x07,0x7c,0x07,0x85,0xfd, + 0xaa,0xfe,0x90,0xfb,0x53,0xfd,0x99,0xfc, + 0x99,0xfe,0xe4,0xfe,0xc4,0xff,0xdb,0xff, + 0x03,0x00,0x00,0x00,0x28,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x02,0x00,0xdf,0xff, + 0xc2,0xff,0xf2,0xfe,0x93,0xfe,0xb1,0xfc, + 0x28,0xfd,0xa1,0xfb,0x59,0xfe,0x74,0xfd, + 0xad,0x06,0xf6,0x07,0x85,0x14,0x4e,0x10, + 0xfa,0x19,0x89,0x05,0xb5,0x0c,0x60,0xdb, + 0x14,0x0e,0xea,0x39,0x3c,0xa8,0xb9,0xc8, + 0xb7,0xb6,0x99,0xcd,0x98,0xcf,0xcd,0xe9, + 0x96,0xee,0x4e,0xfe,0xcb,0x00,0x66,0x08, + 0x10,0x06,0xa6,0x07,0x25,0x05,0x7d,0x04, + 0x6d,0x02,0x7d,0x01,0x7e,0x00,0x23,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xf1,0xff,0xcb,0xff,0x9c,0xff, + 0x4b,0xff,0x0d,0xff,0x04,0xff,0xf1,0xfe, + 0xff,0xfe,0x7f,0xfe,0x6c,0xfd,0x1b,0xfd, + 0x02,0xfd,0x0b,0xfd,0x9a,0xfd,0xa8,0xff, + 0xba,0x01,0xc7,0x07,0x60,0x10,0xc7,0x13, + 0x0d,0x57,0x2d,0x18,0xb7,0x17,0x63,0x16, + 0xc2,0x13,0x37,0x0e,0xa6,0x07,0x45,0x04, + 0xdc,0x01,0xf9,0x00,0x13,0x00,0x32,0xff, + 0x0a,0xff,0x64,0xff,0x9e,0xff,0xd0,0xff, + 0xe9,0xff,0xf7,0xff,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xf2,0xff,0xf0,0xff,0xb8,0xff, + 0xbd,0xff,0x2c,0xff,0x55,0xff,0x90,0xfe, + 0x55,0x00,0x27,0x00,0x76,0x02,0xd5,0x02, + 0x7e,0x08,0xd7,0x0a,0x35,0x16,0xbe,0x12, + 0x9d,0x1d,0x2b,0x0e,0x25,0x53,0xda,0x24, + 0x9f,0x0a,0xb3,0x0e,0x9d,0xff,0xdb,0x02, + 0xc0,0xfc,0xe5,0xfe,0x55,0xfc,0x51,0xfe, + 0xdc,0xfc,0x07,0xff,0xae,0xfe,0x48,0xff, + 0xda,0xfe,0x37,0xff,0x36,0xff,0xa7,0xff, + 0xc7,0xff,0xf2,0xff,0x00,0x00,0x00,0x00, + 0x28,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x00, + 0x79,0x00,0x7a,0x01,0x58,0x02,0x92,0x04, + 0x07,0x05,0xfa,0x07,0xed,0x05,0xf0,0x08, + 0x7e,0x01,0xf9,0xff,0x8d,0xef,0x1c,0xec, + 0x1d,0xd1,0xb1,0xcf,0xe9,0xb5,0xf8,0xc9, + 0x0f,0xa4,0x25,0x1f,0xf8,0x27,0x01,0xd1, + 0x00,0x0c,0x56,0x00,0x66,0x19,0x50,0x0e, + 0x1b,0x15,0x3e,0x07,0xc4,0x07,0x65,0xfd, + 0xf3,0xfe,0x9d,0xfb,0x87,0xfd,0xa8,0xfc, + 0xb6,0xfe,0xec,0xfe,0xcd,0xff,0xdd,0xff, + 0x04,0x00,0x00,0x00,0x28,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x03,0x00,0xe6,0xff, + 0xc9,0xff,0x0d,0xff,0xac,0xfe,0xdf,0xfc, + 0x24,0xfd,0xb8,0xfb,0x36,0xfe,0x2e,0xfd, + 0xc1,0x05,0x49,0x07,0xd6,0x12,0x09,0x10, + 0x49,0x18,0x8d,0x05,0xb7,0x0a,0xbd,0xdd, + 0x65,0x06,0x02,0x3f,0x41,0xaa,0x41,0xc7, + 0x3a,0xb7,0xca,0xcc,0x43,0xcf,0xa9,0xe8, + 0x5a,0xee,0xab,0xfd,0xbb,0x00,0xf5,0x07, + 0xfe,0x05,0x7f,0x07,0x2f,0x05,0x73,0x04, + 0x75,0x02,0x7b,0x01,0x81,0x00,0x23,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xf1,0xff,0xca,0xff,0x9a,0xff, + 0x4d,0xff,0x06,0xff,0x01,0xff,0xf1,0xfe, + 0x08,0xff,0xac,0xfe,0x9e,0xfd,0x59,0xfd, + 0x6a,0xfd,0x64,0xfd,0x2b,0xfe,0x2d,0x00, + 0xff,0x01,0x54,0x08,0xb7,0x10,0x03,0x14, + 0x51,0x57,0x79,0x18,0x10,0x18,0x9d,0x16, + 0x22,0x14,0x47,0x0e,0xa3,0x07,0x89,0x04, + 0xd2,0x01,0xf0,0x00,0x0c,0x00,0x18,0xff, + 0x05,0xff,0x5b,0xff,0x96,0xff,0xca,0xff, + 0xe4,0xff,0xf5,0xff,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfb,0xff,0xf7,0xff,0xc6,0xff,0xd8,0xff, + 0x48,0xff,0x99,0xff,0x87,0xfe,0xe5,0xff, + 0x96,0xff,0x16,0x02,0x93,0x01,0xee,0x07, + 0xc2,0x06,0xad,0x14,0x06,0x11,0x69,0x1e, + 0x68,0x0d,0x21,0x38,0x8b,0x47,0xd3,0x05, + 0x43,0x17,0xf0,0x00,0x0e,0x06,0xf8,0xfd, + 0x70,0x01,0x54,0xfc,0xd7,0xff,0x8e,0xfc, + 0x6f,0xff,0x69,0xfe,0x6d,0xff,0x6d,0xfe, + 0x0a,0xff,0xbf,0xfe,0x70,0xff,0x7a,0xff, + 0xcc,0xff,0xee,0xff,0x00,0x00,0x00,0x00, + 0x28,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x00, + 0x9f,0x00,0x4f,0x01,0xe0,0x02,0xaa,0x03, + 0xde,0x05,0x1c,0x05,0xb4,0x06,0xe1,0x02, + 0xde,0x00,0x5e,0xf4,0xcd,0xee,0xb7,0xd9, + 0x10,0xd3,0x28,0xbe,0x26,0xc7,0x1c,0xad, + 0x74,0xee,0x4d,0x46,0x5b,0xcd,0x47,0x01, + 0x78,0xfb,0x21,0x13,0x25,0x0d,0x12,0x14, + 0xea,0x06,0xf1,0x07,0xbc,0xfd,0xb2,0xfe, + 0x89,0xfb,0x18,0xfd,0x33,0xfc,0x64,0xfe, + 0xac,0xfe,0xba,0xff,0xcf,0xff,0x14,0x00, + 0x04,0x00,0x00,0x00,0x28,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x06,0x00,0xfc,0xff,0xe1,0xff, + 0x59,0xff,0xf3,0xfe,0x7e,0xfd,0x26,0xfd, + 0x13,0xfc,0xbf,0xfd,0xe5,0xfc,0xce,0x02, + 0xaa,0x05,0x61,0x0d,0x47,0x0f,0xac,0x12, + 0xf4,0x05,0xb0,0x03,0x76,0xe5,0xe9,0xf0, + 0x36,0x4a,0x18,0xb4,0xf4,0xc1,0x18,0xba, + 0x1b,0xca,0xa2,0xcf,0xda,0xe4,0x2b,0xee, + 0x68,0xfb,0xd6,0x00,0x6b,0x06,0xd9,0x05, + 0xe4,0x06,0x48,0x05,0x43,0x04,0x89,0x02, + 0x6c,0x01,0x89,0x00,0x22,0x00,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf1,0xff,0xc7,0xff,0x94,0xff,0x54,0xff, + 0xfa,0xfe,0xf1,0xfe,0xf4,0xfe,0x17,0xff, + 0x25,0xff,0x32,0xfe,0x13,0xfe,0x7b,0xfe, + 0x6f,0xfe,0xdc,0xff,0xa2,0x01,0xdb,0x02, + 0xe6,0x09,0x98,0x11,0xab,0x14,0xeb,0x57, + 0x34,0x19,0xeb,0x18,0x2c,0x17,0x15,0x15, + 0x6a,0x0e,0x9f,0x07,0x3a,0x05,0xe6,0x01, + 0xc9,0x00,0xf2,0xff,0xde,0xfe,0xfc,0xfe, + 0x42,0xff,0x82,0xff,0xb8,0xff,0xd7,0xff, + 0xf1,0xff,0xfd,0xff,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfd,0xff,0xe7,0xff,0xd7,0xff,0x86,0xff, + 0x95,0xff,0xfb,0xfe,0x4c,0xff,0x5e,0xfe, + 0xf6,0xff,0xc3,0xff,0x09,0x03,0x33,0x04, + 0x33,0x09,0x8c,0x0a,0x29,0x18,0x07,0x14, + 0x65,0x1f,0x72,0x0f,0x89,0x53,0xbe,0x27, + 0xc4,0x0b,0xc3,0x12,0x47,0x02,0xe8,0x05, + 0xfe,0x00,0xf7,0x01,0x8d,0xfe,0x34,0x00, + 0x50,0xfe,0x1c,0x00,0xd2,0xfe,0x4c,0xff, + 0xa7,0xfe,0x23,0xff,0x43,0xff,0x99,0xff, + 0xc1,0xff,0xf1,0xff,0x00,0x00,0x00,0x00, + 0x28,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x22,0x00, + 0x83,0x00,0x5d,0x01,0x4c,0x02,0x1b,0x04, + 0xd2,0x04,0x81,0x06,0xf0,0x04,0x53,0x05, + 0x96,0x00,0x40,0xfb,0xf1,0xed,0xa2,0xe4, + 0x0d,0xd1,0x7d,0xcc,0x87,0xba,0x42,0xc4, + 0x79,0xb1,0xa6,0x47,0x4c,0xf2,0x40,0xdf, + 0xb9,0xfd,0x32,0xfe,0xaf,0x0c,0xda,0x09, + 0x03,0x09,0xbb,0x01,0x1e,0x01,0x98,0xfc, + 0x31,0xfe,0x6e,0xfc,0xf6,0xfd,0x31,0xfe, + 0x8d,0xff,0xa5,0xff,0x1c,0x00,0x10,0x00, + 0x0c,0x00,0x00,0x00,0x28,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x0a,0x00,0x1d,0x00,0x09,0x00, + 0xde,0xff,0x47,0xff,0xc0,0xfe,0x4b,0xfd, + 0x27,0xfd,0xaa,0xfc,0xe9,0xfd,0x22,0xfe, + 0x97,0x03,0x8c,0x04,0x1d,0x0d,0xd0,0x08, + 0x77,0x06,0xe0,0xf6,0xd2,0xf0,0x46,0xd5, + 0x21,0x4e,0x2b,0xcf,0x72,0xb7,0x62,0xc2, + 0xef,0xc4,0xd4,0xd3,0x9a,0xde,0xb7,0xee, + 0x75,0xf7,0x12,0x01,0xd7,0x03,0x88,0x05, + 0xa9,0x05,0x48,0x05,0xd3,0x03,0x92,0x02, + 0x4b,0x01,0x93,0x00,0x20,0x00,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf0,0xff,0xc5,0xff,0x8b,0xff,0x58,0xff, + 0x07,0xff,0xca,0xfe,0xf6,0xfe,0x23,0xff, + 0x9d,0xff,0x35,0xff,0x30,0xff,0xc2,0xff, + 0x3d,0x00,0x7f,0x02,0xc3,0x03,0x8e,0x04, + 0x48,0x0c,0xb8,0x12,0x9e,0x15,0x83,0x58, + 0xdb,0x19,0xcb,0x19,0xb3,0x17,0x15,0x16, + 0x64,0x0e,0xc9,0x07,0xd7,0x05,0x82,0x02, + 0x9f,0x00,0x91,0xff,0xd1,0xfe,0xee,0xfe, + 0x2b,0xff,0x6a,0xff,0x9b,0xff,0xc7,0xff, + 0xeb,0xff,0xfb,0xff,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xf9,0xff,0xe2,0xff,0xbe,0xff, + 0x7f,0xff,0x5d,0xff,0x24,0xff,0x0e,0xff, + 0x0a,0xff,0x25,0xff,0xd5,0x00,0xb1,0x03, + 0xd1,0x05,0xc1,0x08,0x72,0x0d,0xb1,0x16, + 0x27,0x17,0x2a,0x1b,0x9d,0x17,0xbc,0x58, + 0x7f,0x19,0x70,0x12,0x59,0x10,0xf3,0x06, + 0x8b,0x06,0xff,0x04,0xdb,0x02,0xb1,0x00, + 0x60,0x00,0x32,0x00,0xb5,0xff,0x12,0xff, + 0xcf,0xfe,0xb0,0xfe,0x23,0xff,0x42,0xff, + 0x89,0xff,0xc3,0xff,0xf0,0xff,0x00,0x00, + 0x28,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00, + 0x71,0x00,0x43,0x01,0xe3,0x01,0x9e,0x03, + 0x37,0x04,0x4d,0x06,0xb3,0x04,0xc2,0x05, + 0xad,0x00,0x1c,0x00,0x6b,0xf2,0x9e,0xec, + 0x28,0xd8,0xbf,0xd7,0x38,0xbe,0xda,0xcb, + 0xf3,0xac,0x44,0xf6,0x3f,0x3f,0xe1,0xc4, + 0xe5,0xf5,0xf2,0xe9,0x1f,0x03,0x20,0xfd, + 0xdb,0x06,0xe6,0xfc,0x2e,0x00,0x00,0xfc, + 0xcb,0xff,0xe9,0xfc,0x53,0xff,0xbd,0xfe, + 0x32,0x00,0xe2,0xff,0x58,0x00,0x1c,0x00, + 0x11,0x00,0x00,0x00,0x28,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x0e,0x00,0x44,0x00,0x38,0x00, + 0x98,0x00,0xbd,0xff,0x41,0x00,0x2d,0xfe, + 0x20,0xff,0xf0,0xfb,0xb2,0xff,0xfd,0xfa, + 0x2d,0x00,0xd2,0xfb,0x73,0x07,0x44,0xfc, + 0xe2,0x03,0x20,0xe8,0xc2,0xf6,0x94,0xc2, + 0xfd,0x38,0x7f,0xff,0x9c,0xac,0x3e,0xcf, + 0x93,0xc0,0x15,0xdb,0xe7,0xda,0xd7,0xee, + 0xb7,0xf3,0x6c,0x00,0x9e,0x00,0x02,0x05, + 0xc3,0x03,0xed,0x04,0x0a,0x03,0x72,0x02, + 0x18,0x01,0x96,0x00,0x1d,0x00,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf0,0xff,0xc5,0xff,0x89,0xff,0x4b,0xff, + 0x24,0xff,0xc9,0xfe,0xca,0xfe,0x38,0xff, + 0xac,0xff,0x75,0x00,0x5b,0x00,0x02,0x01, + 0xab,0x02,0x69,0x05,0x5e,0x06,0x8a,0x07, + 0x58,0x0f,0xcc,0x13,0xb6,0x16,0xe9,0x58, + 0xf6,0x19,0xed,0x19,0xbe,0x17,0x0f,0x16, + 0x01,0x0e,0x49,0x08,0xed,0x05,0x61,0x03, + 0xed,0x00,0xed,0xfe,0x05,0xff,0xed,0xfe, + 0x20,0xff,0x4d,0xff,0x7d,0xff,0xb9,0xff, + 0xe2,0xff,0xf9,0xff,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xf6,0xff,0xdb,0xff,0xad,0xff, + 0x7b,0xff,0x36,0xff,0x34,0xff,0x30,0xff, + 0x0d,0xff,0x6c,0xff,0x79,0x01,0x0a,0x04, + 0xeb,0x05,0x0a,0x09,0x41,0x0d,0x4b,0x14, + 0x41,0x17,0x51,0x18,0x8b,0x1a,0xea,0x58, + 0xd6,0x16,0x65,0x15,0x52,0x12,0xce,0x0b, + 0x02,0x09,0x71,0x07,0xdb,0x04,0x10,0x02, + 0x1e,0x01,0xae,0x00,0x80,0xff,0xdc,0xfe, + 0x93,0xfe,0xf8,0xfe,0x02,0xff,0x49,0xff, + 0x88,0xff,0xc8,0xff,0xf1,0xff,0x00,0x00, + 0x28,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x00, + 0x64,0x00,0x1b,0x01,0x81,0x01,0xe5,0x02, + 0xcf,0x02,0x99,0x04,0x77,0x02,0xa0,0x03, + 0xd6,0xfc,0x19,0xfe,0x57,0xef,0x46,0xed, + 0xb4,0xdb,0xc7,0xdd,0x0e,0xc2,0xd6,0xd6, + 0x23,0xae,0x9f,0x35,0xfb,0x06,0xeb,0xc4, + 0x8d,0xed,0x32,0xe0,0x19,0xfa,0x68,0xf2, + 0xe1,0xfe,0x5f,0xf7,0xf6,0xfd,0xad,0xfc, + 0xab,0x00,0xb4,0xfe,0x29,0x01,0x2b,0x00, + 0x27,0x01,0x90,0x00,0xab,0x00,0x3e,0x00, + 0x18,0x00,0x00,0x00,0x28,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x17,0x00,0x3a,0x00,0xa2,0x00, + 0x81,0x00,0x0f,0x01,0x0a,0x00,0xfd,0x00, + 0x7d,0xfe,0x6e,0x00,0x61,0xfc,0x98,0xfd, + 0x0a,0xf7,0x7a,0xfe,0xff,0xf1,0xa2,0xf9, + 0x8a,0xdf,0x1d,0xed,0x7a,0xc4,0xb1,0x06, + 0x4f,0x35,0x0d,0xae,0xeb,0xd6,0x44,0xc2, + 0x54,0xde,0x30,0xdc,0xc4,0xed,0xf2,0xef, + 0x9e,0xfe,0x44,0xfd,0xff,0x03,0xc1,0x02, + 0xd1,0x04,0xf6,0x02,0xff,0x02,0x91,0x01, + 0x24,0x01,0x67,0x00,0x1f,0x00,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xf1,0xff, + 0xca,0xff,0x8d,0xff,0x4f,0xff,0x12,0xff, + 0x06,0xff,0xb0,0xfe,0xf7,0xfe,0xb1,0xff, + 0xd0,0x00,0x64,0x01,0x39,0x02,0x34,0x05, + 0x8d,0x07,0x6d,0x09,0xf0,0x0b,0xd0,0x12, + 0x1c,0x15,0xd6,0x17,0xf9,0x58,0x9a,0x19, + 0xa6,0x18,0xcc,0x16,0x26,0x14,0xd2,0x0c, + 0xe3,0x08,0x8c,0x05,0xd9,0x03,0x32,0x01, + 0x48,0xff,0xe3,0xfe,0x1c,0xff,0x1c,0xff, + 0x2c,0xff,0x71,0xff,0xa9,0xff,0xd9,0xff, + 0xf6,0xff,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xf4,0xff,0xd1,0xff,0x9c,0xff, + 0x5b,0xff,0x1d,0xff,0xee,0xfe,0xf0,0xfe, + 0xcf,0xfe,0x45,0xff,0x4e,0x00,0xbf,0x01, + 0xc5,0x03,0x4c,0x06,0x45,0x09,0x13,0x0c, + 0x42,0x11,0xe6,0x15,0x03,0x17,0x76,0x19, + 0xf4,0x58,0x21,0x18,0xba,0x16,0x96,0x14, + 0x31,0x10,0xd9,0x0a,0x61,0x08,0x57,0x05, + 0x25,0x03,0x3d,0x01,0x20,0x00,0x38,0xff, + 0xf9,0xfe,0x1a,0xff,0x32,0xff,0x61,0xff, + 0x9e,0xff,0xd1,0xff,0xf4,0xff,0x00,0x00, + 0x28,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00, + 0x5f,0x00,0xc9,0x00,0x49,0x01,0xc9,0x01, + 0x21,0x02,0x25,0x02,0x5c,0x02,0x84,0x01, + 0x5b,0xff,0x99,0xfc,0x69,0xf8,0x8a,0xf3, + 0x5d,0xed,0x0f,0xe8,0x58,0xdd,0x87,0xd4, + 0x89,0xd1,0x09,0xce,0xaa,0x4d,0xcf,0xce, + 0xfa,0xd2,0x85,0xd6,0xbf,0xdf,0x1d,0xea, + 0x54,0xef,0x33,0xf5,0xc3,0xf9,0x73,0xfd, + 0xc7,0xff,0x86,0x01,0x14,0x02,0xc7,0x01, + 0x9f,0x01,0x3b,0x01,0xc5,0x00,0x5e,0x00, + 0x19,0x00,0x00,0x00,0x28,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x18,0x00,0x5f,0x00,0xc9,0x00, + 0x49,0x01,0xc9,0x01,0x21,0x02,0x25,0x02, + 0x5c,0x02,0x84,0x01,0x5b,0xff,0x99,0xfc, + 0x69,0xf8,0x8a,0xf3,0x5d,0xed,0x0f,0xe8, + 0x58,0xdd,0x87,0xd4,0x89,0xd1,0x09,0xce, + 0xaa,0x4d,0xcf,0xce,0xfa,0xd2,0x85,0xd6, + 0xbf,0xdf,0x1d,0xea,0x54,0xef,0x33,0xf5, + 0xc3,0xf9,0x73,0xfd,0xc7,0xff,0x86,0x01, + 0x14,0x02,0xc7,0x01,0x9f,0x01,0x3b,0x01, + 0xc5,0x00,0x5e,0x00,0x19,0x00,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xff, + 0xd1,0xff,0x9c,0xff,0x5b,0xff,0x1d,0xff, + 0xee,0xfe,0xf0,0xfe,0xcf,0xfe,0x45,0xff, + 0x4e,0x00,0xbf,0x01,0xc5,0x03,0x4c,0x06, + 0x45,0x09,0x13,0x0c,0x42,0x11,0xe6,0x15, + 0x03,0x17,0x76,0x19,0xf4,0x58,0x21,0x18, + 0xba,0x16,0x96,0x14,0x31,0x10,0xd9,0x0a, + 0x61,0x08,0x57,0x05,0x25,0x03,0x3d,0x01, + 0x20,0x00,0x38,0xff,0xf9,0xfe,0x1a,0xff, + 0x32,0xff,0x61,0xff,0x9e,0xff,0xd1,0xff, + 0xf4,0xff,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xf1,0xff,0xca,0xff,0x8d,0xff, + 0x4f,0xff,0x12,0xff,0x06,0xff,0xb0,0xfe, + 0xf7,0xfe,0xb1,0xff,0xd0,0x00,0x64,0x01, + 0x39,0x02,0x34,0x05,0x8d,0x07,0x6d,0x09, + 0xf0,0x0b,0xd0,0x12,0x1c,0x15,0xd6,0x17, + 0xf9,0x58,0x9a,0x19,0xa6,0x18,0xcc,0x16, + 0x26,0x14,0xd2,0x0c,0xe3,0x08,0x8c,0x05, + 0xd9,0x03,0x32,0x01,0x48,0xff,0xe3,0xfe, + 0x1c,0xff,0x1c,0xff,0x2c,0xff,0x71,0xff, + 0xa9,0xff,0xd9,0xff,0xf6,0xff,0x00,0x00, + 0x28,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x00, + 0x3a,0x00,0xa2,0x00,0x81,0x00,0x0f,0x01, + 0x0a,0x00,0xfd,0x00,0x7d,0xfe,0x6e,0x00, + 0x61,0xfc,0x98,0xfd,0x0a,0xf7,0x7a,0xfe, + 0xff,0xf1,0xa2,0xf9,0x8a,0xdf,0x1d,0xed, + 0x7a,0xc4,0xb1,0x06,0x4f,0x35,0x0d,0xae, + 0xeb,0xd6,0x44,0xc2,0x54,0xde,0x30,0xdc, + 0xc4,0xed,0xf2,0xef,0x9e,0xfe,0x44,0xfd, + 0xff,0x03,0xc1,0x02,0xd1,0x04,0xf6,0x02, + 0xff,0x02,0x91,0x01,0x24,0x01,0x67,0x00, + 0x1f,0x00,0x00,0x00,0x28,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x1e,0x00,0x64,0x00,0x1b,0x01, + 0x81,0x01,0xe5,0x02,0xcf,0x02,0x99,0x04, + 0x77,0x02,0xa0,0x03,0xd6,0xfc,0x19,0xfe, + 0x57,0xef,0x46,0xed,0xb4,0xdb,0xc7,0xdd, + 0x0e,0xc2,0xd6,0xd6,0x23,0xae,0x9f,0x35, + 0xfb,0x06,0xeb,0xc4,0x8d,0xed,0x32,0xe0, + 0x19,0xfa,0x68,0xf2,0xe1,0xfe,0x5f,0xf7, + 0xf6,0xfd,0xad,0xfc,0xab,0x00,0xb4,0xfe, + 0x29,0x01,0x2b,0x00,0x27,0x01,0x90,0x00, + 0xab,0x00,0x3e,0x00,0x18,0x00,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xf6,0xff, + 0xdb,0xff,0xad,0xff,0x7b,0xff,0x36,0xff, + 0x34,0xff,0x30,0xff,0x0d,0xff,0x6c,0xff, + 0x79,0x01,0x0a,0x04,0xeb,0x05,0x0a,0x09, + 0x41,0x0d,0x4b,0x14,0x41,0x17,0x51,0x18, + 0x8b,0x1a,0xea,0x58,0xd6,0x16,0x65,0x15, + 0x52,0x12,0xce,0x0b,0x02,0x09,0x71,0x07, + 0xdb,0x04,0x10,0x02,0x1e,0x01,0xae,0x00, + 0x80,0xff,0xdc,0xfe,0x93,0xfe,0xf8,0xfe, + 0x02,0xff,0x49,0xff,0x88,0xff,0xc8,0xff, + 0xf1,0xff,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf0,0xff,0xc5,0xff, + 0x89,0xff,0x4b,0xff,0x24,0xff,0xc9,0xfe, + 0xca,0xfe,0x38,0xff,0xac,0xff,0x75,0x00, + 0x5b,0x00,0x02,0x01,0xab,0x02,0x69,0x05, + 0x5e,0x06,0x8a,0x07,0x58,0x0f,0xcc,0x13, + 0xb6,0x16,0xe9,0x58,0xf6,0x19,0xed,0x19, + 0xbe,0x17,0x0f,0x16,0x01,0x0e,0x49,0x08, + 0xed,0x05,0x61,0x03,0xed,0x00,0xed,0xfe, + 0x05,0xff,0xed,0xfe,0x20,0xff,0x4d,0xff, + 0x7d,0xff,0xb9,0xff,0xe2,0xff,0xf9,0xff, + 0x28,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x00, + 0x44,0x00,0x38,0x00,0x98,0x00,0xbd,0xff, + 0x41,0x00,0x2d,0xfe,0x20,0xff,0xf0,0xfb, + 0xb2,0xff,0xfd,0xfa,0x2d,0x00,0xd2,0xfb, + 0x73,0x07,0x44,0xfc,0xe2,0x03,0x20,0xe8, + 0xc2,0xf6,0x94,0xc2,0xfd,0x38,0x7f,0xff, + 0x9c,0xac,0x3e,0xcf,0x93,0xc0,0x15,0xdb, + 0xe7,0xda,0xd7,0xee,0xb7,0xf3,0x6c,0x00, + 0x9e,0x00,0x02,0x05,0xc3,0x03,0xed,0x04, + 0x0a,0x03,0x72,0x02,0x18,0x01,0x96,0x00, + 0x1d,0x00,0x00,0x00,0x28,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x20,0x00,0x71,0x00,0x43,0x01, + 0xe3,0x01,0x9e,0x03,0x37,0x04,0x4d,0x06, + 0xb3,0x04,0xc2,0x05,0xad,0x00,0x1c,0x00, + 0x6b,0xf2,0x9e,0xec,0x28,0xd8,0xbf,0xd7, + 0x38,0xbe,0xda,0xcb,0xf3,0xac,0x44,0xf6, + 0x3f,0x3f,0xe1,0xc4,0xe5,0xf5,0xf2,0xe9, + 0x1f,0x03,0x20,0xfd,0xdb,0x06,0xe6,0xfc, + 0x2e,0x00,0x00,0xfc,0xcb,0xff,0xe9,0xfc, + 0x53,0xff,0xbd,0xfe,0x32,0x00,0xe2,0xff, + 0x58,0x00,0x1c,0x00,0x11,0x00,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xf9,0xff, + 0xe2,0xff,0xbe,0xff,0x7f,0xff,0x5d,0xff, + 0x24,0xff,0x0e,0xff,0x0a,0xff,0x25,0xff, + 0xd5,0x00,0xb1,0x03,0xd1,0x05,0xc1,0x08, + 0x72,0x0d,0xb1,0x16,0x27,0x17,0x2a,0x1b, + 0x9d,0x17,0xbc,0x58,0x7f,0x19,0x70,0x12, + 0x59,0x10,0xf3,0x06,0x8b,0x06,0xff,0x04, + 0xdb,0x02,0xb1,0x00,0x60,0x00,0x32,0x00, + 0xb5,0xff,0x12,0xff,0xcf,0xfe,0xb0,0xfe, + 0x23,0xff,0x42,0xff,0x89,0xff,0xc3,0xff, + 0xf0,0xff,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf0,0xff,0xc5,0xff, + 0x8b,0xff,0x58,0xff,0x07,0xff,0xca,0xfe, + 0xf6,0xfe,0x23,0xff,0x9d,0xff,0x35,0xff, + 0x30,0xff,0xc2,0xff,0x3d,0x00,0x7f,0x02, + 0xc3,0x03,0x8e,0x04,0x48,0x0c,0xb8,0x12, + 0x9e,0x15,0x83,0x58,0xdb,0x19,0xcb,0x19, + 0xb3,0x17,0x15,0x16,0x64,0x0e,0xc9,0x07, + 0xd7,0x05,0x82,0x02,0x9f,0x00,0x91,0xff, + 0xd1,0xfe,0xee,0xfe,0x2b,0xff,0x6a,0xff, + 0x9b,0xff,0xc7,0xff,0xeb,0xff,0xfb,0xff, + 0x28,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00, + 0x1d,0x00,0x09,0x00,0xde,0xff,0x47,0xff, + 0xc0,0xfe,0x4b,0xfd,0x27,0xfd,0xaa,0xfc, + 0xe9,0xfd,0x22,0xfe,0x97,0x03,0x8c,0x04, + 0x1d,0x0d,0xd0,0x08,0x77,0x06,0xe0,0xf6, + 0xd2,0xf0,0x46,0xd5,0x21,0x4e,0x2b,0xcf, + 0x72,0xb7,0x62,0xc2,0xef,0xc4,0xd4,0xd3, + 0x9a,0xde,0xb7,0xee,0x75,0xf7,0x12,0x01, + 0xd7,0x03,0x88,0x05,0xa9,0x05,0x48,0x05, + 0xd3,0x03,0x92,0x02,0x4b,0x01,0x93,0x00, + 0x20,0x00,0x00,0x00,0x28,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x22,0x00,0x83,0x00,0x5d,0x01, + 0x4c,0x02,0x1b,0x04,0xd2,0x04,0x81,0x06, + 0xf0,0x04,0x53,0x05,0x96,0x00,0x40,0xfb, + 0xf1,0xed,0xa2,0xe4,0x0d,0xd1,0x7d,0xcc, + 0x87,0xba,0x42,0xc4,0x79,0xb1,0xa6,0x47, + 0x4c,0xf2,0x40,0xdf,0xb9,0xfd,0x32,0xfe, + 0xaf,0x0c,0xda,0x09,0x03,0x09,0xbb,0x01, + 0x1e,0x01,0x98,0xfc,0x31,0xfe,0x6e,0xfc, + 0xf6,0xfd,0x31,0xfe,0x8d,0xff,0xa5,0xff, + 0x1c,0x00,0x10,0x00,0x0c,0x00,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfd,0xff,0xe7,0xff, + 0xd7,0xff,0x86,0xff,0x95,0xff,0xfb,0xfe, + 0x4c,0xff,0x5e,0xfe,0xf6,0xff,0xc3,0xff, + 0x09,0x03,0x33,0x04,0x33,0x09,0x8c,0x0a, + 0x29,0x18,0x07,0x14,0x65,0x1f,0x72,0x0f, + 0x89,0x53,0xbe,0x27,0xc4,0x0b,0xc3,0x12, + 0x47,0x02,0xe8,0x05,0xfe,0x00,0xf7,0x01, + 0x8d,0xfe,0x34,0x00,0x50,0xfe,0x1c,0x00, + 0xd2,0xfe,0x4c,0xff,0xa7,0xfe,0x23,0xff, + 0x43,0xff,0x99,0xff,0xc1,0xff,0xf1,0xff, + 0x00,0x00,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf1,0xff,0xc7,0xff, + 0x94,0xff,0x54,0xff,0xfa,0xfe,0xf1,0xfe, + 0xf4,0xfe,0x17,0xff,0x25,0xff,0x32,0xfe, + 0x13,0xfe,0x7b,0xfe,0x6f,0xfe,0xdc,0xff, + 0xa2,0x01,0xdb,0x02,0xe6,0x09,0x98,0x11, + 0xab,0x14,0xeb,0x57,0x34,0x19,0xeb,0x18, + 0x2c,0x17,0x15,0x15,0x6a,0x0e,0x9f,0x07, + 0x3a,0x05,0xe6,0x01,0xc9,0x00,0xf2,0xff, + 0xde,0xfe,0xfc,0xfe,0x42,0xff,0x82,0xff, + 0xb8,0xff,0xd7,0xff,0xf1,0xff,0xfd,0xff, + 0x28,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00, + 0xfc,0xff,0xe1,0xff,0x59,0xff,0xf3,0xfe, + 0x7e,0xfd,0x26,0xfd,0x13,0xfc,0xbf,0xfd, + 0xe5,0xfc,0xce,0x02,0xaa,0x05,0x61,0x0d, + 0x47,0x0f,0xac,0x12,0xf4,0x05,0xb0,0x03, + 0x76,0xe5,0xe9,0xf0,0x36,0x4a,0x18,0xb4, + 0xf4,0xc1,0x18,0xba,0x1b,0xca,0xa2,0xcf, + 0xda,0xe4,0x2b,0xee,0x68,0xfb,0xd6,0x00, + 0x6b,0x06,0xd9,0x05,0xe4,0x06,0x48,0x05, + 0x43,0x04,0x89,0x02,0x6c,0x01,0x89,0x00, + 0x22,0x00,0x00,0x00,0x28,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x1f,0x00,0x9f,0x00,0x4f,0x01, + 0xe0,0x02,0xaa,0x03,0xde,0x05,0x1c,0x05, + 0xb4,0x06,0xe1,0x02,0xde,0x00,0x5e,0xf4, + 0xcd,0xee,0xb7,0xd9,0x10,0xd3,0x28,0xbe, + 0x26,0xc7,0x1c,0xad,0x74,0xee,0x4d,0x46, + 0x5b,0xcd,0x47,0x01,0x78,0xfb,0x21,0x13, + 0x25,0x0d,0x12,0x14,0xea,0x06,0xf1,0x07, + 0xbc,0xfd,0xb2,0xfe,0x89,0xfb,0x18,0xfd, + 0x33,0xfc,0x64,0xfe,0xac,0xfe,0xba,0xff, + 0xcf,0xff,0x14,0x00,0x04,0x00,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfb,0xff,0xf7,0xff, + 0xc6,0xff,0xd8,0xff,0x48,0xff,0x99,0xff, + 0x87,0xfe,0xe5,0xff,0x96,0xff,0x16,0x02, + 0x93,0x01,0xee,0x07,0xc2,0x06,0xad,0x14, + 0x06,0x11,0x69,0x1e,0x68,0x0d,0x21,0x38, + 0x8b,0x47,0xd3,0x05,0x43,0x17,0xf0,0x00, + 0x0e,0x06,0xf8,0xfd,0x70,0x01,0x54,0xfc, + 0xd7,0xff,0x8e,0xfc,0x6f,0xff,0x69,0xfe, + 0x6d,0xff,0x6d,0xfe,0x0a,0xff,0xbf,0xfe, + 0x70,0xff,0x7a,0xff,0xcc,0xff,0xee,0xff, + 0x00,0x00,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xf1,0xff, + 0xca,0xff,0x9a,0xff,0x4d,0xff,0x06,0xff, + 0x01,0xff,0xf1,0xfe,0x08,0xff,0xac,0xfe, + 0x9e,0xfd,0x59,0xfd,0x6a,0xfd,0x64,0xfd, + 0x2b,0xfe,0x2d,0x00,0xff,0x01,0x54,0x08, + 0xb7,0x10,0x03,0x14,0x51,0x57,0x79,0x18, + 0x10,0x18,0x9d,0x16,0x22,0x14,0x47,0x0e, + 0xa3,0x07,0x89,0x04,0xd2,0x01,0xf0,0x00, + 0x0c,0x00,0x18,0xff,0x05,0xff,0x5b,0xff, + 0x96,0xff,0xca,0xff,0xe4,0xff,0xf5,0xff, + 0x28,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x03,0x00,0xe6,0xff,0xc9,0xff,0x0d,0xff, + 0xac,0xfe,0xdf,0xfc,0x24,0xfd,0xb8,0xfb, + 0x36,0xfe,0x2e,0xfd,0xc1,0x05,0x49,0x07, + 0xd6,0x12,0x09,0x10,0x49,0x18,0x8d,0x05, + 0xb7,0x0a,0xbd,0xdd,0x65,0x06,0x02,0x3f, + 0x41,0xaa,0x41,0xc7,0x3a,0xb7,0xca,0xcc, + 0x43,0xcf,0xa9,0xe8,0x5a,0xee,0xab,0xfd, + 0xbb,0x00,0xf5,0x07,0xfe,0x05,0x7f,0x07, + 0x2f,0x05,0x73,0x04,0x75,0x02,0x7b,0x01, + 0x81,0x00,0x23,0x00,0x28,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x23,0x00,0x79,0x00,0x7a,0x01, + 0x58,0x02,0x92,0x04,0x07,0x05,0xfa,0x07, + 0xed,0x05,0xf0,0x08,0x7e,0x01,0xf9,0xff, + 0x8d,0xef,0x1c,0xec,0x1d,0xd1,0xb1,0xcf, + 0xe9,0xb5,0xf8,0xc9,0x0f,0xa4,0x25,0x1f, + 0xf8,0x27,0x01,0xd1,0x00,0x0c,0x56,0x00, + 0x66,0x19,0x50,0x0e,0x1b,0x15,0x3e,0x07, + 0xc4,0x07,0x65,0xfd,0xf3,0xfe,0x9d,0xfb, + 0x87,0xfd,0xa8,0xfc,0xb6,0xfe,0xec,0xfe, + 0xcd,0xff,0xdd,0xff,0x04,0x00,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xf2,0xff, + 0xf0,0xff,0xb8,0xff,0xbd,0xff,0x2c,0xff, + 0x55,0xff,0x90,0xfe,0x55,0x00,0x27,0x00, + 0x76,0x02,0xd5,0x02,0x7e,0x08,0xd7,0x0a, + 0x35,0x16,0xbe,0x12,0x9d,0x1d,0x2b,0x0e, + 0x25,0x53,0xda,0x24,0x9f,0x0a,0xb3,0x0e, + 0x9d,0xff,0xdb,0x02,0xc0,0xfc,0xe5,0xfe, + 0x55,0xfc,0x51,0xfe,0xdc,0xfc,0x07,0xff, + 0xae,0xfe,0x48,0xff,0xda,0xfe,0x37,0xff, + 0x36,0xff,0xa7,0xff,0xc7,0xff,0xf2,0xff, + 0x00,0x00,0x00,0x00,0x28,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xf1,0xff, + 0xcb,0xff,0x9c,0xff,0x4b,0xff,0x0d,0xff, + 0x04,0xff,0xf1,0xfe,0xff,0xfe,0x7f,0xfe, + 0x6c,0xfd,0x1b,0xfd,0x02,0xfd,0x0b,0xfd, + 0x9a,0xfd,0xa8,0xff,0xba,0x01,0xc7,0x07, + 0x60,0x10,0xc7,0x13,0x0d,0x57,0x2d,0x18, + 0xb7,0x17,0x63,0x16,0xc2,0x13,0x37,0x0e, + 0xa6,0x07,0x45,0x04,0xdc,0x01,0xf9,0x00, + 0x13,0x00,0x32,0xff,0x0a,0xff,0x64,0xff, + 0x9e,0xff,0xd0,0xff,0xe9,0xff,0xf7,0xff, + 0x28,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x02,0x00,0xdf,0xff,0xc2,0xff,0xf2,0xfe, + 0x93,0xfe,0xb1,0xfc,0x28,0xfd,0xa1,0xfb, + 0x59,0xfe,0x74,0xfd,0xad,0x06,0xf6,0x07, + 0x85,0x14,0x4e,0x10,0xfa,0x19,0x89,0x05, + 0xb5,0x0c,0x60,0xdb,0x14,0x0e,0xea,0x39, + 0x3c,0xa8,0xb9,0xc8,0xb7,0xb6,0x99,0xcd, + 0x98,0xcf,0xcd,0xe9,0x96,0xee,0x4e,0xfe, + 0xcb,0x00,0x66,0x08,0x10,0x06,0xa6,0x07, + 0x25,0x05,0x7d,0x04,0x6d,0x02,0x7d,0x01, + 0x7e,0x00,0x23,0x00,0x28,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x23,0x00,0x7b,0x00,0x7e,0x01, + 0x62,0x02,0x8b,0x04,0x14,0x05,0xda,0x07, + 0x03,0x06,0xd5,0x08,0x11,0x01,0x3d,0xff, + 0xfd,0xee,0x34,0xeb,0x39,0xd0,0xd4,0xce, + 0x02,0xb6,0x00,0xca,0x60,0xa5,0x39,0x2e, + 0xe2,0x1a,0x1f,0xd6,0x64,0x0d,0x5f,0x03, + 0x8a,0x1a,0x90,0x0f,0x6b,0x15,0xed,0x07, + 0x7c,0x07,0x85,0xfd,0xaa,0xfe,0x90,0xfb, + 0x53,0xfd,0x99,0xfc,0x99,0xfe,0xe4,0xfe, + 0xc4,0xff,0xdb,0xff,0x03,0x00,0x00,0x00, + 0x28,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xff,0xff,0xf6,0xff, + 0xee,0xff,0xc8,0xff,0xae,0xff,0x51,0xff, + 0x2a,0xff,0xf8,0xfe,0x36,0x00,0xa3,0x00, + 0x23,0x02,0x96,0x03,0xf7,0x07,0xde,0x0c, + 0xaa,0x14,0xbf,0x14,0x1f,0x1a,0x77,0x13, + 0x9a,0x56,0x9e,0x19,0x26,0x0e,0x39,0x0a, + 0xbf,0x00,0xc2,0x00,0x04,0xfd,0xa4,0xfd, + 0x96,0xfc,0x7b,0xfd,0x20,0xfd,0xa5,0xfe, + 0xda,0xfe,0x14,0xff,0xf5,0xfe,0x21,0xff, + 0x42,0xff,0xa1,0xff,0xca,0xff,0xf2,0xff, + 0x00,0x00,0x00,0x00,0x04,0x00,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x04,0x00,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0x02,0x00,0x03,0x00,0x03,0x00,0x03,0x00, + 0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x02,0x00,0xa6,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0xb5,0xff,0x00,0x00, + 0x04,0x00,0x00,0x00,0xc4,0xff,0x00,0x00, + 0x08,0x00,0x00,0x00,0xd3,0xff,0x00,0x00, + 0x0c,0x00,0x00,0x00,0xe2,0xff,0x00,0x00, + 0x10,0x00,0x00,0x00,0xf1,0xff,0x00,0x00, + 0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x18,0x00,0x00,0x00,0x0f,0x00,0x00,0x00, + 0x1c,0x00,0x00,0x00,0x1e,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x2d,0x00,0x00,0x00, + 0x24,0x00,0x00,0x00,0x3c,0x00,0x00,0x00, + 0x28,0x00,0x00,0x00,0x4b,0x00,0x00,0x00, + 0x2c,0x00,0x00,0x00,0x5a,0x00,0x00,0x00, + 0x30,0x00,0x00,0x00,0x00,0x00,0xac,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x39,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xc7,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x54,0xff, + 0x00,0x00,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/tdfb/line4_28mm_azm90_90_13_48khz.conf b/tools/topology/topology2/include/components/tdfb/line4_28mm_azm90_90_13_48khz.conf new file mode 100644 index 000000000000..fb13f144c246 --- /dev/null +++ b/tools/topology/topology2/include/components/tdfb/line4_28mm_azm90_90_13_48khz.conf @@ -0,0 +1,1218 @@ +# Created with script example_line_array.m 23-Oct-2023 +# cd tools/tune/tdfb; octave --no-window-system example_line_array.m +Object.Base.data."tdfb_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0xc4,0x25,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xc4,0x25,0x00,0x00,0x04,0x00,0x02,0x00, + 0x01,0x00,0x04,0x00,0x0d,0x00,0x01,0x00, + 0x00,0x00,0x0f,0x00,0xa6,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x50,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfa,0xff,0xeb,0xff,0x00,0x00,0xf1,0xff, + 0x0e,0x00,0xf3,0xff,0x28,0x00,0x01,0x00, + 0x5b,0x00,0x15,0x00,0x71,0x00,0x38,0x00, + 0xe2,0x00,0x92,0x00,0x7d,0x01,0x0f,0x01, + 0x4c,0x02,0x99,0x01,0x60,0x03,0x7d,0x03, + 0x28,0x05,0x5b,0x04,0x7b,0x06,0x35,0x05, + 0xc9,0x07,0xe6,0x05,0xba,0x08,0x90,0x05, + 0xca,0x09,0x4c,0x05,0x3e,0x0b,0xc9,0x03, + 0x4b,0x0e,0x9a,0xfc,0x99,0x41,0x38,0x1a, + 0x11,0xff,0xca,0x0b,0x8f,0x02,0xa4,0x08, + 0xef,0x02,0xaf,0x06,0x93,0x02,0xb1,0x03, + 0x32,0x00,0x3b,0x02,0xba,0xff,0x40,0x01, + 0x55,0xff,0x84,0x00,0x20,0xff,0x44,0x00, + 0xed,0xfe,0xd5,0xff,0xfc,0xfe,0xb7,0xff, + 0x1d,0xff,0xb4,0xff,0x49,0xff,0xbc,0xff, + 0x61,0xff,0xbc,0xff,0x8b,0xff,0xce,0xff, + 0xaf,0xff,0xde,0xff,0xcc,0xff,0xf4,0xff, + 0xed,0xff,0xfb,0xff,0xf7,0xff,0xfe,0xff, + 0xfe,0xff,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x50,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x04,0x00,0x0c,0x00, + 0x1e,0x00,0x2b,0x00,0x49,0x00,0x4d,0x00, + 0x84,0x00,0x7d,0x00,0xa0,0x00,0x68,0x00, + 0x7e,0x00,0x02,0x00,0x01,0x00,0x3d,0xff, + 0x35,0xff,0xf0,0xfd,0xc3,0xfd,0x0e,0xfc, + 0xd6,0xfb,0xac,0xf9,0x84,0xf9,0xda,0xf6, + 0xb5,0xf5,0x26,0xf2,0x9e,0xf2,0x0f,0xef, + 0x27,0xf0,0x47,0xec,0x54,0xee,0x14,0xea, + 0xae,0xec,0x49,0xe7,0x28,0xed,0xba,0xe6, + 0xd6,0xef,0xdc,0xe5,0x78,0xf6,0x8b,0xdd, + 0xc8,0x6a,0x09,0x0a,0x49,0xe9,0x0e,0xfd, + 0x03,0xf3,0x0d,0xfe,0xbb,0xf8,0x78,0x00, + 0x22,0xfd,0xc9,0x03,0x52,0x01,0x6c,0x05, + 0x50,0x03,0x47,0x06,0x6a,0x04,0x67,0x06, + 0xdb,0x04,0x62,0x06,0x2a,0x04,0x08,0x05, + 0x58,0x03,0xc7,0x03,0x56,0x02,0x88,0x02, + 0x5d,0x01,0x72,0x01,0x7c,0x00,0x96,0x00, + 0x00,0x00,0x19,0x00,0xbe,0xff,0xdb,0xff, + 0xaf,0xff,0xe1,0xff,0xd3,0xff,0xe7,0xff, + 0xe6,0xff,0xf4,0xff,0xf9,0xff,0xfe,0xff, + 0x00,0x00,0x00,0x00,0x50,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff, + 0xfa,0xff,0xf1,0xff,0xeb,0xff,0xde,0xff, + 0xdd,0xff,0xd1,0xff,0xc7,0xff,0xb5,0xff, + 0xde,0xff,0xdf,0xff,0x2e,0x00,0x42,0x00, + 0xbe,0x00,0xf7,0x00,0xbd,0x01,0xee,0x01, + 0xdb,0x02,0x06,0x03,0x0e,0x04,0x1b,0x04, + 0x20,0x05,0x24,0x05,0x4e,0x06,0x09,0x05, + 0x22,0x06,0x9f,0x04,0x87,0x05,0x5b,0x03, + 0x2d,0x04,0x37,0x01,0x33,0x01,0xb9,0xfc, + 0x14,0xfe,0x83,0xf8,0x17,0xfb,0x38,0xf3, + 0x8f,0xf9,0x0e,0xe9,0x5c,0x6f,0x48,0xfa, + 0x57,0xe8,0xdd,0xef,0xe5,0xe8,0xad,0xec, + 0xa4,0xe8,0x65,0xeb,0x28,0xe9,0xd5,0xec, + 0xce,0xeb,0x60,0xee,0x1a,0xee,0xa0,0xf0, + 0xec,0xf0,0x57,0xf3,0x19,0xf4,0x7b,0xf7, + 0x75,0xf8,0x41,0xfa,0xf9,0xfa,0x7c,0xfc, + 0x16,0xfd,0x40,0xfe,0xb1,0xfe,0x7c,0xff, + 0xa6,0xff,0x2a,0x00,0x40,0x00,0x82,0x00, + 0x7a,0x00,0x8d,0x00,0x73,0x00,0x59,0x00, + 0x3e,0x00,0x30,0x00,0x1b,0x00,0x0d,0x00, + 0x50,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfe,0xff,0xfc,0xff, + 0xfa,0xff,0xf7,0xff,0xf3,0xff,0xee,0xff, + 0xda,0xff,0xce,0xff,0xc2,0xff,0xb6,0xff, + 0xa7,0xff,0x9b,0xff,0x88,0xff,0x89,0xff, + 0x81,0xff,0x74,0xff,0x65,0xff,0x61,0xff, + 0x58,0xff,0x64,0xff,0x60,0xff,0xa2,0xff, + 0xc5,0xff,0xc0,0xff,0x10,0x00,0x48,0x00, + 0xa9,0x00,0xfc,0x00,0x72,0x01,0xde,0x01, + 0xe0,0x03,0xb5,0x04,0x20,0x05,0xb1,0x05, + 0x22,0x06,0xa0,0x06,0x02,0x07,0x66,0x07, + 0xa5,0x47,0xea,0x07,0x00,0x08,0x10,0x08, + 0xfe,0x07,0xe5,0x07,0xac,0x07,0x69,0x07, + 0x1f,0x07,0x3c,0x07,0xb5,0x06,0x47,0x06, + 0xab,0x05,0x37,0x05,0x8b,0x04,0x2c,0x04, + 0x28,0x03,0x19,0x02,0xef,0x01,0x7d,0x01, + 0x37,0x01,0xe6,0x00,0xac,0x00,0x76,0x00, + 0x4a,0x00,0x37,0x00,0x3d,0x00,0x21,0x00, + 0x14,0x00,0x07,0x00,0x01,0x00,0xfd,0xff, + 0xfb,0xff,0xf2,0xff,0x50,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf9,0xff,0xe0,0xff,0xf6,0xff,0xe0,0xff, + 0x1a,0x00,0xdd,0xff,0x47,0x00,0xef,0xff, + 0xa1,0x00,0x09,0x00,0xce,0x00,0x42,0x00, + 0xa1,0x01,0xe1,0x00,0xc6,0x02,0xc7,0x01, + 0x46,0x04,0xea,0x02,0x8f,0x05,0xb3,0x05, + 0x39,0x0a,0xb7,0x07,0xdd,0x0c,0x67,0x09, + 0x9a,0x0f,0xc5,0x0a,0x0b,0x12,0x1e,0x0a, + 0x38,0x14,0x88,0x09,0x88,0x17,0x72,0x06, + 0xd3,0x1d,0x16,0xfa,0x4b,0x48,0x5c,0x76, + 0xc2,0xf3,0x5f,0x1d,0x60,0x02,0x5a,0x14, + 0xb2,0x04,0x8c,0x0f,0xcd,0x04,0xf0,0x0a, + 0xde,0xff,0xf7,0x05,0x24,0xff,0xb8,0x03, + 0x68,0xfe,0x0f,0x02,0xe0,0xfd,0x86,0x01, + 0xf7,0xfd,0x16,0x00,0xda,0xfd,0xc5,0xff, + 0x13,0xfe,0xa7,0xff,0x69,0xfe,0xa9,0xff, + 0xb1,0xfe,0x8b,0xff,0xef,0xfe,0xa4,0xff, + 0x3b,0xff,0xbd,0xff,0x7a,0xff,0xe7,0xff, + 0xcc,0xff,0xf5,0xff,0xe4,0xff,0xfa,0xff, + 0xf5,0xff,0xfe,0xff,0xff,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x50,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x04,0x00,0x0b,0x00, + 0x20,0x00,0x28,0x00,0x4f,0x00,0x45,0x00, + 0x86,0x00,0x73,0x00,0xbc,0x00,0x59,0x00, + 0xab,0x00,0xed,0xff,0x44,0x00,0x23,0xff, + 0x90,0xff,0xc4,0xfd,0x3c,0xfe,0xd0,0xfb, + 0x72,0xfc,0x54,0xf9,0x47,0xfa,0x59,0xf6, + 0xec,0xf6,0x90,0xf1,0xb4,0xf3,0x2e,0xee, + 0x75,0xf1,0x0b,0xeb,0xe5,0xef,0x60,0xe8, + 0xc9,0xee,0xbc,0xe4,0x9b,0xef,0x1b,0xe3, + 0x74,0xf3,0x3c,0xe0,0xfa,0xfc,0x68,0xd2, + 0xe5,0x4b,0x90,0x37,0x1a,0xda,0xbd,0x04, + 0x64,0xec,0xc7,0x01,0x5c,0xf4,0xba,0x02, + 0xc1,0xf9,0xd2,0x04,0xdc,0xfe,0x65,0x06, + 0x50,0x01,0x02,0x07,0xcc,0x02,0x00,0x07, + 0x7a,0x03,0x28,0x07,0x61,0x03,0x60,0x05, + 0xaf,0x02,0x16,0x04,0xd8,0x01,0xcc,0x02, + 0x01,0x01,0xb2,0x01,0x52,0x00,0xc0,0x00, + 0xdc,0xff,0x3a,0x00,0xa8,0xff,0xf2,0xff, + 0xa3,0xff,0xef,0xff,0xcd,0xff,0xee,0xff, + 0xe4,0xff,0xf6,0xff,0xf8,0xff,0xff,0xff, + 0x00,0x00,0x00,0x00,0x50,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff, + 0xfa,0xff,0xf0,0xff,0xed,0xff,0xd9,0xff, + 0xe2,0xff,0xc8,0xff,0xdb,0xff,0x9d,0xff, + 0xe9,0xff,0xb9,0xff,0x3a,0x00,0x07,0x00, + 0xcd,0x00,0xac,0x00,0xc9,0x01,0x78,0x01, + 0xea,0x02,0x71,0x02,0x29,0x04,0x66,0x03, + 0x4d,0x05,0x62,0x04,0xdf,0x06,0x02,0x04, + 0x9d,0x06,0x6d,0x03,0x3e,0x06,0xf4,0x01, + 0x36,0x05,0x86,0xff,0xae,0x02,0xa6,0xfa, + 0x4d,0x00,0xad,0xf5,0x8a,0xfe,0xa9,0xee, + 0x28,0x00,0x9a,0xdd,0x2d,0x67,0xc0,0x0f, + 0x74,0xdf,0x79,0xf5,0xe3,0xe4,0xd1,0xef, + 0x16,0xe6,0x84,0xed,0x35,0xe7,0x1c,0xee, + 0x83,0xea,0x71,0xef,0x0b,0xed,0x6a,0xf1, + 0x0e,0xf0,0xe9,0xf3,0x62,0xf3,0x98,0xf7, + 0xd2,0xf7,0x8d,0xfa,0x78,0xfa,0xb0,0xfc, + 0xb0,0xfc,0x65,0xfe,0x62,0xfe,0x9e,0xff, + 0x7b,0xff,0x3b,0x00,0x1e,0x00,0x8f,0x00, + 0x64,0x00,0x96,0x00,0x64,0x00,0x5c,0x00, + 0x38,0x00,0x31,0x00,0x19,0x00,0x0e,0x00, + 0x50,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfe,0xff,0xfc,0xff, + 0xfa,0xff,0xf7,0xff,0xf3,0xff,0xf1,0xff, + 0xdf,0xff,0xd0,0xff,0xc7,0xff,0xbb,0xff, + 0xaf,0xff,0xa2,0xff,0x96,0xff,0x9a,0xff, + 0x8f,0xff,0x87,0xff,0x78,0xff,0x78,0xff, + 0x6d,0xff,0x7f,0xff,0x75,0xff,0xdc,0xff, + 0xf0,0xff,0xd9,0xff,0x2a,0x00,0x64,0x00, + 0xbf,0x00,0x1a,0x01,0x80,0x01,0x16,0x02, + 0x22,0x04,0xc1,0x04,0x40,0x05,0xc2,0x05, + 0x3d,0x06,0xb2,0x06,0x1a,0x07,0x78,0x07, + 0xba,0x47,0x00,0x08,0x1b,0x08,0x2a,0x08, + 0x19,0x08,0x01,0x08,0xc7,0x07,0x89,0x07, + 0x2d,0x07,0x4b,0x07,0xd2,0x06,0x5d,0x06, + 0xc3,0x05,0x4d,0x05,0x9e,0x04,0x43,0x04, + 0x11,0x03,0x06,0x02,0x03,0x02,0x84,0x01, + 0x45,0x01,0xec,0x00,0xb7,0x00,0x79,0x00, + 0x53,0x00,0x2b,0x00,0x37,0x00,0x23,0x00, + 0x13,0x00,0x07,0x00,0x00,0x00,0xfd,0xff, + 0xf7,0xff,0xf1,0xff,0x50,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfb,0xff,0xf2,0xff,0xf6,0xff,0xea,0xff, + 0x05,0x00,0xf7,0xff,0x17,0x00,0x09,0x00, + 0x31,0x00,0x02,0x00,0x60,0x00,0x42,0x00, + 0xc4,0x00,0xa3,0x00,0x52,0x01,0x28,0x01, + 0x0d,0x02,0xad,0x01,0x71,0x02,0xb0,0x02, + 0xfb,0x04,0x62,0x04,0x34,0x06,0x62,0x05, + 0x76,0x07,0x45,0x06,0x69,0x08,0x2e,0x06, + 0x54,0x09,0x4d,0x06,0x73,0x0a,0x95,0x05, + 0x35,0x0c,0x5d,0x02,0x6c,0x15,0x80,0x44, + 0x5a,0xfe,0x3e,0x0c,0x70,0x03,0xf8,0x08, + 0xde,0x03,0x26,0x07,0x76,0x03,0xa8,0x05, + 0x7f,0x01,0x81,0x02,0x8e,0x00,0xa0,0x01, + 0x0a,0x00,0xea,0x00,0xb6,0xff,0xcf,0x00, + 0xe8,0xff,0x2c,0x00,0x68,0xff,0xf5,0xff, + 0x72,0xff,0xe5,0xff,0x86,0xff,0xdd,0xff, + 0x99,0xff,0xda,0xff,0xa1,0xff,0xd3,0xff, + 0xb9,0xff,0xdc,0xff,0xd4,0xff,0xf9,0xff, + 0xed,0xff,0xfb,0xff,0xf5,0xff,0xfc,0xff, + 0xfb,0xff,0xff,0xff,0xff,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x50,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x04,0x00,0x0c,0x00, + 0x1d,0x00,0x28,0x00,0x46,0x00,0x46,0x00, + 0x6d,0x00,0x67,0x00,0xa5,0x00,0x56,0x00, + 0x84,0x00,0xee,0xff,0x24,0x00,0x28,0xff, + 0x36,0xff,0xc5,0xfd,0xca,0xfd,0xdb,0xfb, + 0xe7,0xfb,0x77,0xf9,0x8b,0xf9,0xe6,0xf5, + 0x5c,0xf6,0x05,0xf2,0xf8,0xf2,0xd4,0xee, + 0xa8,0xf0,0xef,0xeb,0xff,0xee,0x54,0xe9, + 0xfc,0xec,0x88,0xe6,0x9d,0xed,0x6b,0xe5, + 0xaa,0xf0,0xc3,0xe3,0x46,0xf8,0x0d,0xd9, + 0xe1,0x65,0x92,0x12,0xd1,0xe4,0x61,0xfe, + 0x55,0xf0,0x2e,0xfe,0x6f,0xf6,0x07,0x00, + 0xc5,0xfa,0x44,0x02,0x44,0xff,0x4b,0x04, + 0x58,0x01,0x1b,0x05,0x98,0x02,0x49,0x05, + 0x8a,0x03,0xef,0x05,0x52,0x03,0x19,0x04, + 0x4f,0x02,0x0a,0x03,0x80,0x01,0xfa,0x01, + 0xc9,0x00,0x1f,0x01,0x3f,0x00,0x71,0x00, + 0xc7,0xff,0x02,0x00,0xa3,0xff,0xd4,0xff, + 0xc0,0xff,0xe8,0xff,0xd0,0xff,0xea,0xff, + 0xe6,0xff,0xf6,0xff,0xf9,0xff,0xff,0xff, + 0x00,0x00,0x00,0x00,0x50,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, + 0xf8,0xff,0xf7,0xff,0xe4,0xff,0xee,0xff, + 0xcb,0xff,0xf2,0xff,0xb3,0xff,0xe2,0xff, + 0x98,0xff,0x1b,0x00,0xb6,0xff,0x99,0x00, + 0x24,0x00,0x51,0x01,0xa1,0x00,0x3b,0x02, + 0x48,0x01,0x5d,0x03,0xfe,0x01,0x80,0x04, + 0x01,0x03,0x5b,0x06,0xcb,0x02,0xcc,0x05, + 0xc7,0x01,0xbe,0x05,0x44,0x00,0x1b,0x05, + 0xcf,0xfd,0x17,0x03,0xf4,0xf8,0x82,0x01, + 0xd9,0xf3,0x94,0x00,0x46,0xec,0x46,0x03, + 0x43,0xdb,0x93,0x2f,0xf8,0x51,0x61,0xd2, + 0x4e,0xfc,0x4e,0xe0,0xf4,0xf2,0x2e,0xe3, + 0x33,0xef,0xfd,0xe4,0x4f,0xee,0x69,0xe8, + 0xf4,0xef,0x36,0xeb,0x79,0xf1,0x58,0xee, + 0xa5,0xf3,0xd2,0xf1,0x0b,0xf7,0xb8,0xf5, + 0x30,0xfa,0x48,0xf9,0x5e,0xfc,0xc0,0xfb, + 0x27,0xfe,0xb6,0xfd,0x7d,0xff,0x20,0xff, + 0x55,0x00,0xe5,0xff,0xa8,0x00,0x51,0x00, + 0xbc,0x00,0x5e,0x00,0x78,0x00,0x44,0x00, + 0x4c,0x00,0x27,0x00,0x1f,0x00,0x0b,0x00, + 0x50,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xfe,0xff,0xfd,0xff,0xfa,0xff, + 0xf9,0xff,0xf6,0xff,0xf4,0xff,0xf1,0xff, + 0xdd,0xff,0xd0,0xff,0xcb,0xff,0xc0,0xff, + 0xbe,0xff,0xc0,0xff,0xbd,0xff,0xb7,0xff, + 0xb8,0xff,0xb3,0xff,0xb3,0xff,0xb4,0xff, + 0xbc,0xff,0xe7,0xff,0x60,0x00,0x58,0x00, + 0x3e,0x00,0x67,0x00,0xbf,0x00,0xf7,0x00, + 0x77,0x01,0x9f,0x01,0xee,0x02,0x9b,0x04, + 0xf1,0x04,0x94,0x05,0xfa,0x05,0x81,0x06, + 0xe7,0x06,0x56,0x07,0xa6,0x07,0xee,0x47, + 0x2e,0x08,0x5b,0x08,0x69,0x08,0x5e,0x08, + 0x45,0x08,0x0c,0x08,0xd1,0x07,0x64,0x07, + 0x59,0x07,0x27,0x07,0x90,0x06,0x0b,0x06, + 0x7a,0x05,0xe4,0x04,0x5a,0x04,0xd9,0x02, + 0x06,0x02,0xfd,0x01,0xb3,0x01,0x5c,0x01, + 0x0c,0x01,0xca,0x00,0x8f,0x00,0x5f,0x00, + 0x38,0x00,0x18,0x00,0x1c,0x00,0x17,0x00, + 0x06,0x00,0x01,0x00,0xf9,0xff,0xee,0xff, + 0xf1,0xff,0xf5,0xff,0x50,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf4,0xff,0xf7,0xff,0xe1,0xff,0xf3,0xff, + 0xcc,0xff,0xfa,0xff,0xe8,0xff,0x3a,0x00, + 0xcd,0xff,0x7b,0x00,0x16,0x00,0x19,0x01, + 0x99,0x00,0x06,0x02,0x60,0x01,0x4b,0x03, + 0x6a,0x02,0x5e,0x04,0xfd,0x02,0x2f,0x06, + 0x78,0x04,0x93,0x0a,0xe2,0x08,0xaf,0x0d, + 0xaa,0x0a,0x9b,0x10,0xcb,0x0b,0x16,0x12, + 0xbd,0x0b,0xcd,0x14,0x38,0x0b,0xea,0x17, + 0x62,0x08,0x77,0x1d,0x25,0xfd,0x91,0x41, + 0x9a,0x7c,0xbf,0xf5,0x8f,0x1d,0x07,0x04, + 0x26,0x15,0x43,0x06,0xb4,0x10,0xfa,0x05, + 0x58,0x0d,0x2a,0x04,0xba,0x06,0xff,0x00, + 0xde,0x04,0x4f,0x00,0x5c,0x03,0x5f,0x00, + 0x3d,0x03,0x32,0x00,0x54,0x02,0x7f,0xff, + 0xf8,0x00,0x55,0xff,0x99,0x00,0x56,0xff, + 0x55,0x00,0x64,0xff,0x24,0x00,0x7a,0xff, + 0x04,0x00,0x7c,0xff,0x06,0x00,0xd0,0xff, + 0x07,0x00,0xdd,0xff,0xfe,0xff,0xe9,0xff, + 0xfb,0xff,0xf5,0xff,0xfd,0xff,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x50,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x04,0x00,0x0a,0x00, + 0x1d,0x00,0x22,0x00,0x47,0x00,0x39,0x00, + 0x71,0x00,0x3b,0x00,0x8e,0x00,0x43,0x00, + 0xa7,0x00,0xea,0xff,0x47,0x00,0x09,0xff, + 0x74,0xff,0xa5,0xfd,0x2e,0xfe,0xb7,0xfb, + 0x79,0xfc,0x35,0xf9,0xb0,0xf9,0xc9,0xf5, + 0x67,0xf7,0x93,0xf2,0x30,0xf4,0xa8,0xee, + 0x23,0xf2,0x97,0xeb,0xc5,0xf0,0x47,0xe8, + 0xea,0xee,0x5e,0xe5,0xce,0xef,0xfc,0xe2, + 0x41,0xf3,0xdb,0xdf,0x9d,0xfc,0x24,0xd2, + 0x5c,0x45,0x06,0x3d,0xc5,0xd7,0xb9,0x03, + 0x48,0xea,0xe9,0xff,0xee,0xf1,0x29,0x00, + 0xe0,0xf6,0x24,0x01,0x06,0xfb,0x73,0x03, + 0xfa,0xfd,0x02,0x04,0xa9,0xff,0x37,0x04, + 0x59,0x01,0xb8,0x04,0x99,0x01,0xf0,0x03, + 0xbf,0x00,0x59,0x02,0x4e,0x00,0x8c,0x01, + 0xf6,0xff,0xde,0x00,0xb4,0xff,0x5f,0x00, + 0x93,0xff,0x09,0x00,0x7c,0xff,0xff,0xff, + 0xb7,0xff,0xf1,0xff,0xce,0xff,0xf2,0xff, + 0xe7,0xff,0xfa,0xff,0xfa,0xff,0xff,0xff, + 0x00,0x00,0x00,0x00,0x50,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xff,0xff,0xfc,0xff, + 0xf3,0xff,0xf2,0xff,0xdd,0xff,0xe7,0xff, + 0xc4,0xff,0xe3,0xff,0xb6,0xff,0xe2,0xff, + 0x76,0xff,0x01,0x00,0xa3,0xff,0x55,0x00, + 0xd9,0xff,0xd4,0x00,0x34,0x00,0x7f,0x01, + 0xa4,0x00,0x3e,0x02,0x53,0x01,0xe6,0x03, + 0x06,0x02,0x7b,0x04,0x9a,0x01,0x88,0x03, + 0x25,0x00,0x17,0x03,0x7d,0xfe,0x24,0x02, + 0x28,0xfb,0x80,0xff,0x94,0xf7,0xfd,0xfd, + 0x0f,0xf3,0xf8,0xfc,0x50,0xec,0x93,0xff, + 0x0a,0xdb,0x20,0x64,0x2d,0x13,0x84,0xdd, + 0x02,0xf6,0xf6,0xe3,0x17,0xf0,0xb3,0xe5, + 0x23,0xee,0x98,0xe7,0x1b,0xee,0x95,0xea, + 0x6e,0xf0,0x6d,0xed,0x36,0xf2,0x54,0xf0, + 0xb0,0xf4,0x4b,0xf4,0xb6,0xf7,0x23,0xf7, + 0x30,0xfa,0x74,0xfa,0xb6,0xfc,0x9c,0xfc, + 0x5c,0xfe,0x48,0xfe,0x8a,0xff,0x70,0xff, + 0x43,0x00,0x1e,0x00,0x8c,0x00,0x4f,0x00, + 0x6b,0x00,0x40,0x00,0x53,0x00,0x30,0x00, + 0x2d,0x00,0x16,0x00,0x0d,0x00,0x03,0x00, + 0x50,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, + 0xfe,0xff,0xfd,0xff,0xfb,0xff,0xfa,0xff, + 0xf9,0xff,0xfa,0xff,0xf8,0xff,0xfb,0xff, + 0xe9,0xff,0xdd,0xff,0xe9,0xff,0xe6,0xff, + 0xeb,0xff,0xed,0xff,0xf3,0xff,0xf9,0xff, + 0x03,0x00,0x12,0x00,0x1a,0x00,0x5e,0x00, + 0xb4,0x00,0xbf,0x00,0x08,0x01,0xea,0x00, + 0xec,0x00,0x33,0x01,0x7e,0x01,0xc7,0x01, + 0x55,0x02,0x42,0x04,0xdd,0x04,0x60,0x05, + 0xe9,0x05,0x64,0x06,0xd4,0x06,0x38,0x07, + 0x95,0x07,0xe2,0x07,0x23,0x48,0x5f,0x08, + 0x8b,0x08,0x9d,0x08,0xa4,0x08,0x83,0x08, + 0x59,0x08,0x0b,0x08,0xbe,0x07,0x50,0x07, + 0x5e,0x07,0xe0,0x06,0x5a,0x06,0xae,0x05, + 0x3d,0x05,0x07,0x04,0xab,0x02,0x6c,0x02, + 0xdd,0x01,0xb6,0x01,0x86,0x01,0x34,0x01, + 0xe8,0x00,0xad,0x00,0x75,0x00,0x4e,0x00, + 0x28,0x00,0x11,0x00,0xfb,0xff,0x09,0x00, + 0xfb,0xff,0xeb,0xff,0xee,0xff,0xf0,0xff, + 0xf5,0xff,0xf8,0xff,0x50,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0xff,0xfd,0xff,0xf8,0xff,0xf9,0xff, + 0xf0,0xff,0xf9,0xff,0xe6,0xff,0xeb,0xff, + 0xe0,0xff,0x19,0x00,0x19,0x00,0x56,0x00, + 0x55,0x00,0xb3,0x00,0xb2,0x00,0x37,0x01, + 0x2e,0x01,0x98,0x01,0x89,0x01,0x63,0x02, + 0x44,0x02,0x57,0x03,0x0c,0x03,0x33,0x05, + 0x99,0x05,0xdd,0x06,0x8c,0x06,0xc2,0x07, + 0xb2,0x06,0xa9,0x08,0x31,0x07,0x92,0x09, + 0x28,0x07,0x71,0x0a,0x46,0x06,0x2c,0x0c, + 0xb8,0x01,0xb9,0x46,0xd8,0x10,0xc8,0x03, + 0x32,0x0a,0x42,0x05,0x4f,0x08,0x13,0x05, + 0xea,0x06,0x7a,0x04,0xb8,0x05,0xa8,0x03, + 0x19,0x03,0x99,0x01,0x4b,0x02,0x39,0x01, + 0x2a,0x02,0x48,0x01,0xaf,0x01,0xf9,0x00, + 0x41,0x01,0xb1,0x00,0xb2,0x00,0x25,0x00, + 0x62,0x00,0x0c,0x00,0x38,0x00,0xf9,0xff, + 0x19,0x00,0xec,0xff,0x1b,0x00,0x04,0x00, + 0x0b,0x00,0xf5,0xff,0xff,0xff,0xf6,0xff, + 0xfc,0xff,0xf9,0xff,0xfd,0xff,0xfe,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x50,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00, + 0x09,0x00,0x16,0x00,0x1f,0x00,0x32,0x00, + 0x35,0x00,0x48,0x00,0x3c,0x00,0x51,0x00, + 0x1b,0x00,0x4a,0x00,0xeb,0xff,0xd0,0xff, + 0x24,0xff,0xec,0xfe,0xf0,0xfd,0xa0,0xfd, + 0x34,0xfc,0x44,0xfb,0x9b,0xf9,0x20,0xf9, + 0x32,0xf7,0xd4,0xf6,0xb1,0xf4,0xeb,0xf3, + 0x1d,0xf1,0x83,0xf1,0xcf,0xee,0x03,0xef, + 0x97,0xeb,0xa0,0xed,0x16,0xea,0x69,0xed, + 0x23,0xe9,0xa7,0xee,0x5c,0xe8,0x09,0xf3, + 0xed,0xe2,0x4b,0x6d,0x41,0xfe,0x71,0xeb, + 0x74,0xf7,0x8f,0xf1,0x52,0xf8,0x30,0xf5, + 0xfe,0xf9,0x22,0xf8,0xc4,0xfb,0xb3,0xfa, + 0x72,0xfe,0x67,0xfd,0x7a,0xff,0xbf,0xfe, + 0x0f,0x01,0x23,0x00,0x30,0x01,0x58,0x00, + 0x0e,0x01,0x67,0x00,0x72,0x00,0x9b,0xff, + 0x09,0x00,0x87,0xff,0xd4,0xff,0x7d,0xff, + 0xba,0xff,0x85,0xff,0xe8,0xff,0xcf,0xff, + 0xe5,0xff,0xcc,0xff,0xe6,0xff,0xe1,0xff, + 0xf1,0xff,0xf2,0xff,0xfb,0xff,0xfd,0xff, + 0x00,0x00,0x00,0x00,0x50,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xff,0xff,0xfe,0xff, + 0xf9,0xff,0xf5,0xff,0xeb,0xff,0xe7,0xff, + 0xd8,0xff,0xd8,0xff,0xcc,0xff,0xe2,0xff, + 0xc6,0xff,0xa7,0xff,0x82,0xff,0xaa,0xff, + 0x88,0xff,0xc5,0xff,0xa2,0xff,0xf1,0xff, + 0xdc,0xff,0xce,0x00,0x71,0x00,0xe6,0x00, + 0x68,0x00,0xdc,0x00,0x21,0x00,0xda,0xff, + 0x3c,0xfe,0xb2,0xfe,0xea,0xfc,0x68,0xfc, + 0xc9,0xf9,0x62,0xfa,0x57,0xf7,0x57,0xf8, + 0x7d,0xf4,0x74,0xf6,0xe5,0xf0,0x7d,0xf5, + 0xae,0xe9,0xab,0x6e,0xed,0xf5,0x87,0xe9, + 0xc6,0xee,0xf7,0xe9,0xe2,0xec,0x5f,0xea, + 0xa7,0xec,0x6e,0xeb,0x80,0xed,0x3c,0xed, + 0x2e,0xf0,0x47,0xf0,0x37,0xf2,0xed,0xf2, + 0x8c,0xf5,0x12,0xf6,0xdf,0xf7,0x88,0xf8, + 0x23,0xfa,0xcc,0xfa,0x91,0xfc,0x4e,0xfd, + 0x3d,0xfe,0xb0,0xfe,0x5d,0xff,0xa6,0xff, + 0x13,0x00,0x34,0x00,0x3e,0x00,0x3e,0x00, + 0x51,0x00,0x3f,0x00,0x40,0x00,0x2e,0x00, + 0x24,0x00,0x15,0x00,0x0b,0x00,0x03,0x00, + 0x50,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xff,0xff,0xfe,0xff, + 0xfd,0xff,0xfb,0xff,0xfb,0xff,0xfa,0xff, + 0xfc,0xff,0xfc,0xff,0x05,0x00,0x0f,0x00, + 0x15,0x00,0x02,0x00,0x09,0x00,0x13,0x00, + 0x22,0x00,0x30,0x00,0x45,0x00,0x54,0x00, + 0x83,0x00,0xe8,0x00,0x10,0x01,0x40,0x01, + 0x6e,0x01,0x9f,0x01,0xdd,0x01,0xc5,0x01, + 0xcf,0x01,0x30,0x02,0x6a,0x02,0x31,0x04, + 0xfe,0x04,0x58,0x05,0xe2,0x05,0x4d,0x06, + 0xca,0x06,0x2e,0x07,0x90,0x07,0xd5,0x07, + 0x1f,0x08,0x46,0x48,0x7f,0x08,0x94,0x08, + 0xa8,0x08,0x9d,0x08,0x8f,0x08,0x5f,0x08, + 0x29,0x08,0xca,0x07,0x6d,0x07,0xff,0x06, + 0x08,0x07,0x64,0x06,0xfa,0x05,0xf6,0x04, + 0x66,0x03,0x02,0x03,0x85,0x02,0x20,0x02, + 0xbc,0x01,0x5f,0x01,0x46,0x01,0x12,0x01, + 0xca,0x00,0x96,0x00,0x66,0x00,0x41,0x00, + 0x23,0x00,0x0c,0x00,0xe9,0xff,0xe0,0xff, + 0xe9,0xff,0xf3,0xff,0xf2,0xff,0xf6,0xff, + 0xf8,0xff,0xfc,0xff,0x50,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0xff,0xfc,0xff,0xfc,0xff, + 0xf6,0xff,0xf1,0xff,0xef,0xff,0xf3,0xff, + 0xf4,0xff,0x03,0x00,0x08,0x00,0x2c,0x00, + 0x5f,0x00,0x91,0x00,0xb5,0x00,0xf4,0x00, + 0xe9,0x00,0x46,0x01,0x78,0x01,0xf3,0x01, + 0x2b,0x02,0xbe,0x02,0xf4,0x02,0x9e,0x03, + 0xc9,0x03,0xb1,0x05,0x3c,0x06,0x96,0x06, + 0x86,0x06,0x6a,0x07,0x34,0x07,0x24,0x08, + 0xa3,0x07,0xc3,0x08,0xc1,0x07,0x5e,0x09, + 0x28,0x07,0x44,0x0b,0x2d,0x48,0xa4,0x05, + 0x68,0x09,0xe8,0x06,0x2b,0x08,0x9f,0x06, + 0x43,0x07,0x0e,0x06,0x68,0x06,0x59,0x05, + 0x99,0x05,0x3f,0x04,0x01,0x03,0x9a,0x02, + 0xf5,0x02,0x72,0x02,0x5f,0x02,0xe5,0x01, + 0xce,0x01,0x6a,0x01,0x54,0x01,0x02,0x01, + 0xe9,0x00,0x70,0x00,0x5e,0x00,0x35,0x00, + 0x2a,0x00,0x2e,0x00,0x2e,0x00,0x13,0x00, + 0x10,0x00,0x01,0x00,0x00,0x00,0xf9,0xff, + 0xf9,0xff,0xf6,0xff,0xfa,0xff,0xfb,0xff, + 0xfe,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0x50,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00, + 0x07,0x00,0x0f,0x00,0x17,0x00,0x21,0x00, + 0x2c,0x00,0x2b,0x00,0x29,0x00,0x18,0x00, + 0x03,0x00,0xd4,0xff,0xb0,0xff,0xa6,0xff, + 0x4c,0xff,0xe1,0xfe,0x4c,0xfe,0x3e,0xfd, + 0x91,0xfc,0xb7,0xfb,0xe7,0xfa,0xec,0xf9, + 0x04,0xf9,0xf4,0xf7,0x04,0xf7,0xf1,0xf5, + 0x39,0xf4,0x00,0xf3,0x6c,0xf1,0x05,0xf0, + 0x8f,0xef,0xaa,0xee,0x83,0xee,0xd2,0xed, + 0x07,0xee,0x78,0xed,0x24,0xee,0x7c,0xed, + 0x9b,0xef,0x31,0x6f,0x1d,0xef,0x5e,0xf1, + 0x69,0xf1,0xc1,0xf2,0x49,0xf3,0x79,0xf4, + 0x2f,0xf5,0x3a,0xf6,0x03,0xf7,0xdf,0xf7, + 0xff,0xf8,0x91,0xfa,0x3a,0xfb,0xba,0xfc, + 0xf9,0xfc,0x89,0xfd,0xd0,0xfd,0x41,0xfe, + 0x78,0xfe,0xcc,0xfe,0xf5,0xfe,0x2e,0xff, + 0xd9,0xfe,0xf1,0xfe,0x15,0xff,0x3b,0xff, + 0x9f,0xff,0xc3,0xff,0xce,0xff,0xdf,0xff, + 0xe9,0xff,0xf3,0xff,0xfa,0xff,0xfb,0xff, + 0xfc,0xff,0x00,0x00,0x01,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x50,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0xff,0xfa,0xff,0xf8,0xff,0xf6,0xff, + 0xef,0xff,0xe3,0xff,0xd8,0xff,0xc5,0xff, + 0xba,0xff,0x8f,0xff,0x2b,0xff,0x0a,0xff, + 0xe0,0xfe,0xca,0xfe,0x19,0xff,0xe2,0xfe, + 0xb3,0xfe,0x63,0xfe,0x23,0xfe,0xb8,0xfd, + 0x67,0xfd,0xe0,0xfc,0x93,0xfc,0x23,0xfb, + 0x5c,0xfa,0xb7,0xf8,0xbe,0xf7,0xde,0xf6, + 0x12,0xf6,0x0e,0xf5,0x4f,0xf4,0x2d,0xf3, + 0x95,0xf2,0x58,0xf1,0x28,0xf1,0x2a,0xef, + 0x19,0x6f,0x57,0xef,0x83,0xed,0x0b,0xee, + 0x7c,0xed,0xfc,0xed,0xda,0xed,0x84,0xee, + 0xb7,0xee,0x9b,0xef,0x18,0xf0,0x82,0xf1, + 0x15,0xf3,0x71,0xf4,0x20,0xf6,0x18,0xf7, + 0x18,0xf8,0x1e,0xf9,0x0f,0xfa,0x01,0xfb, + 0xd8,0xfb,0xa8,0xfc,0x5f,0xfd,0x6a,0xfe, + 0xf7,0xfe,0x60,0xff,0xb7,0xff,0xbf,0xff, + 0xe2,0xff,0x0d,0x00,0x21,0x00,0x30,0x00, + 0x31,0x00,0x2f,0x00,0x23,0x00,0x19,0x00, + 0x0f,0x00,0x08,0x00,0x02,0x00,0x00,0x00, + 0x50,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xfe,0xff,0xfc,0xff,0xfa,0xff, + 0xf8,0xff,0xf9,0xff,0xfd,0xff,0x01,0x00, + 0x08,0x00,0x11,0x00,0x1d,0x00,0x2e,0x00, + 0x3c,0x00,0x2c,0x00,0x46,0x00,0x5e,0x00, + 0x88,0x00,0xea,0x00,0x1c,0x01,0x51,0x01, + 0x8a,0x01,0xc8,0x01,0x0c,0x02,0x55,0x02, + 0x9f,0x02,0xe8,0x02,0xde,0x02,0xe6,0x02, + 0x95,0x04,0x69,0x05,0xaf,0x05,0x27,0x06, + 0x79,0x06,0xe2,0x06,0x31,0x07,0x8d,0x07, + 0xd2,0x07,0x1e,0x08,0x42,0x08,0x61,0x48, + 0x75,0x08,0x85,0x08,0x75,0x08,0x65,0x08, + 0x36,0x08,0x08,0x08,0xbd,0x07,0x77,0x07, + 0x17,0x07,0xb5,0x06,0x43,0x06,0x54,0x06, + 0x6e,0x05,0xd2,0x03,0x71,0x03,0xfb,0x02, + 0x97,0x02,0x2d,0x02,0xd1,0x01,0x77,0x01, + 0x2b,0x01,0xe6,0x00,0xdc,0x00,0xb3,0x00, + 0x80,0x00,0x5c,0x00,0x1f,0x00,0x06,0x00, + 0xfa,0xff,0xf2,0xff,0xee,0xff,0xee,0xff, + 0xee,0xff,0xf6,0xff,0xfb,0xff,0xfc,0xff, + 0xfe,0xff,0xff,0xff,0x50,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0xff,0xfe,0xff,0xfc,0xff, + 0xf8,0xff,0xf7,0xff,0xf4,0xff,0xf7,0xff, + 0xf7,0xff,0x00,0x00,0x05,0x00,0x17,0x00, + 0x23,0x00,0x41,0x00,0x55,0x00,0x82,0x00, + 0xa2,0x00,0xdf,0x00,0x0b,0x01,0x5a,0x01, + 0x90,0x01,0xf0,0x01,0x2c,0x02,0x9b,0x02, + 0xdb,0x02,0x57,0x03,0x97,0x03,0x1f,0x04, + 0x32,0x05,0x02,0x06,0x18,0x06,0xc6,0x06, + 0xc8,0x06,0x7b,0x07,0x53,0x07,0x1a,0x08, + 0xab,0x07,0xae,0x08,0x9b,0x07,0xdb,0x09, + 0x58,0x48,0x04,0x07,0xed,0x08,0xa8,0x07, + 0x37,0x08,0x68,0x07,0x93,0x07,0xe8,0x06, + 0xdb,0x06,0x42,0x06,0x0d,0x06,0x8c,0x05, + 0xfe,0x04,0xa9,0x03,0x82,0x03,0xf6,0x02, + 0xbe,0x02,0x47,0x02,0x0d,0x02,0xa8,0x01, + 0x73,0x01,0x20,0x01,0xf3,0x00,0xb2,0x00, + 0x8d,0x00,0x5e,0x00,0x4a,0x00,0x2a,0x00, + 0x1d,0x00,0x0a,0x00,0x03,0x00,0xfa,0xff, + 0xf8,0xff,0xf6,0xff,0xf7,0xff,0xf9,0xff, + 0xfb,0xff,0xfe,0xff,0x00,0x00,0x00,0x00, + 0x50,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0x03,0x00,0x08,0x00,0x10,0x00,0x13,0x00, + 0x16,0x00,0x15,0x00,0x10,0x00,0x04,0x00, + 0xf3,0xff,0xd7,0xff,0xb5,0xff,0x86,0xff, + 0x4f,0xff,0x06,0xff,0xb3,0xfe,0x51,0xfe, + 0xdd,0xfd,0x5e,0xfd,0xd0,0xfc,0x38,0xfc, + 0x92,0xfb,0xe8,0xfa,0x2d,0xfa,0x77,0xf9, + 0xac,0xf8,0xf4,0xf7,0x76,0xf5,0x32,0xf4, + 0x95,0xf3,0xbc,0xf2,0x21,0xf2,0x6b,0xf1, + 0xe9,0xf0,0x58,0xf0,0xfb,0xef,0x94,0xef, + 0x62,0xef,0x28,0xef,0x1c,0x6f,0x3b,0xef, + 0x85,0xef,0xc6,0xef,0x3e,0xf0,0xa7,0xf0, + 0x48,0xf1,0xd2,0xf1,0x97,0xf2,0x35,0xf3, + 0x1e,0xf4,0xb3,0xf4,0x26,0xf6,0x7f,0xf8, + 0x20,0xf9,0xf2,0xf9,0x9e,0xfa,0x58,0xfb, + 0xfa,0xfb,0x9a,0xfc,0x29,0xfd,0xaf,0xfd, + 0x26,0xfe,0x8f,0xfe,0xee,0xfe,0x3b,0xff, + 0x73,0xff,0xa5,0xff,0xcb,0xff,0xe8,0xff, + 0xfd,0xff,0x0a,0x00,0x11,0x00,0x13,0x00, + 0x12,0x00,0x0e,0x00,0x0a,0x00,0x04,0x00, + 0x01,0x00,0x00,0x00,0x50,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x01,0x00,0x03,0x00,0x08,0x00, + 0x10,0x00,0x13,0x00,0x16,0x00,0x15,0x00, + 0x10,0x00,0x04,0x00,0xf3,0xff,0xd7,0xff, + 0xb5,0xff,0x86,0xff,0x4f,0xff,0x06,0xff, + 0xb3,0xfe,0x51,0xfe,0xdd,0xfd,0x5e,0xfd, + 0xd0,0xfc,0x38,0xfc,0x92,0xfb,0xe8,0xfa, + 0x2d,0xfa,0x77,0xf9,0xac,0xf8,0xf4,0xf7, + 0x76,0xf5,0x32,0xf4,0x95,0xf3,0xbc,0xf2, + 0x21,0xf2,0x6b,0xf1,0xe9,0xf0,0x58,0xf0, + 0xfb,0xef,0x94,0xef,0x62,0xef,0x28,0xef, + 0x1c,0x6f,0x3b,0xef,0x85,0xef,0xc6,0xef, + 0x3e,0xf0,0xa7,0xf0,0x48,0xf1,0xd2,0xf1, + 0x97,0xf2,0x35,0xf3,0x1e,0xf4,0xb3,0xf4, + 0x26,0xf6,0x7f,0xf8,0x20,0xf9,0xf2,0xf9, + 0x9e,0xfa,0x58,0xfb,0xfa,0xfb,0x9a,0xfc, + 0x29,0xfd,0xaf,0xfd,0x26,0xfe,0x8f,0xfe, + 0xee,0xfe,0x3b,0xff,0x73,0xff,0xa5,0xff, + 0xcb,0xff,0xe8,0xff,0xfd,0xff,0x0a,0x00, + 0x11,0x00,0x13,0x00,0x12,0x00,0x0e,0x00, + 0x0a,0x00,0x04,0x00,0x01,0x00,0x00,0x00, + 0x50,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, + 0xfe,0xff,0xfc,0xff,0xf8,0xff,0xf7,0xff, + 0xf4,0xff,0xf7,0xff,0xf7,0xff,0x00,0x00, + 0x05,0x00,0x17,0x00,0x23,0x00,0x41,0x00, + 0x55,0x00,0x82,0x00,0xa2,0x00,0xdf,0x00, + 0x0b,0x01,0x5a,0x01,0x90,0x01,0xf0,0x01, + 0x2c,0x02,0x9b,0x02,0xdb,0x02,0x57,0x03, + 0x97,0x03,0x1f,0x04,0x32,0x05,0x02,0x06, + 0x18,0x06,0xc6,0x06,0xc8,0x06,0x7b,0x07, + 0x53,0x07,0x1a,0x08,0xab,0x07,0xae,0x08, + 0x9b,0x07,0xdb,0x09,0x58,0x48,0x04,0x07, + 0xed,0x08,0xa8,0x07,0x37,0x08,0x68,0x07, + 0x93,0x07,0xe8,0x06,0xdb,0x06,0x42,0x06, + 0x0d,0x06,0x8c,0x05,0xfe,0x04,0xa9,0x03, + 0x82,0x03,0xf6,0x02,0xbe,0x02,0x47,0x02, + 0x0d,0x02,0xa8,0x01,0x73,0x01,0x20,0x01, + 0xf3,0x00,0xb2,0x00,0x8d,0x00,0x5e,0x00, + 0x4a,0x00,0x2a,0x00,0x1d,0x00,0x0a,0x00, + 0x03,0x00,0xfa,0xff,0xf8,0xff,0xf6,0xff, + 0xf7,0xff,0xf9,0xff,0xfb,0xff,0xfe,0xff, + 0x00,0x00,0x00,0x00,0x50,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xff,0xff,0xfe,0xff, + 0xfc,0xff,0xfa,0xff,0xf8,0xff,0xf9,0xff, + 0xfd,0xff,0x01,0x00,0x08,0x00,0x11,0x00, + 0x1d,0x00,0x2e,0x00,0x3c,0x00,0x2c,0x00, + 0x46,0x00,0x5e,0x00,0x88,0x00,0xea,0x00, + 0x1c,0x01,0x51,0x01,0x8a,0x01,0xc8,0x01, + 0x0c,0x02,0x55,0x02,0x9f,0x02,0xe8,0x02, + 0xde,0x02,0xe6,0x02,0x95,0x04,0x69,0x05, + 0xaf,0x05,0x27,0x06,0x79,0x06,0xe2,0x06, + 0x31,0x07,0x8d,0x07,0xd2,0x07,0x1e,0x08, + 0x42,0x08,0x61,0x48,0x75,0x08,0x85,0x08, + 0x75,0x08,0x65,0x08,0x36,0x08,0x08,0x08, + 0xbd,0x07,0x77,0x07,0x17,0x07,0xb5,0x06, + 0x43,0x06,0x54,0x06,0x6e,0x05,0xd2,0x03, + 0x71,0x03,0xfb,0x02,0x97,0x02,0x2d,0x02, + 0xd1,0x01,0x77,0x01,0x2b,0x01,0xe6,0x00, + 0xdc,0x00,0xb3,0x00,0x80,0x00,0x5c,0x00, + 0x1f,0x00,0x06,0x00,0xfa,0xff,0xf2,0xff, + 0xee,0xff,0xee,0xff,0xee,0xff,0xf6,0xff, + 0xfb,0xff,0xfc,0xff,0xfe,0xff,0xff,0xff, + 0x50,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfe,0xff,0xfa,0xff, + 0xf8,0xff,0xf6,0xff,0xef,0xff,0xe3,0xff, + 0xd8,0xff,0xc5,0xff,0xba,0xff,0x8f,0xff, + 0x2b,0xff,0x0a,0xff,0xe0,0xfe,0xca,0xfe, + 0x19,0xff,0xe2,0xfe,0xb3,0xfe,0x63,0xfe, + 0x23,0xfe,0xb8,0xfd,0x67,0xfd,0xe0,0xfc, + 0x93,0xfc,0x23,0xfb,0x5c,0xfa,0xb7,0xf8, + 0xbe,0xf7,0xde,0xf6,0x12,0xf6,0x0e,0xf5, + 0x4f,0xf4,0x2d,0xf3,0x95,0xf2,0x58,0xf1, + 0x28,0xf1,0x2a,0xef,0x19,0x6f,0x57,0xef, + 0x83,0xed,0x0b,0xee,0x7c,0xed,0xfc,0xed, + 0xda,0xed,0x84,0xee,0xb7,0xee,0x9b,0xef, + 0x18,0xf0,0x82,0xf1,0x15,0xf3,0x71,0xf4, + 0x20,0xf6,0x18,0xf7,0x18,0xf8,0x1e,0xf9, + 0x0f,0xfa,0x01,0xfb,0xd8,0xfb,0xa8,0xfc, + 0x5f,0xfd,0x6a,0xfe,0xf7,0xfe,0x60,0xff, + 0xb7,0xff,0xbf,0xff,0xe2,0xff,0x0d,0x00, + 0x21,0x00,0x30,0x00,0x31,0x00,0x2f,0x00, + 0x23,0x00,0x19,0x00,0x0f,0x00,0x08,0x00, + 0x02,0x00,0x00,0x00,0x50,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x02,0x00,0x07,0x00,0x0f,0x00, + 0x17,0x00,0x21,0x00,0x2c,0x00,0x2b,0x00, + 0x29,0x00,0x18,0x00,0x03,0x00,0xd4,0xff, + 0xb0,0xff,0xa6,0xff,0x4c,0xff,0xe1,0xfe, + 0x4c,0xfe,0x3e,0xfd,0x91,0xfc,0xb7,0xfb, + 0xe7,0xfa,0xec,0xf9,0x04,0xf9,0xf4,0xf7, + 0x04,0xf7,0xf1,0xf5,0x39,0xf4,0x00,0xf3, + 0x6c,0xf1,0x05,0xf0,0x8f,0xef,0xaa,0xee, + 0x83,0xee,0xd2,0xed,0x07,0xee,0x78,0xed, + 0x24,0xee,0x7c,0xed,0x9b,0xef,0x31,0x6f, + 0x1d,0xef,0x5e,0xf1,0x69,0xf1,0xc1,0xf2, + 0x49,0xf3,0x79,0xf4,0x2f,0xf5,0x3a,0xf6, + 0x03,0xf7,0xdf,0xf7,0xff,0xf8,0x91,0xfa, + 0x3a,0xfb,0xba,0xfc,0xf9,0xfc,0x89,0xfd, + 0xd0,0xfd,0x41,0xfe,0x78,0xfe,0xcc,0xfe, + 0xf5,0xfe,0x2e,0xff,0xd9,0xfe,0xf1,0xfe, + 0x15,0xff,0x3b,0xff,0x9f,0xff,0xc3,0xff, + 0xce,0xff,0xdf,0xff,0xe9,0xff,0xf3,0xff, + 0xfa,0xff,0xfb,0xff,0xfc,0xff,0x00,0x00, + 0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x50,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, + 0xfc,0xff,0xfc,0xff,0xf6,0xff,0xf1,0xff, + 0xef,0xff,0xf3,0xff,0xf4,0xff,0x03,0x00, + 0x08,0x00,0x2c,0x00,0x5f,0x00,0x91,0x00, + 0xb5,0x00,0xf4,0x00,0xe9,0x00,0x46,0x01, + 0x78,0x01,0xf3,0x01,0x2b,0x02,0xbe,0x02, + 0xf4,0x02,0x9e,0x03,0xc9,0x03,0xb1,0x05, + 0x3c,0x06,0x96,0x06,0x86,0x06,0x6a,0x07, + 0x34,0x07,0x24,0x08,0xa3,0x07,0xc3,0x08, + 0xc1,0x07,0x5e,0x09,0x28,0x07,0x44,0x0b, + 0x2d,0x48,0xa4,0x05,0x68,0x09,0xe8,0x06, + 0x2b,0x08,0x9f,0x06,0x43,0x07,0x0e,0x06, + 0x68,0x06,0x59,0x05,0x99,0x05,0x3f,0x04, + 0x01,0x03,0x9a,0x02,0xf5,0x02,0x72,0x02, + 0x5f,0x02,0xe5,0x01,0xce,0x01,0x6a,0x01, + 0x54,0x01,0x02,0x01,0xe9,0x00,0x70,0x00, + 0x5e,0x00,0x35,0x00,0x2a,0x00,0x2e,0x00, + 0x2e,0x00,0x13,0x00,0x10,0x00,0x01,0x00, + 0x00,0x00,0xf9,0xff,0xf9,0xff,0xf6,0xff, + 0xfa,0xff,0xfb,0xff,0xfe,0xff,0xff,0xff, + 0x00,0x00,0x00,0x00,0x50,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xfe,0xff,0xfd,0xff,0xfb,0xff, + 0xfb,0xff,0xfa,0xff,0xfc,0xff,0xfc,0xff, + 0x05,0x00,0x0f,0x00,0x15,0x00,0x02,0x00, + 0x09,0x00,0x13,0x00,0x22,0x00,0x30,0x00, + 0x45,0x00,0x54,0x00,0x83,0x00,0xe8,0x00, + 0x10,0x01,0x40,0x01,0x6e,0x01,0x9f,0x01, + 0xdd,0x01,0xc5,0x01,0xcf,0x01,0x30,0x02, + 0x6a,0x02,0x31,0x04,0xfe,0x04,0x58,0x05, + 0xe2,0x05,0x4d,0x06,0xca,0x06,0x2e,0x07, + 0x90,0x07,0xd5,0x07,0x1f,0x08,0x46,0x48, + 0x7f,0x08,0x94,0x08,0xa8,0x08,0x9d,0x08, + 0x8f,0x08,0x5f,0x08,0x29,0x08,0xca,0x07, + 0x6d,0x07,0xff,0x06,0x08,0x07,0x64,0x06, + 0xfa,0x05,0xf6,0x04,0x66,0x03,0x02,0x03, + 0x85,0x02,0x20,0x02,0xbc,0x01,0x5f,0x01, + 0x46,0x01,0x12,0x01,0xca,0x00,0x96,0x00, + 0x66,0x00,0x41,0x00,0x23,0x00,0x0c,0x00, + 0xe9,0xff,0xe0,0xff,0xe9,0xff,0xf3,0xff, + 0xf2,0xff,0xf6,0xff,0xf8,0xff,0xfc,0xff, + 0x50,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xfe,0xff,0xf9,0xff,0xf5,0xff, + 0xeb,0xff,0xe7,0xff,0xd8,0xff,0xd8,0xff, + 0xcc,0xff,0xe2,0xff,0xc6,0xff,0xa7,0xff, + 0x82,0xff,0xaa,0xff,0x88,0xff,0xc5,0xff, + 0xa2,0xff,0xf1,0xff,0xdc,0xff,0xce,0x00, + 0x71,0x00,0xe6,0x00,0x68,0x00,0xdc,0x00, + 0x21,0x00,0xda,0xff,0x3c,0xfe,0xb2,0xfe, + 0xea,0xfc,0x68,0xfc,0xc9,0xf9,0x62,0xfa, + 0x57,0xf7,0x57,0xf8,0x7d,0xf4,0x74,0xf6, + 0xe5,0xf0,0x7d,0xf5,0xae,0xe9,0xab,0x6e, + 0xed,0xf5,0x87,0xe9,0xc6,0xee,0xf7,0xe9, + 0xe2,0xec,0x5f,0xea,0xa7,0xec,0x6e,0xeb, + 0x80,0xed,0x3c,0xed,0x2e,0xf0,0x47,0xf0, + 0x37,0xf2,0xed,0xf2,0x8c,0xf5,0x12,0xf6, + 0xdf,0xf7,0x88,0xf8,0x23,0xfa,0xcc,0xfa, + 0x91,0xfc,0x4e,0xfd,0x3d,0xfe,0xb0,0xfe, + 0x5d,0xff,0xa6,0xff,0x13,0x00,0x34,0x00, + 0x3e,0x00,0x3e,0x00,0x51,0x00,0x3f,0x00, + 0x40,0x00,0x2e,0x00,0x24,0x00,0x15,0x00, + 0x0b,0x00,0x03,0x00,0x50,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x03,0x00,0x09,0x00,0x16,0x00, + 0x1f,0x00,0x32,0x00,0x35,0x00,0x48,0x00, + 0x3c,0x00,0x51,0x00,0x1b,0x00,0x4a,0x00, + 0xeb,0xff,0xd0,0xff,0x24,0xff,0xec,0xfe, + 0xf0,0xfd,0xa0,0xfd,0x34,0xfc,0x44,0xfb, + 0x9b,0xf9,0x20,0xf9,0x32,0xf7,0xd4,0xf6, + 0xb1,0xf4,0xeb,0xf3,0x1d,0xf1,0x83,0xf1, + 0xcf,0xee,0x03,0xef,0x97,0xeb,0xa0,0xed, + 0x16,0xea,0x69,0xed,0x23,0xe9,0xa7,0xee, + 0x5c,0xe8,0x09,0xf3,0xed,0xe2,0x4b,0x6d, + 0x41,0xfe,0x71,0xeb,0x74,0xf7,0x8f,0xf1, + 0x52,0xf8,0x30,0xf5,0xfe,0xf9,0x22,0xf8, + 0xc4,0xfb,0xb3,0xfa,0x72,0xfe,0x67,0xfd, + 0x7a,0xff,0xbf,0xfe,0x0f,0x01,0x23,0x00, + 0x30,0x01,0x58,0x00,0x0e,0x01,0x67,0x00, + 0x72,0x00,0x9b,0xff,0x09,0x00,0x87,0xff, + 0xd4,0xff,0x7d,0xff,0xba,0xff,0x85,0xff, + 0xe8,0xff,0xcf,0xff,0xe5,0xff,0xcc,0xff, + 0xe6,0xff,0xe1,0xff,0xf1,0xff,0xf2,0xff, + 0xfb,0xff,0xfd,0xff,0x00,0x00,0x00,0x00, + 0x50,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfe,0xff,0xfd,0xff, + 0xf8,0xff,0xf9,0xff,0xf0,0xff,0xf9,0xff, + 0xe6,0xff,0xeb,0xff,0xe0,0xff,0x19,0x00, + 0x19,0x00,0x56,0x00,0x55,0x00,0xb3,0x00, + 0xb2,0x00,0x37,0x01,0x2e,0x01,0x98,0x01, + 0x89,0x01,0x63,0x02,0x44,0x02,0x57,0x03, + 0x0c,0x03,0x33,0x05,0x99,0x05,0xdd,0x06, + 0x8c,0x06,0xc2,0x07,0xb2,0x06,0xa9,0x08, + 0x31,0x07,0x92,0x09,0x28,0x07,0x71,0x0a, + 0x46,0x06,0x2c,0x0c,0xb8,0x01,0xb9,0x46, + 0xd8,0x10,0xc8,0x03,0x32,0x0a,0x42,0x05, + 0x4f,0x08,0x13,0x05,0xea,0x06,0x7a,0x04, + 0xb8,0x05,0xa8,0x03,0x19,0x03,0x99,0x01, + 0x4b,0x02,0x39,0x01,0x2a,0x02,0x48,0x01, + 0xaf,0x01,0xf9,0x00,0x41,0x01,0xb1,0x00, + 0xb2,0x00,0x25,0x00,0x62,0x00,0x0c,0x00, + 0x38,0x00,0xf9,0xff,0x19,0x00,0xec,0xff, + 0x1b,0x00,0x04,0x00,0x0b,0x00,0xf5,0xff, + 0xff,0xff,0xf6,0xff,0xfc,0xff,0xf9,0xff, + 0xfd,0xff,0xfe,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x50,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0xff,0xfe,0xff,0xfd,0xff, + 0xfb,0xff,0xfa,0xff,0xf9,0xff,0xfa,0xff, + 0xf8,0xff,0xfb,0xff,0xe9,0xff,0xdd,0xff, + 0xe9,0xff,0xe6,0xff,0xeb,0xff,0xed,0xff, + 0xf3,0xff,0xf9,0xff,0x03,0x00,0x12,0x00, + 0x1a,0x00,0x5e,0x00,0xb4,0x00,0xbf,0x00, + 0x08,0x01,0xea,0x00,0xec,0x00,0x33,0x01, + 0x7e,0x01,0xc7,0x01,0x55,0x02,0x42,0x04, + 0xdd,0x04,0x60,0x05,0xe9,0x05,0x64,0x06, + 0xd4,0x06,0x38,0x07,0x95,0x07,0xe2,0x07, + 0x23,0x48,0x5f,0x08,0x8b,0x08,0x9d,0x08, + 0xa4,0x08,0x83,0x08,0x59,0x08,0x0b,0x08, + 0xbe,0x07,0x50,0x07,0x5e,0x07,0xe0,0x06, + 0x5a,0x06,0xae,0x05,0x3d,0x05,0x07,0x04, + 0xab,0x02,0x6c,0x02,0xdd,0x01,0xb6,0x01, + 0x86,0x01,0x34,0x01,0xe8,0x00,0xad,0x00, + 0x75,0x00,0x4e,0x00,0x28,0x00,0x11,0x00, + 0xfb,0xff,0x09,0x00,0xfb,0xff,0xeb,0xff, + 0xee,0xff,0xf0,0xff,0xf5,0xff,0xf8,0xff, + 0x50,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xfc,0xff,0xf3,0xff,0xf2,0xff, + 0xdd,0xff,0xe7,0xff,0xc4,0xff,0xe3,0xff, + 0xb6,0xff,0xe2,0xff,0x76,0xff,0x01,0x00, + 0xa3,0xff,0x55,0x00,0xd9,0xff,0xd4,0x00, + 0x34,0x00,0x7f,0x01,0xa4,0x00,0x3e,0x02, + 0x53,0x01,0xe6,0x03,0x06,0x02,0x7b,0x04, + 0x9a,0x01,0x88,0x03,0x25,0x00,0x17,0x03, + 0x7d,0xfe,0x24,0x02,0x28,0xfb,0x80,0xff, + 0x94,0xf7,0xfd,0xfd,0x0f,0xf3,0xf8,0xfc, + 0x50,0xec,0x93,0xff,0x0a,0xdb,0x20,0x64, + 0x2d,0x13,0x84,0xdd,0x02,0xf6,0xf6,0xe3, + 0x17,0xf0,0xb3,0xe5,0x23,0xee,0x98,0xe7, + 0x1b,0xee,0x95,0xea,0x6e,0xf0,0x6d,0xed, + 0x36,0xf2,0x54,0xf0,0xb0,0xf4,0x4b,0xf4, + 0xb6,0xf7,0x23,0xf7,0x30,0xfa,0x74,0xfa, + 0xb6,0xfc,0x9c,0xfc,0x5c,0xfe,0x48,0xfe, + 0x8a,0xff,0x70,0xff,0x43,0x00,0x1e,0x00, + 0x8c,0x00,0x4f,0x00,0x6b,0x00,0x40,0x00, + 0x53,0x00,0x30,0x00,0x2d,0x00,0x16,0x00, + 0x0d,0x00,0x03,0x00,0x50,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0x0a,0x00,0x1d,0x00,0x22,0x00, + 0x47,0x00,0x39,0x00,0x71,0x00,0x3b,0x00, + 0x8e,0x00,0x43,0x00,0xa7,0x00,0xea,0xff, + 0x47,0x00,0x09,0xff,0x74,0xff,0xa5,0xfd, + 0x2e,0xfe,0xb7,0xfb,0x79,0xfc,0x35,0xf9, + 0xb0,0xf9,0xc9,0xf5,0x67,0xf7,0x93,0xf2, + 0x30,0xf4,0xa8,0xee,0x23,0xf2,0x97,0xeb, + 0xc5,0xf0,0x47,0xe8,0xea,0xee,0x5e,0xe5, + 0xce,0xef,0xfc,0xe2,0x41,0xf3,0xdb,0xdf, + 0x9d,0xfc,0x24,0xd2,0x5c,0x45,0x06,0x3d, + 0xc5,0xd7,0xb9,0x03,0x48,0xea,0xe9,0xff, + 0xee,0xf1,0x29,0x00,0xe0,0xf6,0x24,0x01, + 0x06,0xfb,0x73,0x03,0xfa,0xfd,0x02,0x04, + 0xa9,0xff,0x37,0x04,0x59,0x01,0xb8,0x04, + 0x99,0x01,0xf0,0x03,0xbf,0x00,0x59,0x02, + 0x4e,0x00,0x8c,0x01,0xf6,0xff,0xde,0x00, + 0xb4,0xff,0x5f,0x00,0x93,0xff,0x09,0x00, + 0x7c,0xff,0xff,0xff,0xb7,0xff,0xf1,0xff, + 0xce,0xff,0xf2,0xff,0xe7,0xff,0xfa,0xff, + 0xfa,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0x50,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf4,0xff,0xf7,0xff, + 0xe1,0xff,0xf3,0xff,0xcc,0xff,0xfa,0xff, + 0xe8,0xff,0x3a,0x00,0xcd,0xff,0x7b,0x00, + 0x16,0x00,0x19,0x01,0x99,0x00,0x06,0x02, + 0x60,0x01,0x4b,0x03,0x6a,0x02,0x5e,0x04, + 0xfd,0x02,0x2f,0x06,0x78,0x04,0x93,0x0a, + 0xe2,0x08,0xaf,0x0d,0xaa,0x0a,0x9b,0x10, + 0xcb,0x0b,0x16,0x12,0xbd,0x0b,0xcd,0x14, + 0x38,0x0b,0xea,0x17,0x62,0x08,0x77,0x1d, + 0x25,0xfd,0x91,0x41,0x9a,0x7c,0xbf,0xf5, + 0x8f,0x1d,0x07,0x04,0x26,0x15,0x43,0x06, + 0xb4,0x10,0xfa,0x05,0x58,0x0d,0x2a,0x04, + 0xba,0x06,0xff,0x00,0xde,0x04,0x4f,0x00, + 0x5c,0x03,0x5f,0x00,0x3d,0x03,0x32,0x00, + 0x54,0x02,0x7f,0xff,0xf8,0x00,0x55,0xff, + 0x99,0x00,0x56,0xff,0x55,0x00,0x64,0xff, + 0x24,0x00,0x7a,0xff,0x04,0x00,0x7c,0xff, + 0x06,0x00,0xd0,0xff,0x07,0x00,0xdd,0xff, + 0xfe,0xff,0xe9,0xff,0xfb,0xff,0xf5,0xff, + 0xfd,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x50,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff, + 0xfd,0xff,0xfa,0xff,0xf9,0xff,0xf6,0xff, + 0xf4,0xff,0xf1,0xff,0xdd,0xff,0xd0,0xff, + 0xcb,0xff,0xc0,0xff,0xbe,0xff,0xc0,0xff, + 0xbd,0xff,0xb7,0xff,0xb8,0xff,0xb3,0xff, + 0xb3,0xff,0xb4,0xff,0xbc,0xff,0xe7,0xff, + 0x60,0x00,0x58,0x00,0x3e,0x00,0x67,0x00, + 0xbf,0x00,0xf7,0x00,0x77,0x01,0x9f,0x01, + 0xee,0x02,0x9b,0x04,0xf1,0x04,0x94,0x05, + 0xfa,0x05,0x81,0x06,0xe7,0x06,0x56,0x07, + 0xa6,0x07,0xee,0x47,0x2e,0x08,0x5b,0x08, + 0x69,0x08,0x5e,0x08,0x45,0x08,0x0c,0x08, + 0xd1,0x07,0x64,0x07,0x59,0x07,0x27,0x07, + 0x90,0x06,0x0b,0x06,0x7a,0x05,0xe4,0x04, + 0x5a,0x04,0xd9,0x02,0x06,0x02,0xfd,0x01, + 0xb3,0x01,0x5c,0x01,0x0c,0x01,0xca,0x00, + 0x8f,0x00,0x5f,0x00,0x38,0x00,0x18,0x00, + 0x1c,0x00,0x17,0x00,0x06,0x00,0x01,0x00, + 0xf9,0xff,0xee,0xff,0xf1,0xff,0xf5,0xff, + 0x50,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0xff,0xf8,0xff,0xf7,0xff, + 0xe4,0xff,0xee,0xff,0xcb,0xff,0xf2,0xff, + 0xb3,0xff,0xe2,0xff,0x98,0xff,0x1b,0x00, + 0xb6,0xff,0x99,0x00,0x24,0x00,0x51,0x01, + 0xa1,0x00,0x3b,0x02,0x48,0x01,0x5d,0x03, + 0xfe,0x01,0x80,0x04,0x01,0x03,0x5b,0x06, + 0xcb,0x02,0xcc,0x05,0xc7,0x01,0xbe,0x05, + 0x44,0x00,0x1b,0x05,0xcf,0xfd,0x17,0x03, + 0xf4,0xf8,0x82,0x01,0xd9,0xf3,0x94,0x00, + 0x46,0xec,0x46,0x03,0x43,0xdb,0x93,0x2f, + 0xf8,0x51,0x61,0xd2,0x4e,0xfc,0x4e,0xe0, + 0xf4,0xf2,0x2e,0xe3,0x33,0xef,0xfd,0xe4, + 0x4f,0xee,0x69,0xe8,0xf4,0xef,0x36,0xeb, + 0x79,0xf1,0x58,0xee,0xa5,0xf3,0xd2,0xf1, + 0x0b,0xf7,0xb8,0xf5,0x30,0xfa,0x48,0xf9, + 0x5e,0xfc,0xc0,0xfb,0x27,0xfe,0xb6,0xfd, + 0x7d,0xff,0x20,0xff,0x55,0x00,0xe5,0xff, + 0xa8,0x00,0x51,0x00,0xbc,0x00,0x5e,0x00, + 0x78,0x00,0x44,0x00,0x4c,0x00,0x27,0x00, + 0x1f,0x00,0x0b,0x00,0x50,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0x0c,0x00,0x1d,0x00,0x28,0x00, + 0x46,0x00,0x46,0x00,0x6d,0x00,0x67,0x00, + 0xa5,0x00,0x56,0x00,0x84,0x00,0xee,0xff, + 0x24,0x00,0x28,0xff,0x36,0xff,0xc5,0xfd, + 0xca,0xfd,0xdb,0xfb,0xe7,0xfb,0x77,0xf9, + 0x8b,0xf9,0xe6,0xf5,0x5c,0xf6,0x05,0xf2, + 0xf8,0xf2,0xd4,0xee,0xa8,0xf0,0xef,0xeb, + 0xff,0xee,0x54,0xe9,0xfc,0xec,0x88,0xe6, + 0x9d,0xed,0x6b,0xe5,0xaa,0xf0,0xc3,0xe3, + 0x46,0xf8,0x0d,0xd9,0xe1,0x65,0x92,0x12, + 0xd1,0xe4,0x61,0xfe,0x55,0xf0,0x2e,0xfe, + 0x6f,0xf6,0x07,0x00,0xc5,0xfa,0x44,0x02, + 0x44,0xff,0x4b,0x04,0x58,0x01,0x1b,0x05, + 0x98,0x02,0x49,0x05,0x8a,0x03,0xef,0x05, + 0x52,0x03,0x19,0x04,0x4f,0x02,0x0a,0x03, + 0x80,0x01,0xfa,0x01,0xc9,0x00,0x1f,0x01, + 0x3f,0x00,0x71,0x00,0xc7,0xff,0x02,0x00, + 0xa3,0xff,0xd4,0xff,0xc0,0xff,0xe8,0xff, + 0xd0,0xff,0xea,0xff,0xe6,0xff,0xf6,0xff, + 0xf9,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0x50,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfb,0xff,0xf2,0xff, + 0xf6,0xff,0xea,0xff,0x05,0x00,0xf7,0xff, + 0x17,0x00,0x09,0x00,0x31,0x00,0x02,0x00, + 0x60,0x00,0x42,0x00,0xc4,0x00,0xa3,0x00, + 0x52,0x01,0x28,0x01,0x0d,0x02,0xad,0x01, + 0x71,0x02,0xb0,0x02,0xfb,0x04,0x62,0x04, + 0x34,0x06,0x62,0x05,0x76,0x07,0x45,0x06, + 0x69,0x08,0x2e,0x06,0x54,0x09,0x4d,0x06, + 0x73,0x0a,0x95,0x05,0x35,0x0c,0x5d,0x02, + 0x6c,0x15,0x80,0x44,0x5a,0xfe,0x3e,0x0c, + 0x70,0x03,0xf8,0x08,0xde,0x03,0x26,0x07, + 0x76,0x03,0xa8,0x05,0x7f,0x01,0x81,0x02, + 0x8e,0x00,0xa0,0x01,0x0a,0x00,0xea,0x00, + 0xb6,0xff,0xcf,0x00,0xe8,0xff,0x2c,0x00, + 0x68,0xff,0xf5,0xff,0x72,0xff,0xe5,0xff, + 0x86,0xff,0xdd,0xff,0x99,0xff,0xda,0xff, + 0xa1,0xff,0xd3,0xff,0xb9,0xff,0xdc,0xff, + 0xd4,0xff,0xf9,0xff,0xed,0xff,0xfb,0xff, + 0xf5,0xff,0xfc,0xff,0xfb,0xff,0xff,0xff, + 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x50,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0xff,0xfc,0xff,0xfa,0xff,0xf7,0xff, + 0xf3,0xff,0xf1,0xff,0xdf,0xff,0xd0,0xff, + 0xc7,0xff,0xbb,0xff,0xaf,0xff,0xa2,0xff, + 0x96,0xff,0x9a,0xff,0x8f,0xff,0x87,0xff, + 0x78,0xff,0x78,0xff,0x6d,0xff,0x7f,0xff, + 0x75,0xff,0xdc,0xff,0xf0,0xff,0xd9,0xff, + 0x2a,0x00,0x64,0x00,0xbf,0x00,0x1a,0x01, + 0x80,0x01,0x16,0x02,0x22,0x04,0xc1,0x04, + 0x40,0x05,0xc2,0x05,0x3d,0x06,0xb2,0x06, + 0x1a,0x07,0x78,0x07,0xba,0x47,0x00,0x08, + 0x1b,0x08,0x2a,0x08,0x19,0x08,0x01,0x08, + 0xc7,0x07,0x89,0x07,0x2d,0x07,0x4b,0x07, + 0xd2,0x06,0x5d,0x06,0xc3,0x05,0x4d,0x05, + 0x9e,0x04,0x43,0x04,0x11,0x03,0x06,0x02, + 0x03,0x02,0x84,0x01,0x45,0x01,0xec,0x00, + 0xb7,0x00,0x79,0x00,0x53,0x00,0x2b,0x00, + 0x37,0x00,0x23,0x00,0x13,0x00,0x07,0x00, + 0x00,0x00,0xfd,0xff,0xf7,0xff,0xf1,0xff, + 0x50,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xfe,0xff,0xfa,0xff,0xf0,0xff, + 0xed,0xff,0xd9,0xff,0xe2,0xff,0xc8,0xff, + 0xdb,0xff,0x9d,0xff,0xe9,0xff,0xb9,0xff, + 0x3a,0x00,0x07,0x00,0xcd,0x00,0xac,0x00, + 0xc9,0x01,0x78,0x01,0xea,0x02,0x71,0x02, + 0x29,0x04,0x66,0x03,0x4d,0x05,0x62,0x04, + 0xdf,0x06,0x02,0x04,0x9d,0x06,0x6d,0x03, + 0x3e,0x06,0xf4,0x01,0x36,0x05,0x86,0xff, + 0xae,0x02,0xa6,0xfa,0x4d,0x00,0xad,0xf5, + 0x8a,0xfe,0xa9,0xee,0x28,0x00,0x9a,0xdd, + 0x2d,0x67,0xc0,0x0f,0x74,0xdf,0x79,0xf5, + 0xe3,0xe4,0xd1,0xef,0x16,0xe6,0x84,0xed, + 0x35,0xe7,0x1c,0xee,0x83,0xea,0x71,0xef, + 0x0b,0xed,0x6a,0xf1,0x0e,0xf0,0xe9,0xf3, + 0x62,0xf3,0x98,0xf7,0xd2,0xf7,0x8d,0xfa, + 0x78,0xfa,0xb0,0xfc,0xb0,0xfc,0x65,0xfe, + 0x62,0xfe,0x9e,0xff,0x7b,0xff,0x3b,0x00, + 0x1e,0x00,0x8f,0x00,0x64,0x00,0x96,0x00, + 0x64,0x00,0x5c,0x00,0x38,0x00,0x31,0x00, + 0x19,0x00,0x0e,0x00,0x50,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0x0b,0x00,0x20,0x00,0x28,0x00, + 0x4f,0x00,0x45,0x00,0x86,0x00,0x73,0x00, + 0xbc,0x00,0x59,0x00,0xab,0x00,0xed,0xff, + 0x44,0x00,0x23,0xff,0x90,0xff,0xc4,0xfd, + 0x3c,0xfe,0xd0,0xfb,0x72,0xfc,0x54,0xf9, + 0x47,0xfa,0x59,0xf6,0xec,0xf6,0x90,0xf1, + 0xb4,0xf3,0x2e,0xee,0x75,0xf1,0x0b,0xeb, + 0xe5,0xef,0x60,0xe8,0xc9,0xee,0xbc,0xe4, + 0x9b,0xef,0x1b,0xe3,0x74,0xf3,0x3c,0xe0, + 0xfa,0xfc,0x68,0xd2,0xe5,0x4b,0x90,0x37, + 0x1a,0xda,0xbd,0x04,0x64,0xec,0xc7,0x01, + 0x5c,0xf4,0xba,0x02,0xc1,0xf9,0xd2,0x04, + 0xdc,0xfe,0x65,0x06,0x50,0x01,0x02,0x07, + 0xcc,0x02,0x00,0x07,0x7a,0x03,0x28,0x07, + 0x61,0x03,0x60,0x05,0xaf,0x02,0x16,0x04, + 0xd8,0x01,0xcc,0x02,0x01,0x01,0xb2,0x01, + 0x52,0x00,0xc0,0x00,0xdc,0xff,0x3a,0x00, + 0xa8,0xff,0xf2,0xff,0xa3,0xff,0xef,0xff, + 0xcd,0xff,0xee,0xff,0xe4,0xff,0xf6,0xff, + 0xf8,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0x50,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf9,0xff,0xe0,0xff, + 0xf6,0xff,0xe0,0xff,0x1a,0x00,0xdd,0xff, + 0x47,0x00,0xef,0xff,0xa1,0x00,0x09,0x00, + 0xce,0x00,0x42,0x00,0xa1,0x01,0xe1,0x00, + 0xc6,0x02,0xc7,0x01,0x46,0x04,0xea,0x02, + 0x8f,0x05,0xb3,0x05,0x39,0x0a,0xb7,0x07, + 0xdd,0x0c,0x67,0x09,0x9a,0x0f,0xc5,0x0a, + 0x0b,0x12,0x1e,0x0a,0x38,0x14,0x88,0x09, + 0x88,0x17,0x72,0x06,0xd3,0x1d,0x16,0xfa, + 0x4b,0x48,0x5c,0x76,0xc2,0xf3,0x5f,0x1d, + 0x60,0x02,0x5a,0x14,0xb2,0x04,0x8c,0x0f, + 0xcd,0x04,0xf0,0x0a,0xde,0xff,0xf7,0x05, + 0x24,0xff,0xb8,0x03,0x68,0xfe,0x0f,0x02, + 0xe0,0xfd,0x86,0x01,0xf7,0xfd,0x16,0x00, + 0xda,0xfd,0xc5,0xff,0x13,0xfe,0xa7,0xff, + 0x69,0xfe,0xa9,0xff,0xb1,0xfe,0x8b,0xff, + 0xef,0xfe,0xa4,0xff,0x3b,0xff,0xbd,0xff, + 0x7a,0xff,0xe7,0xff,0xcc,0xff,0xf5,0xff, + 0xe4,0xff,0xfa,0xff,0xf5,0xff,0xfe,0xff, + 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x50,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0xff,0xfc,0xff,0xfa,0xff,0xf7,0xff, + 0xf3,0xff,0xee,0xff,0xda,0xff,0xce,0xff, + 0xc2,0xff,0xb6,0xff,0xa7,0xff,0x9b,0xff, + 0x88,0xff,0x89,0xff,0x81,0xff,0x74,0xff, + 0x65,0xff,0x61,0xff,0x58,0xff,0x64,0xff, + 0x60,0xff,0xa2,0xff,0xc5,0xff,0xc0,0xff, + 0x10,0x00,0x48,0x00,0xa9,0x00,0xfc,0x00, + 0x72,0x01,0xde,0x01,0xe0,0x03,0xb5,0x04, + 0x20,0x05,0xb1,0x05,0x22,0x06,0xa0,0x06, + 0x02,0x07,0x66,0x07,0xa5,0x47,0xea,0x07, + 0x00,0x08,0x10,0x08,0xfe,0x07,0xe5,0x07, + 0xac,0x07,0x69,0x07,0x1f,0x07,0x3c,0x07, + 0xb5,0x06,0x47,0x06,0xab,0x05,0x37,0x05, + 0x8b,0x04,0x2c,0x04,0x28,0x03,0x19,0x02, + 0xef,0x01,0x7d,0x01,0x37,0x01,0xe6,0x00, + 0xac,0x00,0x76,0x00,0x4a,0x00,0x37,0x00, + 0x3d,0x00,0x21,0x00,0x14,0x00,0x07,0x00, + 0x01,0x00,0xfd,0xff,0xfb,0xff,0xf2,0xff, + 0x50,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xfe,0xff,0xfa,0xff,0xf1,0xff, + 0xeb,0xff,0xde,0xff,0xdd,0xff,0xd1,0xff, + 0xc7,0xff,0xb5,0xff,0xde,0xff,0xdf,0xff, + 0x2e,0x00,0x42,0x00,0xbe,0x00,0xf7,0x00, + 0xbd,0x01,0xee,0x01,0xdb,0x02,0x06,0x03, + 0x0e,0x04,0x1b,0x04,0x20,0x05,0x24,0x05, + 0x4e,0x06,0x09,0x05,0x22,0x06,0x9f,0x04, + 0x87,0x05,0x5b,0x03,0x2d,0x04,0x37,0x01, + 0x33,0x01,0xb9,0xfc,0x14,0xfe,0x83,0xf8, + 0x17,0xfb,0x38,0xf3,0x8f,0xf9,0x0e,0xe9, + 0x5c,0x6f,0x48,0xfa,0x57,0xe8,0xdd,0xef, + 0xe5,0xe8,0xad,0xec,0xa4,0xe8,0x65,0xeb, + 0x28,0xe9,0xd5,0xec,0xce,0xeb,0x60,0xee, + 0x1a,0xee,0xa0,0xf0,0xec,0xf0,0x57,0xf3, + 0x19,0xf4,0x7b,0xf7,0x75,0xf8,0x41,0xfa, + 0xf9,0xfa,0x7c,0xfc,0x16,0xfd,0x40,0xfe, + 0xb1,0xfe,0x7c,0xff,0xa6,0xff,0x2a,0x00, + 0x40,0x00,0x82,0x00,0x7a,0x00,0x8d,0x00, + 0x73,0x00,0x59,0x00,0x3e,0x00,0x30,0x00, + 0x1b,0x00,0x0d,0x00,0x50,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0x0c,0x00,0x1e,0x00,0x2b,0x00, + 0x49,0x00,0x4d,0x00,0x84,0x00,0x7d,0x00, + 0xa0,0x00,0x68,0x00,0x7e,0x00,0x02,0x00, + 0x01,0x00,0x3d,0xff,0x35,0xff,0xf0,0xfd, + 0xc3,0xfd,0x0e,0xfc,0xd6,0xfb,0xac,0xf9, + 0x84,0xf9,0xda,0xf6,0xb5,0xf5,0x26,0xf2, + 0x9e,0xf2,0x0f,0xef,0x27,0xf0,0x47,0xec, + 0x54,0xee,0x14,0xea,0xae,0xec,0x49,0xe7, + 0x28,0xed,0xba,0xe6,0xd6,0xef,0xdc,0xe5, + 0x78,0xf6,0x8b,0xdd,0xc8,0x6a,0x09,0x0a, + 0x49,0xe9,0x0e,0xfd,0x03,0xf3,0x0d,0xfe, + 0xbb,0xf8,0x78,0x00,0x22,0xfd,0xc9,0x03, + 0x52,0x01,0x6c,0x05,0x50,0x03,0x47,0x06, + 0x6a,0x04,0x67,0x06,0xdb,0x04,0x62,0x06, + 0x2a,0x04,0x08,0x05,0x58,0x03,0xc7,0x03, + 0x56,0x02,0x88,0x02,0x5d,0x01,0x72,0x01, + 0x7c,0x00,0x96,0x00,0x00,0x00,0x19,0x00, + 0xbe,0xff,0xdb,0xff,0xaf,0xff,0xe1,0xff, + 0xd3,0xff,0xe7,0xff,0xe6,0xff,0xf4,0xff, + 0xf9,0xff,0xfe,0xff,0x00,0x00,0x00,0x00, + 0x50,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfa,0xff,0xeb,0xff, + 0x00,0x00,0xf1,0xff,0x0e,0x00,0xf3,0xff, + 0x28,0x00,0x01,0x00,0x5b,0x00,0x15,0x00, + 0x71,0x00,0x38,0x00,0xe2,0x00,0x92,0x00, + 0x7d,0x01,0x0f,0x01,0x4c,0x02,0x99,0x01, + 0x60,0x03,0x7d,0x03,0x28,0x05,0x5b,0x04, + 0x7b,0x06,0x35,0x05,0xc9,0x07,0xe6,0x05, + 0xba,0x08,0x90,0x05,0xca,0x09,0x4c,0x05, + 0x3e,0x0b,0xc9,0x03,0x4b,0x0e,0x9a,0xfc, + 0x99,0x41,0x38,0x1a,0x11,0xff,0xca,0x0b, + 0x8f,0x02,0xa4,0x08,0xef,0x02,0xaf,0x06, + 0x93,0x02,0xb1,0x03,0x32,0x00,0x3b,0x02, + 0xba,0xff,0x40,0x01,0x55,0xff,0x84,0x00, + 0x20,0xff,0x44,0x00,0xed,0xfe,0xd5,0xff, + 0xfc,0xfe,0xb7,0xff,0x1d,0xff,0xb4,0xff, + 0x49,0xff,0xbc,0xff,0x61,0xff,0xbc,0xff, + 0x8b,0xff,0xce,0xff,0xaf,0xff,0xde,0xff, + 0xcc,0xff,0xf4,0xff,0xed,0xff,0xfb,0xff, + 0xf7,0xff,0xfe,0xff,0xfe,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x04,0x00,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x04,0x00,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x00,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0x02,0x00,0x03,0x00,0x03,0x00,0x03,0x00, + 0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x02,0x00,0xa6,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0xb5,0xff,0x00,0x00, + 0x04,0x00,0x00,0x00,0xc4,0xff,0x00,0x00, + 0x08,0x00,0x00,0x00,0xd3,0xff,0x00,0x00, + 0x0c,0x00,0x00,0x00,0xe2,0xff,0x00,0x00, + 0x10,0x00,0x00,0x00,0xf1,0xff,0x00,0x00, + 0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x18,0x00,0x00,0x00,0x0f,0x00,0x00,0x00, + 0x1c,0x00,0x00,0x00,0x1e,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x2d,0x00,0x00,0x00, + 0x24,0x00,0x00,0x00,0x3c,0x00,0x00,0x00, + 0x28,0x00,0x00,0x00,0x4b,0x00,0x00,0x00, + 0x2c,0x00,0x00,0x00,0x5a,0x00,0x00,0x00, + 0x30,0x00,0x00,0x00,0x00,0x00,0xac,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x39,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xc7,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x54,0xff, + 0x00,0x00,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/tdfb/line4_28mm_pm90deg_16khz.conf b/tools/topology/topology2/include/components/tdfb/line4_28mm_pm90deg_16khz.conf new file mode 100644 index 000000000000..9e757b4f6e89 --- /dev/null +++ b/tools/topology/topology2/include/components/tdfb/line4_28mm_pm90deg_16khz.conf @@ -0,0 +1,172 @@ +# Created with script example_two_beams.m 23-Oct-2023 +# cd tools/tune/tdfb; matlab -nodisplay -nosplash -nodesktop -r example_two_beams +Object.Base.data."tdfb_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x14,0x05,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x14,0x05,0x00,0x00,0x08,0x00,0x02,0x00, + 0x01,0x00,0x04,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x0f,0x00,0xa6,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xfb,0xff, + 0xec,0xff,0xd1,0xff,0xa9,0xff,0x72,0xff, + 0x2b,0xff,0xd8,0xfe,0x79,0xfe,0x16,0xfe, + 0xb0,0xfd,0x4f,0xfd,0xf5,0xfc,0xc5,0xfc, + 0xac,0xfc,0xd6,0xfc,0x64,0xfc,0x87,0xfc, + 0x38,0xfd,0x90,0xfd,0x09,0xfe,0x70,0xfd, + 0x14,0xfc,0xfe,0xfb,0x2c,0xfc,0x75,0xfc, + 0x47,0xfd,0xa0,0xff,0xd1,0x01,0xfa,0x07, + 0x86,0x10,0xcc,0x13,0x24,0x57,0x65,0x18, + 0x52,0x18,0x89,0x17,0x7b,0x15,0x23,0x10, + 0x2a,0x09,0x76,0x05,0x94,0x02,0x7b,0x01, + 0x21,0x00,0x6c,0xfe,0xc9,0xfd,0x48,0xfe, + 0x9b,0xfe,0x09,0xff,0x45,0xff,0x72,0xff, + 0xc4,0xff,0xf9,0xff,0x17,0x00,0x27,0x00, + 0x2f,0x00,0x31,0x00,0x2c,0x00,0x24,0x00, + 0x1b,0x00,0x13,0x00,0x0b,0x00,0x05,0x00, + 0x40,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x03,0x00,0x08,0x00,0x24,0x00,0x32,0x00, + 0x81,0x00,0x8e,0x00,0x19,0x01,0xfe,0x00, + 0xb0,0x01,0x24,0x01,0xbf,0x01,0x3e,0x00, + 0x89,0x00,0xe7,0xfd,0x09,0xfe,0x9e,0xfa, + 0xc9,0xfa,0xa2,0xf6,0x6f,0xf9,0x75,0xf7, + 0x2e,0xfd,0x20,0xfc,0x3f,0x09,0x2f,0x0a, + 0x96,0x18,0x83,0x12,0x3e,0x1c,0xd1,0x05, + 0x08,0x0d,0x0b,0xdb,0x17,0x0e,0xf9,0x39, + 0x70,0xa7,0x4f,0xc7,0xf7,0xb2,0x34,0xc9, + 0x0b,0xc9,0x67,0xe5,0xb8,0xe9,0xa7,0xfd, + 0x35,0x01,0x53,0x0e,0xda,0x0b,0xa7,0x11, + 0x8f,0x0e,0x6c,0x10,0x67,0x0c,0x08,0x0c, + 0xe5,0x07,0x97,0x07,0xbf,0x04,0x69,0x04, + 0x7e,0x02,0x58,0x02,0x43,0x01,0x38,0x01, + 0x9e,0x00,0x90,0x00,0x40,0x00,0x31,0x00, + 0x10,0x00,0x05,0x00,0x40,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x05,0x00,0x0f,0x00,0x32,0x00, + 0x3e,0x00,0x93,0x00,0x99,0x00,0x3d,0x01, + 0x38,0x01,0x5d,0x02,0x67,0x02,0x6e,0x04, + 0x9b,0x04,0xa0,0x07,0xb3,0x07,0x0d,0x0c, + 0x2d,0x0c,0xa0,0x10,0x60,0x0e,0x20,0x12, + 0xc0,0x0b,0x10,0x0f,0x9f,0x01,0xf2,0xfe, + 0x3d,0xea,0x16,0xe7,0xc2,0xc9,0x8b,0xca, + 0x38,0xb2,0x9e,0xc8,0x8e,0xa4,0x45,0x2e, + 0xe9,0x1a,0xbe,0xd5,0xbb,0x0d,0x8c,0x03, + 0xdb,0x1c,0xab,0x11,0xa9,0x19,0x24,0x0a, + 0x5d,0x0a,0x39,0xfc,0xb9,0xfd,0x54,0xf7, + 0xd2,0xf9,0x5f,0xf6,0xe0,0xfa,0x53,0xfa, + 0x19,0xfe,0xaa,0xfd,0x90,0x00,0x16,0x00, + 0xc6,0x01,0x0f,0x01,0xb9,0x01,0xf4,0x00, + 0x20,0x01,0x8b,0x00,0x85,0x00,0x30,0x00, + 0x25,0x00,0x07,0x00,0x03,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x02,0x00,0x05,0x00, + 0x0c,0x00,0x11,0x00,0x1e,0x00,0x20,0x00, + 0x33,0x00,0x2a,0x00,0x3b,0x00,0x1a,0x00, + 0x2b,0x00,0xe7,0xff,0xe3,0xff,0x58,0xff, + 0x6b,0xff,0xe4,0xfe,0xd3,0xfe,0x12,0xfe, + 0x11,0xfe,0xfb,0xfd,0x5c,0x00,0xf8,0x00, + 0xf5,0x02,0x96,0x04,0x8b,0x09,0x9c,0x0e, + 0x78,0x16,0xcf,0x15,0xca,0x1a,0xa4,0x13, + 0xb0,0x56,0xa4,0x19,0x47,0x0e,0x7c,0x0a, + 0xc9,0x00,0xd3,0x00,0x9d,0xfc,0x2d,0xfd, + 0xa1,0xfb,0x83,0xfc,0x9f,0xfb,0xb0,0xfd, + 0xc1,0xfd,0xe0,0xfd,0x0b,0xfd,0xcf,0xfc, + 0x38,0xfc,0xff,0xfc,0x98,0xfc,0xe3,0xfc, + 0xe5,0xfc,0x61,0xfd,0xa4,0xfd,0x20,0xfe, + 0x70,0xfe,0xdd,0xfe,0x26,0xff,0x74,0xff, + 0xa7,0xff,0xd2,0xff,0xec,0xff,0xfb,0xff, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x02,0x00,0x05,0x00,0x0c,0x00,0x11,0x00, + 0x1e,0x00,0x20,0x00,0x33,0x00,0x2a,0x00, + 0x3b,0x00,0x1a,0x00,0x2b,0x00,0xe7,0xff, + 0xe3,0xff,0x58,0xff,0x6b,0xff,0xe4,0xfe, + 0xd3,0xfe,0x12,0xfe,0x11,0xfe,0xfb,0xfd, + 0x5c,0x00,0xf8,0x00,0xf5,0x02,0x96,0x04, + 0x8b,0x09,0x9c,0x0e,0x78,0x16,0xcf,0x15, + 0xca,0x1a,0xa4,0x13,0xb0,0x56,0xa4,0x19, + 0x47,0x0e,0x7c,0x0a,0xc9,0x00,0xd3,0x00, + 0x9d,0xfc,0x2d,0xfd,0xa1,0xfb,0x83,0xfc, + 0x9f,0xfb,0xb0,0xfd,0xc1,0xfd,0xe0,0xfd, + 0x0b,0xfd,0xcf,0xfc,0x38,0xfc,0xff,0xfc, + 0x98,0xfc,0xe3,0xfc,0xe5,0xfc,0x61,0xfd, + 0xa4,0xfd,0x20,0xfe,0x70,0xfe,0xdd,0xfe, + 0x26,0xff,0x74,0xff,0xa7,0xff,0xd2,0xff, + 0xec,0xff,0xfb,0xff,0x00,0x00,0x00,0x00, + 0x40,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00, + 0x0f,0x00,0x32,0x00,0x3e,0x00,0x93,0x00, + 0x99,0x00,0x3d,0x01,0x38,0x01,0x5d,0x02, + 0x67,0x02,0x6e,0x04,0x9b,0x04,0xa0,0x07, + 0xb3,0x07,0x0d,0x0c,0x2d,0x0c,0xa0,0x10, + 0x60,0x0e,0x20,0x12,0xc0,0x0b,0x10,0x0f, + 0x9f,0x01,0xf2,0xfe,0x3d,0xea,0x16,0xe7, + 0xc2,0xc9,0x8b,0xca,0x38,0xb2,0x9e,0xc8, + 0x8e,0xa4,0x45,0x2e,0xe9,0x1a,0xbe,0xd5, + 0xbb,0x0d,0x8c,0x03,0xdb,0x1c,0xab,0x11, + 0xa9,0x19,0x24,0x0a,0x5d,0x0a,0x39,0xfc, + 0xb9,0xfd,0x54,0xf7,0xd2,0xf9,0x5f,0xf6, + 0xe0,0xfa,0x53,0xfa,0x19,0xfe,0xaa,0xfd, + 0x90,0x00,0x16,0x00,0xc6,0x01,0x0f,0x01, + 0xb9,0x01,0xf4,0x00,0x20,0x01,0x8b,0x00, + 0x85,0x00,0x30,0x00,0x25,0x00,0x07,0x00, + 0x03,0x00,0x00,0x00,0x40,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x03,0x00,0x08,0x00, + 0x24,0x00,0x32,0x00,0x81,0x00,0x8e,0x00, + 0x19,0x01,0xfe,0x00,0xb0,0x01,0x24,0x01, + 0xbf,0x01,0x3e,0x00,0x89,0x00,0xe7,0xfd, + 0x09,0xfe,0x9e,0xfa,0xc9,0xfa,0xa2,0xf6, + 0x6f,0xf9,0x75,0xf7,0x2e,0xfd,0x20,0xfc, + 0x3f,0x09,0x2f,0x0a,0x96,0x18,0x83,0x12, + 0x3e,0x1c,0xd1,0x05,0x08,0x0d,0x0b,0xdb, + 0x17,0x0e,0xf9,0x39,0x70,0xa7,0x4f,0xc7, + 0xf7,0xb2,0x34,0xc9,0x0b,0xc9,0x67,0xe5, + 0xb8,0xe9,0xa7,0xfd,0x35,0x01,0x53,0x0e, + 0xda,0x0b,0xa7,0x11,0x8f,0x0e,0x6c,0x10, + 0x67,0x0c,0x08,0x0c,0xe5,0x07,0x97,0x07, + 0xbf,0x04,0x69,0x04,0x7e,0x02,0x58,0x02, + 0x43,0x01,0x38,0x01,0x9e,0x00,0x90,0x00, + 0x40,0x00,0x31,0x00,0x10,0x00,0x05,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xfb,0xff,0xec,0xff,0xd1,0xff, + 0xa9,0xff,0x72,0xff,0x2b,0xff,0xd8,0xfe, + 0x79,0xfe,0x16,0xfe,0xb0,0xfd,0x4f,0xfd, + 0xf5,0xfc,0xc5,0xfc,0xac,0xfc,0xd6,0xfc, + 0x64,0xfc,0x87,0xfc,0x38,0xfd,0x90,0xfd, + 0x09,0xfe,0x70,0xfd,0x14,0xfc,0xfe,0xfb, + 0x2c,0xfc,0x75,0xfc,0x47,0xfd,0xa0,0xff, + 0xd1,0x01,0xfa,0x07,0x86,0x10,0xcc,0x13, + 0x24,0x57,0x65,0x18,0x52,0x18,0x89,0x17, + 0x7b,0x15,0x23,0x10,0x2a,0x09,0x76,0x05, + 0x94,0x02,0x7b,0x01,0x21,0x00,0x6c,0xfe, + 0xc9,0xfd,0x48,0xfe,0x9b,0xfe,0x09,0xff, + 0x45,0xff,0x72,0xff,0xc4,0xff,0xf9,0xff, + 0x17,0x00,0x27,0x00,0x2f,0x00,0x31,0x00, + 0x2c,0x00,0x24,0x00,0x1b,0x00,0x13,0x00, + 0x0b,0x00,0x05,0x00,0x00,0x00,0x01,0x00, + 0x02,0x00,0x03,0x00,0x00,0x00,0x01,0x00, + 0x02,0x00,0x03,0x00,0x01,0x00,0x01,0x00, + 0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00, + 0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x5a,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xac,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x39,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xc7,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x54,0xff, + 0x00,0x00,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/tdfb/line4_28mm_pm90deg_48khz.conf b/tools/topology/topology2/include/components/tdfb/line4_28mm_pm90deg_48khz.conf new file mode 100644 index 000000000000..150519bdac18 --- /dev/null +++ b/tools/topology/topology2/include/components/tdfb/line4_28mm_pm90deg_48khz.conf @@ -0,0 +1,172 @@ +# Created with script example_two_beams.m 23-Oct-2023 +# cd tools/tune/tdfb; matlab -nodisplay -nosplash -nodesktop -r example_two_beams +Object.Base.data."tdfb_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x14,0x05,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x14,0x05,0x00,0x00,0x08,0x00,0x02,0x00, + 0x01,0x00,0x04,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x0f,0x00,0xa6,0xff,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, + 0xfc,0xff,0xf7,0xff,0xef,0xff,0xe7,0xff, + 0xdb,0xff,0xd4,0xff,0xca,0xff,0xbc,0xff, + 0xae,0xff,0xa4,0xff,0x98,0xff,0x99,0xff, + 0x90,0xff,0xbb,0xff,0xd3,0xff,0xcd,0xff, + 0x0e,0x00,0x3e,0x00,0x94,0x00,0xe2,0x00, + 0x53,0x01,0xbf,0x01,0xad,0x03,0x87,0x04, + 0xfc,0x04,0x96,0x05,0x11,0x06,0x96,0x06, + 0xfe,0x06,0x65,0x07,0xa1,0x47,0xe6,0x07, + 0xf4,0x07,0xf9,0x07,0xd8,0x07,0xad,0x07, + 0x60,0x07,0x07,0x07,0xa5,0x06,0xa1,0x06, + 0x05,0x06,0x81,0x05,0xd6,0x04,0x51,0x04, + 0xa2,0x03,0x36,0x03,0x53,0x02,0x79,0x01, + 0x49,0x01,0xed,0x00,0xb4,0x00,0x7a,0x00, + 0x53,0x00,0x33,0x00,0x1b,0x00,0x11,0x00, + 0x40,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xfe,0xff,0xfe,0xff,0xfc,0xff, + 0x09,0x00,0x11,0x00,0x3b,0x00,0x5c,0x00, + 0xbe,0x00,0xee,0x00,0x84,0x01,0xc0,0x01, + 0x86,0x02,0xb9,0x02,0x98,0x03,0xca,0x03, + 0xda,0x04,0x07,0x04,0x13,0x05,0xf1,0x03, + 0xd9,0x04,0x03,0x03,0xd4,0x03,0x22,0x01, + 0x23,0x01,0xd9,0xfc,0x22,0xfe,0xa6,0xf8, + 0x25,0xfb,0x4a,0xf3,0x92,0xf9,0x0f,0xe9, + 0x56,0x6f,0x4b,0xfa,0x79,0xe8,0x0b,0xf0, + 0x52,0xe9,0x35,0xed,0x8b,0xe9,0x75,0xec, + 0xad,0xea,0x6f,0xee,0xe0,0xed,0x8d,0xf0, + 0xba,0xf0,0x46,0xf3,0xf0,0xf3,0x41,0xf6, + 0x3b,0xf7,0x06,0xfa,0xff,0xfa,0x6d,0xfc, + 0x18,0xfd,0x22,0xfe,0x99,0xfe,0x40,0xff, + 0x84,0xff,0xd7,0xff,0xea,0xff,0x08,0x00, + 0x08,0x00,0x09,0x00,0x40,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x03,0x00,0x07,0x00,0x10,0x00,0x00,0x00, + 0x00,0x00,0xc3,0xff,0xb5,0xff,0x1e,0xff, + 0xed,0xfe,0xe8,0xfd,0x98,0xfd,0x10,0xfc, + 0xb3,0xfb,0x95,0xf9,0x6a,0xf8,0x57,0xf5, + 0x4c,0xf5,0xfa,0xf1,0x7a,0xf2,0xb6,0xee, + 0x23,0xf0,0xe8,0xeb,0xf7,0xed,0x8f,0xe8, + 0xe2,0xed,0x6d,0xe7,0x22,0xf0,0x26,0xe6, + 0x86,0xf6,0x9d,0xdd,0xc1,0x6a,0x08,0x0a, + 0x55,0xe9,0x13,0xfd,0x28,0xf3,0x16,0xfe, + 0xee,0xf8,0x73,0x00,0x48,0xfd,0x88,0x03, + 0x36,0x01,0xde,0x04,0xe7,0x02,0x5b,0x05, + 0xa8,0x03,0x1f,0x05,0xbd,0x03,0xb4,0x04, + 0xec,0x02,0x57,0x03,0x15,0x02,0x2f,0x02, + 0x3e,0x01,0x38,0x01,0x95,0x00,0x89,0x00, + 0x27,0x00,0x25,0x00,0x00,0x00,0x03,0x00, + 0xfc,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x17,0x00,0x06,0x00, + 0x2a,0x00,0x18,0x00,0x6c,0x00,0x4e,0x00, + 0xdd,0x00,0xa9,0x00,0x86,0x01,0x1f,0x01, + 0x7d,0x02,0xaf,0x02,0x20,0x04,0x9b,0x03, + 0x87,0x05,0x90,0x04,0xfd,0x06,0x68,0x05, + 0x25,0x08,0x47,0x05,0x69,0x09,0x27,0x05, + 0x09,0x0b,0xbf,0x03,0x37,0x0e,0x9c,0xfc, + 0x95,0x41,0x37,0x1a,0x11,0xff,0xb9,0x0b, + 0x88,0x02,0x7c,0x08,0xdb,0x02,0x6d,0x06, + 0x71,0x02,0x72,0x03,0x2d,0x00,0x00,0x02, + 0xc3,0xff,0x11,0x01,0x73,0xff,0x6a,0x00, + 0x54,0xff,0x32,0x00,0x3f,0xff,0xe3,0xff, + 0x5e,0xff,0xd6,0xff,0x87,0xff,0xdb,0xff, + 0xb2,0xff,0xe7,0xff,0xcf,0xff,0xef,0xff, + 0xea,0xff,0xfa,0xff,0xfb,0xff,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x17,0x00,0x06,0x00,0x2a,0x00,0x18,0x00, + 0x6c,0x00,0x4e,0x00,0xdd,0x00,0xa9,0x00, + 0x86,0x01,0x1f,0x01,0x7d,0x02,0xaf,0x02, + 0x20,0x04,0x9b,0x03,0x87,0x05,0x90,0x04, + 0xfd,0x06,0x68,0x05,0x25,0x08,0x47,0x05, + 0x69,0x09,0x27,0x05,0x09,0x0b,0xbf,0x03, + 0x37,0x0e,0x9c,0xfc,0x95,0x41,0x37,0x1a, + 0x11,0xff,0xb9,0x0b,0x88,0x02,0x7c,0x08, + 0xdb,0x02,0x6d,0x06,0x71,0x02,0x72,0x03, + 0x2d,0x00,0x00,0x02,0xc3,0xff,0x11,0x01, + 0x73,0xff,0x6a,0x00,0x54,0xff,0x32,0x00, + 0x3f,0xff,0xe3,0xff,0x5e,0xff,0xd6,0xff, + 0x87,0xff,0xdb,0xff,0xb2,0xff,0xe7,0xff, + 0xcf,0xff,0xef,0xff,0xea,0xff,0xfa,0xff, + 0xfb,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x03,0x00,0x07,0x00, + 0x10,0x00,0x00,0x00,0x00,0x00,0xc3,0xff, + 0xb5,0xff,0x1e,0xff,0xed,0xfe,0xe8,0xfd, + 0x98,0xfd,0x10,0xfc,0xb3,0xfb,0x95,0xf9, + 0x6a,0xf8,0x57,0xf5,0x4c,0xf5,0xfa,0xf1, + 0x7a,0xf2,0xb6,0xee,0x23,0xf0,0xe8,0xeb, + 0xf7,0xed,0x8f,0xe8,0xe2,0xed,0x6d,0xe7, + 0x22,0xf0,0x26,0xe6,0x86,0xf6,0x9d,0xdd, + 0xc1,0x6a,0x08,0x0a,0x55,0xe9,0x13,0xfd, + 0x28,0xf3,0x16,0xfe,0xee,0xf8,0x73,0x00, + 0x48,0xfd,0x88,0x03,0x36,0x01,0xde,0x04, + 0xe7,0x02,0x5b,0x05,0xa8,0x03,0x1f,0x05, + 0xbd,0x03,0xb4,0x04,0xec,0x02,0x57,0x03, + 0x15,0x02,0x2f,0x02,0x3e,0x01,0x38,0x01, + 0x95,0x00,0x89,0x00,0x27,0x00,0x25,0x00, + 0x00,0x00,0x03,0x00,0xfc,0xff,0xff,0xff, + 0x00,0x00,0x00,0x00,0x40,0x00,0x02,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff, + 0xfe,0xff,0xfc,0xff,0x09,0x00,0x11,0x00, + 0x3b,0x00,0x5c,0x00,0xbe,0x00,0xee,0x00, + 0x84,0x01,0xc0,0x01,0x86,0x02,0xb9,0x02, + 0x98,0x03,0xca,0x03,0xda,0x04,0x07,0x04, + 0x13,0x05,0xf1,0x03,0xd9,0x04,0x03,0x03, + 0xd4,0x03,0x22,0x01,0x23,0x01,0xd9,0xfc, + 0x22,0xfe,0xa6,0xf8,0x25,0xfb,0x4a,0xf3, + 0x92,0xf9,0x0f,0xe9,0x56,0x6f,0x4b,0xfa, + 0x79,0xe8,0x0b,0xf0,0x52,0xe9,0x35,0xed, + 0x8b,0xe9,0x75,0xec,0xad,0xea,0x6f,0xee, + 0xe0,0xed,0x8d,0xf0,0xba,0xf0,0x46,0xf3, + 0xf0,0xf3,0x41,0xf6,0x3b,0xf7,0x06,0xfa, + 0xff,0xfa,0x6d,0xfc,0x18,0xfd,0x22,0xfe, + 0x99,0xfe,0x40,0xff,0x84,0xff,0xd7,0xff, + 0xea,0xff,0x08,0x00,0x08,0x00,0x09,0x00, + 0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0xff,0xfc,0xff,0xf7,0xff, + 0xef,0xff,0xe7,0xff,0xdb,0xff,0xd4,0xff, + 0xca,0xff,0xbc,0xff,0xae,0xff,0xa4,0xff, + 0x98,0xff,0x99,0xff,0x90,0xff,0xbb,0xff, + 0xd3,0xff,0xcd,0xff,0x0e,0x00,0x3e,0x00, + 0x94,0x00,0xe2,0x00,0x53,0x01,0xbf,0x01, + 0xad,0x03,0x87,0x04,0xfc,0x04,0x96,0x05, + 0x11,0x06,0x96,0x06,0xfe,0x06,0x65,0x07, + 0xa1,0x47,0xe6,0x07,0xf4,0x07,0xf9,0x07, + 0xd8,0x07,0xad,0x07,0x60,0x07,0x07,0x07, + 0xa5,0x06,0xa1,0x06,0x05,0x06,0x81,0x05, + 0xd6,0x04,0x51,0x04,0xa2,0x03,0x36,0x03, + 0x53,0x02,0x79,0x01,0x49,0x01,0xed,0x00, + 0xb4,0x00,0x7a,0x00,0x53,0x00,0x33,0x00, + 0x1b,0x00,0x11,0x00,0x00,0x00,0x01,0x00, + 0x02,0x00,0x03,0x00,0x00,0x00,0x01,0x00, + 0x02,0x00,0x03,0x00,0x01,0x00,0x01,0x00, + 0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00, + 0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x5a,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xac,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x39,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xc7,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x54,0xff, + 0x00,0x00,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/tdfb/line4_pass.conf b/tools/topology/topology2/include/components/tdfb/line4_pass.conf new file mode 100644 index 000000000000..d32da6170539 --- /dev/null +++ b/tools/topology/topology2/include/components/tdfb/line4_pass.conf @@ -0,0 +1,16 @@ +# Exported with script example_pass_config.m 23-Oct-2023 +# cd tools/tune/tdfb; octave --no-window-system example_pass_config.m +Object.Base.data."tdfb_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x34,0x00,0x00,0x00,0x00,0xa0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x34,0x00,0x00,0x00,0x04,0x00,0x04,0x00, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0x02,0x00,0x03,0x00,0x01,0x00,0x02,0x00, + 0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/widget-common.conf b/tools/topology/topology2/include/components/widget-common.conf index af87e4e70f7d..3c398300ef89 100644 --- a/tools/topology/topology2/include/components/widget-common.conf +++ b/tools/topology/topology2/include/components/widget-common.conf @@ -2,12 +2,12 @@ # Common widget attribute definitions # -# instance of the widget object +## instance of the widget object DefineAttribute."instance" {} # -# no_pm - maps to the DAPM widget's reg field -# "false" value indicates that there is no direct DAPM for this widget +## no_pm - maps to the DAPM widget's reg field +## "false" value indicates that there is no direct DAPM for this widget # DefineAttribute."no_pm" { type "string" @@ -20,26 +20,26 @@ DefineAttribute."no_pm" { } # -# Widget Type - maps to the widget ID with values of type enum SND_SOC_TPLG_DAPM_* +## Widget Type - maps to the widget ID with values of type enum SND_SOC_TPLG_DAPM_* # DefineAttribute."type" { type "string" } # -# Stream name - maps to the DAPM widget's stream name +## Stream name - maps to the DAPM widget's stream name # DefineAttribute."stream_name" { type "string" } # -# Event type widget binds to +## Event type widget binds to # DefineAttribute.event_type {} # -# Widget event flags +## Widget event flags # DefineAttribute.event_flags {} @@ -47,7 +47,7 @@ DefineAttribute.event_flags {} # Attributes with a "token_ref" value will be added to widget's private data # -# widget format +## widget format DefineAttribute."format" { type "string" # Token set reference name and type @@ -62,49 +62,50 @@ DefineAttribute."format" { } } -# ID of the core this widget should be scheduled on +## ID of the core this widget should be scheduled on DefineAttribute."core_id" { # Token set reference name and type token_ref "comp.word" } -# number of periods to preload +## number of periods to preload DefineAttribute."preload_count" { # Token set reference name and type token_ref "comp.word" } -# Number of sink pins a widget can support +## Number of sink pins a widget can support DefineAttribute."num_input_pins" { # Token set reference name and type token_ref "comp.word" } -# Number of source pins a widget can support +## Number of source pins a widget can support DefineAttribute."num_output_pins" { # Token set reference name and type token_ref "comp.word" } -# Number of supported sink(input) audio formats +## Number of supported sink(input) audio formats DefineAttribute."num_input_audio_formats" { # Token set reference name and type token_ref "comp.word" } -# Number of supported source(output) audio formats +## Number of supported source(output) audio formats DefineAttribute."num_output_audio_formats" { # Token set reference name and type token_ref "comp.word" } -# Widget UUID +## Widget UUID DefineAttribute.uuid { type "string" # Token set reference name and type token_ref "comp.uuid" } +## Whether to add this widget's name to the beginning of all its associated mixer names DefineAttribute."no_wname_in_kcontrol_name" { type "string" # Token set reference name diff --git a/tools/topology/topology2/include/controls/common.conf b/tools/topology/topology2/include/controls/common.conf index 77593fccc1fb..caf32838b61e 100644 --- a/tools/topology/topology2/include/controls/common.conf +++ b/tools/topology/topology2/include/controls/common.conf @@ -1,15 +1,19 @@ -# Common class definitions for controls - -# -# Class for channel objects. These are instantiated as: -# Object.Base.channel."fl" { -# reg 1 -# shift 0 -# } -# +## \file common.conf +## \brief Common class definitions for controls. + +## \struct channel +## \brief Class for channel objects. +## These are instantiated as: +## +## Object.Base.channel."fl" { +## reg 1 +## shift 0 +## } +## + Class.Base."channel" { DefineAttribute."instance" {} - # name of the channel + ## name of the channel DefineAttribute."name" { type "string" } @@ -33,13 +37,18 @@ Class.Base."channel" { shift 1 } -# Class definition for control ops. These are instantiated as: -# Object.Base.ops."ctl" { -# info "volsw" -# get "259" -# put "259" -# } -# +## \struct ops +## \brief Class definition for control ops. +## +## These are instantiated as: +## +## Object.Base.ops."ctl" { +## info "volsw" +## get "259" +## put "259" +## } +## + Class.Base."ops" { DefineAttribute."instance" {} # ops name @@ -68,13 +77,17 @@ Class.Base."ops" { } } -# Class definition for control extops. These are instantiated as: -# Object.Base.extops."ctl" { -# info "volsw" -# get "258" -# put "258" -# } -# +## \struct extops +## \brief Class definition for control extops. +## These are instantiated as: +## +## Object.Base.extops."ctl" { +## info "volsw" +## get "258" +## put "258" +## } +## + Class.Base."extops" { DefineAttribute."instance" {} # extops name @@ -104,12 +117,15 @@ Class.Base."extops" { } } -# -# Class definition for scale objects. These are instantiated as follows: -# Object.Base.scale."name" { -# mute 1 -# } -# +## \struct scale +## \brief Class definition for scale objects. +## These are instantiated as follows: +## +## Object.Base.scale."name" { +## mute 1 +## } +## + Class.Base."scale" { DefineAttribute."instance" {} DefineAttribute."name" { @@ -139,11 +155,17 @@ Class.Base."scale" { mute 1 } -# -# Class definition for tlv objects. These are instantiated as follows: -# Object.Base.tlv."vtlv_m64s2" { -# Object.Base.scale."0" {} -# } +## \struct tlv +## \brief Class definition for tlv objects. +## These are instantiated as follows: +## +## Object.Base.tlv."vtlv_m64s2" { +## Object.Base.scale."0" {} +## } +## +## The linked object instance is \link scale \endlink . +## + Class.Base."tlv" { DefineAttribute."instance" {} DefineAttribute."name" { @@ -160,3 +182,22 @@ Class.Base."tlv" { unique "instance" } } + +Class.Base."text" { + DefineAttribute."instance" {} + + DefineAttribute."name" { + type "string" + } + + attributes { + !constructor [ + "name" + ] + # + # text objects instantiated within the same alsaconf node must have unique + # instance attribute + # + unique "instance" + } +} diff --git a/tools/topology/topology2/include/controls/enum.conf b/tools/topology/topology2/include/controls/enum.conf new file mode 100644 index 000000000000..349f062475c1 --- /dev/null +++ b/tools/topology/topology2/include/controls/enum.conf @@ -0,0 +1,97 @@ +# +# Enum kcontrol class. All attributes defined herein are namespaced +# by alsatplg to "Object.Control.enum.N.attribute_name" +# +# Usage: this component can be used by instantiating it in the parent object. i.e. +# +# Object.Control.enum."N" { +# index 1 +# name "Master Playback Enum Control" +# Object.Base.text.1 { +# name "mytext" +# !values [ +# "One" +# "Two" +# "Three" +# ] +# } +# Object.Base.channel.1 { +# name "fc" +# shift 0 +# reg 0 +# } +# Object.Base.ops."ctl" { +# info "enum" +# get "257" +# put "257" +# } +# } +# +# Where N is the unique instance number for the buffer object within the same alsaconf node. +# The enum control object should also include the ops, channels and tlv objects in the object +# instance + +<include/controls/common.conf> + +Class.Control."enum" { + # + # Pipeline ID for the enum object + # + DefineAttribute."index" {} + + # + # Instance of enum object in the same alsaconf node + # + DefineAttribute."instance" {} + + # + # Enum name. A enum object is included in the built topology only if it is given a + # name + # + DefineAttribute."name" { + type "string" + } + + # + # access control for enum + # + DefineAttribute."access" { + type "compound" + constraints { + !valid_values [ + "read_write" + "tlv_read_write" + "read" + "write" + "volatile" + "tlv_read" + "tlv_write" + "tlv_command" + "inactive" + "lock" + "owner" + "tlv_callback" + ] + } + } + + attributes { + # + # The Enum object name would be constructed using the index and instance arguments. + # For ex: "enum.1.1" or "enum.10.2" etc. + # + !constructor [ + "index" + "instance" + ] + !mandatory [ + name + ] + # + # enum control objects instantiated within the same alsaconf node must have unique + # index attribute + # + unique "instance" + } + +} diff --git a/tools/topology/topology2/include/controls/mixer.conf b/tools/topology/topology2/include/controls/mixer.conf index 66b5085cf857..191230ec5bdc 100644 --- a/tools/topology/topology2/include/controls/mixer.conf +++ b/tools/topology/topology2/include/controls/mixer.conf @@ -1,41 +1,45 @@ -# -# Mixer kcontrol class. All attributes defined herein are namespaced -# by alsatplg to "Object.Control.mixer.N.attribute_name" -# -# Usage: this component can be used by instantiating it in the parent object. i.e. -# -# Object.Control.mixer."N" { -# index 1 -# name "1 Master Playback Volume" -# mas 32 -# Object.Base.channel.1 { -# name "fl" -# shift 0 -# reg 0 -# } -# Object.Base.channel.2 { -# name "fr" -# shift 1 -# reg 1 -# } -# Object.Base.ops."ctl" { -# info "volsw" -# get "258" -# put "258" -# } -# } -# -# Where N is the unique instance number for the buffer object within the same alsaconf node. -# The mixer control object should also include the ops, channels and tlv objects in the object -# instance +## \struct mixer +## \brief Topology Mixer class +## +## All attributes defined herein are namespaced +## by alsatplg to "Object.Control.mixer.N.attribute_name" +## +## Usage: this component can be used by instantiating it in the parent object. i.e. +## +## Object.Control.mixer."N" { +## index 1 +## name "1 Master Playback Volume" +## max 32 +## Object.Base.channel.1 { +## name "fl" +## shift 0 +## reg 0 +## } +## Object.Base.channel.2 { +## name "fr" +## shift 1 +## reg 1 +## } +## Object.Base.ops."ctl" { +## info "volsw" +## get "258" +## put "258" +## } +## } +## +## The linked object instaces are \link channel \endlink and \link ops \endlink . +## +## Where N is the unique instance number for the buffer object within the same alsaconf node. +## The mixer control object should also include the ops, channels and tlv objects in the object +## instance <include/controls/common.conf> Class.Control."mixer" { - # - # Pipeline ID for the mixer object - # - DefineAttribute."index" {} + ## + ## @ Pipeline ID for the mixer object + ## + DefineAttribute."index" {} ##< Automatically given unique index # # Instance of mixer object in the same alsaconf node diff --git a/tools/topology/topology2/include/dais/mic_extension.conf b/tools/topology/topology2/include/dais/mic_extension.conf index 6dc12a1f21b2..31628e9b2241 100644 --- a/tools/topology/topology2/include/dais/mic_extension.conf +++ b/tools/topology/topology2/include/dais/mic_extension.conf @@ -1,3 +1,6 @@ +## \brief Mic extension class +## \struct mic_extension + Class.Base."mic_extension" { DefineAttribute."id" {} diff --git a/tools/topology/topology2/include/dais/pdm_config.conf b/tools/topology/topology2/include/dais/pdm_config.conf index 2a8759a7742c..3745bea7998e 100644 --- a/tools/topology/topology2/include/dais/pdm_config.conf +++ b/tools/topology/topology2/include/dais/pdm_config.conf @@ -1,3 +1,6 @@ +## \brief Class for PDM config +## \struct pdm_config + Class.Base."pdm_config" { DefineAttribute."instance" {} # diff --git a/tools/topology/topology2/include/pipelines/cavs/dai-copier-be.conf b/tools/topology/topology2/include/pipelines/cavs/dai-copier-be.conf index d17e651316b9..4a597637ce50 100644 --- a/tools/topology/topology2/include/pipelines/cavs/dai-copier-be.conf +++ b/tools/topology/topology2/include/pipelines/cavs/dai-copier-be.conf @@ -16,14 +16,13 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/dai-copier.conf> <include/components/pipeline.conf> Class.Pipeline."dai-copier-be" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -41,46 +40,59 @@ Class.Pipeline."dai-copier-be" { num_output_audio_formats 3 num_output_pins 1 - # 32-bit 48KHz 2ch - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 32-bit 48KHz 4ch - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } - # 24-bit 48KHz 2ch - Object.Base.audio_format.3 { - in_bit_depth 32 - in_valid_bit_depth 24 - out_bit_depth 32 - out_valid_bit_depth 24 - out_sample_type $SAMPLE_TYPE_MSB_INTEGER - out_fmt_cfg "$[($out_channels | ($out_valid_bit_depth * 256))]" - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + { + in_bit_depth 32 + in_valid_bit_depth 24 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + { + out_bit_depth 32 + out_valid_bit_depth 24 + out_sample_type $SAMPLE_TYPE_MSB_INTEGER + out_fmt_cfg "$[($out_channels | ($out_valid_bit_depth * 256))]" + } + ] } module-copier."2" { num_input_audio_formats 1 num_output_audio_formats 1 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } pipeline."1" { diff --git a/tools/topology/topology2/include/pipelines/cavs/dai-copier-eqiir-module-copier-capture.conf b/tools/topology/topology2/include/pipelines/cavs/dai-copier-eqiir-module-copier-capture.conf index 131e5969cd4e..4869a6bb3bd7 100644 --- a/tools/topology/topology2/include/pipelines/cavs/dai-copier-eqiir-module-copier-capture.conf +++ b/tools/topology/topology2/include/pipelines/cavs/dai-copier-eqiir-module-copier-capture.conf @@ -25,8 +25,6 @@ Class.Pipeline."dai-copier-eqiir-module-copier-capture" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { diff --git a/tools/topology/topology2/include/pipelines/cavs/dai-copier-gain-mixin-capture.conf b/tools/topology/topology2/include/pipelines/cavs/dai-copier-gain-mixin-capture.conf index a5ce31f7aa30..9e8d4c8b0f8a 100644 --- a/tools/topology/topology2/include/pipelines/cavs/dai-copier-gain-mixin-capture.conf +++ b/tools/topology/topology2/include/pipelines/cavs/dai-copier-gain-mixin-capture.conf @@ -16,7 +16,8 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/dai-copier.conf> <include/components/gain.conf> <include/components/mixin.conf> @@ -24,8 +25,6 @@ Class.Pipeline."dai-copier-gain-mixin-capture" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -53,12 +52,18 @@ Class.Pipeline."dai-copier-gain-mixin-capture" { num_output_pins 1 # copier only supports one format based on mixin/mixout requirements: 32-bit 48KHz 2ch - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } mixin."1" {} @@ -66,12 +71,18 @@ Class.Pipeline."dai-copier-gain-mixin-capture" { num_input_audio_formats 1 num_output_audio_formats 1 # 32-bit 48KHz 2ch - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } pipeline."1" { diff --git a/tools/topology/topology2/include/pipelines/cavs/dai-copier-gain-module-copier-capture.conf b/tools/topology/topology2/include/pipelines/cavs/dai-copier-gain-module-copier-capture.conf index 072a5f9be1be..146ab0dcf044 100644 --- a/tools/topology/topology2/include/pipelines/cavs/dai-copier-gain-module-copier-capture.conf +++ b/tools/topology/topology2/include/pipelines/cavs/dai-copier-gain-module-copier-capture.conf @@ -16,15 +16,14 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/dai-copier.conf> <include/components/gain.conf> <include/components/pipeline.conf> Class.Pipeline."dai-copier-gain-module-copier-capture" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -52,35 +51,53 @@ Class.Pipeline."dai-copier-gain-module-copier-capture" { num_output_pins 1 # copier only supports one format based on mixin/mixout requirements: 32-bit 48KHz 2ch - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } module-copier."2" { num_input_audio_formats 1 num_output_audio_formats 1 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } gain."1" { num_input_audio_formats 1 num_output_audio_formats 1 # 32-bit 48KHz 2ch - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } pipeline."1" { diff --git a/tools/topology/topology2/include/pipelines/cavs/dai-kpb-be.conf b/tools/topology/topology2/include/pipelines/cavs/dai-kpb-be.conf index 70bc4f2c8dba..71ed5dff6039 100644 --- a/tools/topology/topology2/include/pipelines/cavs/dai-kpb-be.conf +++ b/tools/topology/topology2/include/pipelines/cavs/dai-kpb-be.conf @@ -24,8 +24,6 @@ Class.Pipeline."dai-kpb-be" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -48,70 +46,78 @@ Class.Pipeline."dai-kpb-be" { num_output_audio_formats 3 num_output_pins 1 - # 32-bit 48KHz 2ch - Object.Base.audio_format.3 { - in_bit_depth 32 - in_valid_bit_depth 24 - out_bit_depth 32 - out_valid_bit_depth 24 - out_sample_type $SAMPLE_TYPE_MSB_INTEGER - out_fmt_cfg "$[($out_channels | ($out_valid_bit_depth * 256))]" - } - - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 32-bit 48KHz 4ch - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + { + in_bit_depth 32 + in_valid_bit_depth 24 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + { + out_bit_depth 32 + out_valid_bit_depth 24 + out_sample_type $SAMPLE_TYPE_MSB_INTEGER + out_fmt_cfg "$[($out_channels | ($out_valid_bit_depth * 256))]" + } + ] } kpb."1" { num_input_audio_formats 2 num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_rate 16000 - out_rate 16000 - obs 128 - in_ch_cfg $CHANNEL_CONFIG_STEREO - in_ch_map $CHANNEL_MAP_STEREO - out_ch_cfg $CHANNEL_CONFIG_STEREO - out_ch_map $CHANNEL_MAP_STEREO - in_channels 2 - out_channels 2 - out_bit_depth 32 - in_bit_depth 32 - in_valid_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_rate 16000 - out_rate 16000 - obs 128 - in_ch_cfg $CHANNEL_CONFIG_4_POINT_0 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_4_POINT_0 - out_ch_map $CHANNEL_MAP_3_POINT_1 - in_channels 4 - out_channels 4 - out_bit_depth 32 - in_bit_depth 32 - in_valid_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_rate 16000 + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_rate 16000 + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + + Object.Base.output_audio_format [ + { + out_rate 16000 + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_rate 16000 + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] } pipeline."1" { diff --git a/tools/topology/topology2/include/pipelines/cavs/deepbuffer-playback.conf b/tools/topology/topology2/include/pipelines/cavs/deepbuffer-playback.conf index fbb19283a9dd..b787551b58bf 100644 --- a/tools/topology/topology2/include/pipelines/cavs/deepbuffer-playback.conf +++ b/tools/topology/topology2/include/pipelines/cavs/deepbuffer-playback.conf @@ -16,7 +16,8 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/host-copier.conf> <include/components/mixin.conf> <include/components/pipeline.conf> @@ -24,8 +25,6 @@ Class.Pipeline."deepbuffer-playback" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -49,39 +48,43 @@ Class.Pipeline."deepbuffer-playback" { type "aif_in" node_type $HDA_HOST_OUTPUT_CLASS num_input_audio_formats 3 - num_output_audio_formats 3 + num_output_audio_formats 1 num_output_pins 1 deep_buffer_dma_ms $DEEPBUFFER_FW_DMA_MS - # 16-bit 48KHz 2ch - Object.Base.audio_format.1 { - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 24-bit 48KHz 2ch - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 24 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 32-bit 48KHz 2ch - Object.Base.audio_format.3 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + { + in_bit_depth 32 + in_valid_bit_depth 24 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } gain."1" { num_input_audio_formats 1 num_output_audio_formats 1 - # 32-bit 48KHz 2ch - Object.Base.audio_format [ + Object.Base.input_audio_format [ { in_bit_depth 32 in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { out_bit_depth 32 out_valid_bit_depth 32 } diff --git a/tools/topology/topology2/include/pipelines/cavs/gain-capture.conf b/tools/topology/topology2/include/pipelines/cavs/gain-capture.conf index 57e65070b6db..dbee6b08aec7 100644 --- a/tools/topology/topology2/include/pipelines/cavs/gain-capture.conf +++ b/tools/topology/topology2/include/pipelines/cavs/gain-capture.conf @@ -24,8 +24,6 @@ Class.Pipeline."gain-capture" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -47,58 +45,173 @@ Class.Pipeline."gain-capture" { Object.Widget { host-copier."1" { type "aif_out" - num_input_audio_formats 3 - num_output_audio_formats 3 + num_input_audio_formats 2 num_input_pins 1 - # 16-bit 48KHz 2ch - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 24-bit 48KHz 2ch - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 32-bit 48KHz 2ch - Object.Base.audio_format.3 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + in_channels 4 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + + num_output_audio_formats 6 + num_output_pins 1 + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + { + out_bit_depth 32 + out_valid_bit_depth 24 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_bit_depth 16 + out_valid_bit_depth 16 + out_channels 4 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + { + out_bit_depth 32 + out_valid_bit_depth 24 + out_channels 4 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + out_channels 4 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + node_type $HDA_HOST_INPUT_CLASS } gain."1" { - num_input_audio_formats 2 - num_output_audio_formats 2 + num_input_audio_formats 4 + num_input_pins 1 + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_bit_depth 16 + in_valid_bit_depth 16 + in_channels 4 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + in_channels 4 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] - #16-bit 48KHz 2ch - Object.Base.audio_format.1 {} - # 32-bit 48KHz 2ch - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + num_output_audio_formats 4 + num_output_pins 1 + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_bit_depth 16 + out_valid_bit_depth 16 + out_channels 4 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + out_channels 4 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] } module-copier."2" { - num_input_audio_formats 2 - num_output_audio_formats 2 - #16-bit 48KHz 2ch - Object.Base.audio_format.1 {} - # 32-bit 48KHz 2ch - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + num_input_audio_formats 4 + num_input_pins 1 + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_bit_depth 16 + in_valid_bit_depth 16 + in_channels 4 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + in_channels 4 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + + num_output_audio_formats 4 + num_output_pins 1 + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_bit_depth 16 + out_valid_bit_depth 16 + out_channels 4 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + out_channels 4 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] } pipeline."1" { diff --git a/tools/topology/topology2/include/pipelines/cavs/gain-copier-capture.conf b/tools/topology/topology2/include/pipelines/cavs/gain-copier-capture.conf index 86ee039fd90e..c63b01b7361b 100644 --- a/tools/topology/topology2/include/pipelines/cavs/gain-copier-capture.conf +++ b/tools/topology/topology2/include/pipelines/cavs/gain-copier-capture.conf @@ -17,15 +17,14 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/host-copier.conf> <include/components/gain.conf> <include/components/pipeline.conf> Class.Pipeline."gain-copier-capture" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -47,59 +46,89 @@ Class.Pipeline."gain-copier-capture" { Object.Widget { host-copier."1" { type "aif_out" - num_input_audio_formats 3 + num_input_audio_formats 1 num_output_audio_formats 3 num_input_pins 1 - # 16-bit 48KHz 2ch - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 24-bit 48KHz 2ch - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 32-bit 48KHz 2ch - Object.Base.audio_format.3 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + # 32-bit 48KHz 2ch + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + { + out_bit_depth 32 + out_valid_bit_depth 24 + } + ] node_type $HDA_HOST_INPUT_CLASS } gain."1" { num_input_audio_formats 2 num_output_audio_formats 2 - #16-bit 48KHz 2ch - Object.Base.audio_format.1 {} - # 32-bit 48KHz 2ch - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + #16-bit 48KHz 2ch + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + # 32-bit 48KHz 2ch + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + ] } module-copier."2" { num_input_audio_formats 2 num_output_audio_formats 2 - #16-bit 48KHz 2ch - #16-bit 48KHz 2ch - Object.Base.audio_format.1 {} - # 32-bit 48KHz 2ch - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + #16-bit 48KHz 2ch + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + # 32-bit 48KHz 2ch + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + ] } pipeline."1" { diff --git a/tools/topology/topology2/include/pipelines/cavs/gain-module-copier.conf b/tools/topology/topology2/include/pipelines/cavs/gain-module-copier.conf index 416a4c3b59e1..b452c42eb1f0 100644 --- a/tools/topology/topology2/include/pipelines/cavs/gain-module-copier.conf +++ b/tools/topology/topology2/include/pipelines/cavs/gain-module-copier.conf @@ -16,15 +16,14 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/dai-copier.conf> <include/components/gain.conf> <include/components/pipeline.conf> Class.Pipeline."gain-module-copier" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -49,26 +48,51 @@ Class.Pipeline."gain-module-copier" { num_input_audio_formats 2 num_output_audio_formats 2 - #16-bit 48KHz 2ch - Object.Base.audio_format.1 {} - # 32-bit 48KHz 2ch - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } module-copier."1" { num_input_audio_formats 2 num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } pipeline."1" { diff --git a/tools/topology/topology2/include/pipelines/cavs/gain-playback.conf b/tools/topology/topology2/include/pipelines/cavs/gain-playback.conf index 81aedde59f7f..84f8927fafaa 100644 --- a/tools/topology/topology2/include/pipelines/cavs/gain-playback.conf +++ b/tools/topology/topology2/include/pipelines/cavs/gain-playback.conf @@ -16,15 +16,14 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/host-copier.conf> <include/components/gain.conf> <include/components/pipeline.conf> Class.Pipeline."gain-playback" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -47,42 +46,54 @@ Class.Pipeline."gain-playback" { host-copier."1" { type "aif_in" num_input_audio_formats 3 - num_output_audio_formats 3 + num_output_audio_formats 1 num_output_pins 1 - # 16-bit 48KHz 2ch - Object.Base.audio_format.1 { - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 24-bit 48KHz 2ch - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 24 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 32-bit 48KHz 2ch - Object.Base.audio_format.3 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_bit_depth 32 + in_valid_bit_depth 24 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] node_type $HDA_HOST_OUTPUT_CLASS } gain."1" { num_input_audio_formats 2 num_output_audio_formats 2 - #16-bit 48KHz 2ch - Object.Base.audio_format.1 {} - # 32-bit 48KHz 2ch - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } pipeline."1" { diff --git a/tools/topology/topology2/include/pipelines/cavs/google-rtc-aec-capture.conf b/tools/topology/topology2/include/pipelines/cavs/google-rtc-aec-capture.conf index 6699ff23bbd0..443113559ffe 100644 --- a/tools/topology/topology2/include/pipelines/cavs/google-rtc-aec-capture.conf +++ b/tools/topology/topology2/include/pipelines/cavs/google-rtc-aec-capture.conf @@ -25,8 +25,6 @@ Class.Pipeline."google-rtc-aec-capture" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -55,50 +53,74 @@ Class.Pipeline."google-rtc-aec-capture" { period_sink_count 1 period_source_count 1 num_audio_formats 1 - num_input_audio_formats 1 - num_output_audio_formats 1 - - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 16 - out_valid_bit_depth 16 - } - } - - google-rtc-aec."1" { - Object.Control.bytes."1" { - name google-rtc-aec_blob - access [ - tlv_read - tlv_callback - ] + num_input_audio_formats 2 + num_output_audio_formats 2 - Object.Base.extops."extctl" { - get 258 - put 0 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 } - max 4096 - - IncludeByKey.GOOGLE_RTC_AEC_SUPPORT { - "[1]" "include/components/google-rtc-aec/rtc-aec-blob.conf" + # 4ch 32-bit on Pin 0 + { + input_pin_index 0 + in_bit_depth 32 + in_valid_bit_depth 32 + in_channels 4 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + { + out_bit_depth 16 + out_valid_bit_depth 16 + out_channels 4 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 } - } - } + + ] + } module-copier."2" { period_sink_count 1 period_source_count 1 - num_audio_formats 1 - num_input_audio_formats 1 - num_output_audio_formats 1 + num_input_audio_formats 2 + num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 16 - in_valid_bit_depth 16 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + { + in_bit_depth 16 + in_valid_bit_depth 16 + in_channels 4 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + Object.Base.output_audio_format [ + # 2ch 32-bit + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + # 4ch 32-bit + { + out_bit_depth 32 + out_valid_bit_depth 32 + out_channels 4 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] } } diff --git a/tools/topology/topology2/include/pipelines/cavs/highpass-capture-be.conf b/tools/topology/topology2/include/pipelines/cavs/highpass-capture-be.conf index 6475b9b719c3..f80a43acb0a3 100644 --- a/tools/topology/topology2/include/pipelines/cavs/highpass-capture-be.conf +++ b/tools/topology/topology2/include/pipelines/cavs/highpass-capture-be.conf @@ -17,7 +17,8 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/dai-copier.conf> <include/components/pipeline.conf> <include/controls/bytes.conf> @@ -25,8 +26,6 @@ Class.Pipeline."highpass-capture-be" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -44,24 +43,36 @@ Class.Pipeline."highpass-capture-be" { num_output_audio_formats 1 num_output_pins 1 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } eqiir."1" { num_input_audio_formats 1 num_output_audio_formats 1 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] Object.Control.bytes."1" { <include/components/eqiir/highpass_40hz_0db_48khz.conf> diff --git a/tools/topology/topology2/include/pipelines/cavs/host-copier-gain-mixin-playback.conf b/tools/topology/topology2/include/pipelines/cavs/host-copier-gain-mixin-playback.conf index 814e78252eb8..8a2665c20bce 100644 --- a/tools/topology/topology2/include/pipelines/cavs/host-copier-gain-mixin-playback.conf +++ b/tools/topology/topology2/include/pipelines/cavs/host-copier-gain-mixin-playback.conf @@ -16,7 +16,8 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/host-copier.conf> <include/components/mixin.conf> <include/components/pipeline.conf> @@ -24,8 +25,6 @@ Class.Pipeline."host-copier-gain-mixin-playback" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -49,27 +48,28 @@ Class.Pipeline."host-copier-gain-mixin-playback" { type "aif_in" node_type $HDA_HOST_OUTPUT_CLASS num_input_audio_formats 3 - num_output_audio_formats 3 + num_output_audio_formats 1 num_output_pins 1 - # 16-bit 48KHz 2ch - Object.Base.audio_format.1 { - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 24-bit 48KHz 2ch - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 24 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 32-bit 48KHz 2ch - Object.Base.audio_format.3 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_bit_depth 32 + in_valid_bit_depth 24 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } gain."1" { @@ -77,10 +77,14 @@ Class.Pipeline."host-copier-gain-mixin-playback" { num_output_audio_formats 1 # 32-bit 48KHz 2ch - Object.Base.audio_format [ + Object.Base.input_audio_format [ { in_bit_depth 32 in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { out_bit_depth 32 out_valid_bit_depth 32 } diff --git a/tools/topology/topology2/include/pipelines/cavs/host-copier-gain-src-mixin-playback.conf b/tools/topology/topology2/include/pipelines/cavs/host-copier-gain-src-mixin-playback.conf index 05ab5ea46c05..b55f2a18c62f 100644 --- a/tools/topology/topology2/include/pipelines/cavs/host-copier-gain-src-mixin-playback.conf +++ b/tools/topology/topology2/include/pipelines/cavs/host-copier-gain-src-mixin-playback.conf @@ -26,8 +26,6 @@ Class.Pipeline."host-copier-gain-src-mixin-playback" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { diff --git a/tools/topology/topology2/include/pipelines/cavs/host-gateway-capture.conf b/tools/topology/topology2/include/pipelines/cavs/host-gateway-capture.conf index deb9df7f9650..84a4cc46cf7f 100644 --- a/tools/topology/topology2/include/pipelines/cavs/host-gateway-capture.conf +++ b/tools/topology/topology2/include/pipelines/cavs/host-gateway-capture.conf @@ -16,14 +16,13 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/host-copier.conf> <include/components/pipeline.conf> Class.Pipeline."host-gateway-capture" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -47,64 +46,57 @@ Class.Pipeline."host-gateway-capture" { type "aif_out" node_type $HDA_HOST_INPUT_CLASS num_input_pins 1 - num_input_audio_formats 6 + num_input_audio_formats 2 num_output_audio_formats 6 - # 16-bit output format 48KHz 2ch. Input sample format is always 32-bit for capture - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 24-bit 48KHz 2ch - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 24 - } - # 32-bit 48KHz 2ch - Object.Base.audio_format.3 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 16-bit output format 48KHz 4ch. Input sample format is always 32-bit for capture - Object.Base.audio_format.4 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } - # 24-bit 48KHz 2ch - Object.Base.audio_format.5 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 24 - out_channels 4 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } - # 32-bit 48KHz 4ch - Object.Base.audio_format.6 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - out_channels 4 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + # Input sample format is always 32-bit for capture + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + in_channels 4 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 24 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + { + out_bit_depth 32 + out_valid_bit_depth 24 + out_channels 4 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + out_channels 4 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + { + out_bit_depth 16 + out_valid_bit_depth 16 + out_channels 4 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] } pipeline."1" { diff --git a/tools/topology/topology2/include/pipelines/cavs/host-gateway-playback.conf b/tools/topology/topology2/include/pipelines/cavs/host-gateway-playback.conf index 577513ad77b4..29417fcc3b25 100644 --- a/tools/topology/topology2/include/pipelines/cavs/host-gateway-playback.conf +++ b/tools/topology/topology2/include/pipelines/cavs/host-gateway-playback.conf @@ -18,12 +18,11 @@ <include/components/host-copier.conf> <include/components/pipeline.conf> -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> Class.Pipeline."host-gateway-playback" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -48,26 +47,28 @@ Class.Pipeline."host-gateway-playback" { type "aif_in" num_output_pins 1 num_input_audio_formats 3 - num_output_audio_formats 3 - # 16-bit input format 48KHz 2ch. Output sample format is always 32-bit for playback - Object.Base.audio_format.1 { - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 24-bit 48KHz 2ch - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 24 - out_bit_depth 32 - out_valid_bit_depth 32 - } - # 32-bit 48KHz 2ch - Object.Base.audio_format.3 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + num_output_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + { + in_bit_depth 32 + in_valid_bit_depth 24 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + # Output sample format is always 32-bit for playback + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } pipeline."1" { diff --git a/tools/topology/topology2/include/pipelines/cavs/io-gateway-capture.conf b/tools/topology/topology2/include/pipelines/cavs/io-gateway-capture.conf index af2094d32ecf..8216a07a0878 100644 --- a/tools/topology/topology2/include/pipelines/cavs/io-gateway-capture.conf +++ b/tools/topology/topology2/include/pipelines/cavs/io-gateway-capture.conf @@ -17,14 +17,13 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/dai-copier.conf> <include/components/pipeline.conf> Class.Pipeline."io-gateway-capture" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -42,12 +41,18 @@ Class.Pipeline."io-gateway-capture" { num_output_audio_formats 1 num_output_pins 1 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } pipeline."1" { diff --git a/tools/topology/topology2/include/pipelines/cavs/io-gateway.conf b/tools/topology/topology2/include/pipelines/cavs/io-gateway.conf index fd160d0d4721..106a17ec463b 100644 --- a/tools/topology/topology2/include/pipelines/cavs/io-gateway.conf +++ b/tools/topology/topology2/include/pipelines/cavs/io-gateway.conf @@ -24,8 +24,6 @@ Class.Pipeline."io-gateway" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { diff --git a/tools/topology/topology2/include/pipelines/cavs/mixout-aria-gain-mixin-playback.conf b/tools/topology/topology2/include/pipelines/cavs/mixout-aria-gain-mixin-playback.conf index 65ae5c009a4e..5bb171977c56 100644 --- a/tools/topology/topology2/include/pipelines/cavs/mixout-aria-gain-mixin-playback.conf +++ b/tools/topology/topology2/include/pipelines/cavs/mixout-aria-gain-mixin-playback.conf @@ -16,7 +16,8 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/mixin.conf> <include/components/gain.conf> <include/components/mixout.conf> @@ -25,8 +26,6 @@ Class.Pipeline."mixout-aria-gain-mixin-playback" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -53,10 +52,14 @@ Class.Pipeline."mixout-aria-gain-mixin-playback" { num_output_audio_formats 1 # 32-bit 48KHz 2ch - Object.Base.audio_format [ + Object.Base.input_audio_format [ { in_bit_depth 32 in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { out_bit_depth 32 out_valid_bit_depth 32 } diff --git a/tools/topology/topology2/include/pipelines/cavs/mixout-dai-copier-playback.conf b/tools/topology/topology2/include/pipelines/cavs/mixout-dai-copier-playback.conf index d426a4d0dac8..a125bbf6fc8f 100644 --- a/tools/topology/topology2/include/pipelines/cavs/mixout-dai-copier-playback.conf +++ b/tools/topology/topology2/include/pipelines/cavs/mixout-dai-copier-playback.conf @@ -16,15 +16,14 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/dai-copier.conf> <include/components/mixout.conf> <include/components/pipeline.conf> Class.Pipeline."mixout-dai-copier-playback" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -52,10 +51,14 @@ Class.Pipeline."mixout-dai-copier-playback" { num_input_pins 1 # copier only supports one format based on mixin/mixout requirements: 32-bit 48KHz 2ch - Object.Base.audio_format [ + Object.Base.input_audio_format [ { in_bit_depth 32 in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { out_bit_depth 32 out_valid_bit_depth 32 } diff --git a/tools/topology/topology2/include/pipelines/cavs/mixout-gain-alh-dai-copier-playback.conf b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-alh-dai-copier-playback.conf index a66f846f7d04..ab8ab712c929 100644 --- a/tools/topology/topology2/include/pipelines/cavs/mixout-gain-alh-dai-copier-playback.conf +++ b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-alh-dai-copier-playback.conf @@ -22,8 +22,6 @@ Class.Pipeline."mixout-gain-alh-dai-copier-playback" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { diff --git a/tools/topology/topology2/include/pipelines/cavs/mixout-gain-dai-copier-playback.conf b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-dai-copier-playback.conf index c90d71556224..06887d0cd9ab 100644 --- a/tools/topology/topology2/include/pipelines/cavs/mixout-gain-dai-copier-playback.conf +++ b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-dai-copier-playback.conf @@ -16,7 +16,8 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/dai-copier.conf> <include/components/gain.conf> <include/components/mixout.conf> @@ -24,8 +25,6 @@ Class.Pipeline."mixout-gain-dai-copier-playback" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -53,10 +52,14 @@ Class.Pipeline."mixout-gain-dai-copier-playback" { num_input_pins 1 # copier only supports one format based on mixin/mixout requirements: 32-bit 48KHz 2ch - Object.Base.audio_format [ + Object.Base.input_audio_format [ { in_bit_depth 32 in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { out_bit_depth 32 out_valid_bit_depth 32 } @@ -66,11 +69,14 @@ Class.Pipeline."mixout-gain-dai-copier-playback" { num_input_audio_formats 1 num_output_audio_formats 1 - # 32-bit 48KHz 2ch - Object.Base.audio_format [ + Object.Base.input_audio_format [ { in_bit_depth 32 in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { out_bit_depth 32 out_valid_bit_depth 32 } diff --git a/tools/topology/topology2/include/pipelines/cavs/mixout-gain-efx-dai-copier-playback.conf b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-efx-dai-copier-playback.conf index 93dc0e64c893..c8f443c4c497 100644 --- a/tools/topology/topology2/include/pipelines/cavs/mixout-gain-efx-dai-copier-playback.conf +++ b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-efx-dai-copier-playback.conf @@ -16,21 +16,20 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/dai-copier.conf> <include/components/gain.conf> <include/components/mixout.conf> <include/components/pipeline.conf> <include/controls/bytes.conf> -<include/components/eqfir.conf> <include/components/eqiir.conf> +<include/components/eqfir.conf> <include/components/drc.conf> <platform/intel/efx-default.conf> Class.Pipeline."mixout-gain-efx-dai-copier-playback" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -58,10 +57,14 @@ Class.Pipeline."mixout-gain-efx-dai-copier-playback" { num_input_pins 1 # copier only supports one format based on mixin/mixout requirements: 32-bit 48KHz 2ch - Object.Base.audio_format [ + Object.Base.input_audio_format [ { in_bit_depth 32 in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { out_bit_depth 32 out_valid_bit_depth 32 } @@ -72,10 +75,14 @@ Class.Pipeline."mixout-gain-efx-dai-copier-playback" { num_output_audio_formats 1 # 32-bit 48KHz 2ch - Object.Base.audio_format [ + Object.Base.input_audio_format [ { in_bit_depth 32 in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { out_bit_depth 32 out_valid_bit_depth 32 } @@ -86,10 +93,14 @@ Class.Pipeline."mixout-gain-efx-dai-copier-playback" { num_output_audio_formats 1 # 32-bit 48KHz 2ch - Object.Base.audio_format [ + Object.Base.input_audio_format [ { in_bit_depth 32 in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { out_bit_depth 32 out_valid_bit_depth 32 } @@ -106,10 +117,14 @@ Class.Pipeline."mixout-gain-efx-dai-copier-playback" { num_output_audio_formats 1 # 32-bit 48KHz 2ch - Object.Base.audio_format [ + Object.Base.input_audio_format [ { in_bit_depth 32 in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { out_bit_depth 32 out_valid_bit_depth 32 } @@ -126,10 +141,14 @@ Class.Pipeline."mixout-gain-efx-dai-copier-playback" { num_output_audio_formats 1 # 32-bit 48KHz 2ch - Object.Base.audio_format [ + Object.Base.input_audio_format [ { in_bit_depth 32 in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { out_bit_depth 32 out_valid_bit_depth 32 } diff --git a/tools/topology/topology2/include/pipelines/cavs/mixout-gain-efx-mbdrc-dai-copier-playback.conf b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-efx-mbdrc-dai-copier-playback.conf new file mode 100644 index 000000000000..70167085bad3 --- /dev/null +++ b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-efx-mbdrc-dai-copier-playback.conf @@ -0,0 +1,197 @@ +# +# BE playback pipeline: mixout-gain-efx-mbdrc-dai-copier. +# +# All attributes defined herein are namespaced +# by alsatplg to "Object.Pipeline.mixout-gain-efx-mbdrc-dai-copier-playback.N.attribute_name" +# +# Usage: mixout-gain-efx-mbdrc-dai-copier-playback pipeline object can be instantiated as: +# +# Object.Pipeline.mixout-gain-efx-mbdrc-dai-copier-playback."N" { +# period 1000 +# time_domain "timer" +# channels 2 +# rate 48000 +# } +# +# Where N is the unique pipeline ID within the same alsaconf node. +# + +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> +<include/components/dai-copier.conf> +<include/components/gain.conf> +<include/components/mixout.conf> +<include/components/pipeline.conf> +<include/controls/bytes.conf> +<include/components/eqiir.conf> +<include/components/eqfir.conf> +<include/components/multiband_drc.conf> +<platform/intel/efx-default.conf> + +Class.Pipeline."mixout-gain-efx-mbdrc-dai-copier-playback" { + + <include/pipelines/pipeline-common.conf> + + attributes { + !constructor [ + "index" + ] + + !immutable [ + "direction" + ] + + # + # mixout-gain-efx-mbdrc-dai-copier-playback objects instantiated within the same alsaconf node must have + # unique instance attribute + # + unique "instance" + } + + Object.Widget { + mixout."1" {} + dai-copier."1" { + type dai_in + num_input_audio_formats 1 + num_output_audio_formats 1 + num_input_pins 1 + + # copier only supports one format based on mixin/mixout requirements: 32-bit 48KHz 2ch + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + } + gain."1" { + num_input_audio_formats 1 + num_output_audio_formats 1 + + # 32-bit 48KHz 2ch + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + } + eqiir."1" { + num_input_audio_formats 1 + num_output_audio_formats 1 + + # 32-bit 48KHz 2ch + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + + Object.Control.bytes."1" { + IncludeByKey.EFX_IIR_PARAMS { + "passthrough" "include/components/eqiir/passthrough.conf" + } + } + } + eqfir."1" { + num_input_audio_formats 1 + num_output_audio_formats 1 + + # 32-bit 48KHz 2ch + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + + Object.Control.bytes."1" { + IncludeByKey.EFX_FIR_PARAMS { + "passthrough" "include/components/eqfir/passthrough.conf" + } + } + } + multiband_drc."1" { + num_input_audio_formats 1 + num_output_audio_formats 1 + + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + + Object.Control.bytes."1" { + IncludeByKey.EFX_MBDRC_PARAMS { + "passthrough" "include/components/multiband_drc/passthrough.conf" + "default" "include/components/multiband_drc/default.conf" + } + } + } + pipeline."1" { + priority 0 + lp_mode 0 + } + } + + Object.Base { + route.1 { + source mixout..1 + sink gain..1 + } + route.2 { + source gain..1 + sink eqiir..1 + } + route.3 { + source eqiir..1 + sink eqfir..1 + } + route.4 { + source eqfir..1 + sink multiband_drc..1 + } + } + + direction "playback" + dynamic_pipeline 1 + time_domain "timer" + channels 2 + channels_min 2 + channels_max 2 + rate 48000 + rate_min 48000 + rate_max 48000 +} diff --git a/tools/topology/topology2/include/pipelines/cavs/mixout-gain-host-copier-capture.conf b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-host-copier-capture.conf index 594251d66062..3126311e93a7 100644 --- a/tools/topology/topology2/include/pipelines/cavs/mixout-gain-host-copier-capture.conf +++ b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-host-copier-capture.conf @@ -24,8 +24,6 @@ Class.Pipeline."mixout-gain-host-copier-capture" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -50,56 +48,58 @@ Class.Pipeline."mixout-gain-host-copier-capture" { host-copier."1" { type "aif_out" node_type $HDA_HOST_INPUT_CLASS - num_input_audio_formats 4 - num_output_audio_formats 4 + num_input_audio_formats 2 + num_output_audio_formats 3 num_input_pins 1 - # 16-bit 48KHz 2ch - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 24-bit 48KHz 2ch - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 24 - } - - Object.Base.audio_format.3 { - in_bit_depth 32 - in_valid_bit_depth 24 - out_bit_depth 32 - out_valid_bit_depth 24 - } - - # 32-bit 48KHz 2ch - Object.Base.audio_format.4 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 24 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 24 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + ] } gain."1"{ num_input_audio_formats 2 num_output_audio_formats 2 - - # 32-bit 48KHz 2ch - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 24 - out_bit_depth 32 - out_valid_bit_depth 24 - } - - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 24 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 24 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } pipeline."1" { diff --git a/tools/topology/topology2/include/pipelines/cavs/mixout-gain-smart-amp-dai-copier-playback.conf b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-smart-amp-dai-copier-playback.conf index 2272c815d1e2..f0ca0fbf6b14 100644 --- a/tools/topology/topology2/include/pipelines/cavs/mixout-gain-smart-amp-dai-copier-playback.conf +++ b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-smart-amp-dai-copier-playback.conf @@ -16,7 +16,8 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/dai-copier.conf> <include/components/gain.conf> <include/components/mixout.conf> @@ -52,10 +53,14 @@ Class.Pipeline."mixout-gain-smart-amp-dai-copier-playback" { num_input_pins 1 # copier only supports one format based on mixin/mixout requirements: 32-bit 48KHz 2ch - Object.Base.audio_format [ + Object.Base.input_audio_format [ { in_bit_depth 32 in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { out_bit_depth 32 out_valid_bit_depth 32 } @@ -66,10 +71,14 @@ Class.Pipeline."mixout-gain-smart-amp-dai-copier-playback" { num_output_audio_formats 1 # 32-bit 48KHz 2ch - Object.Base.audio_format [ + Object.Base.input_audio_format [ { in_bit_depth 32 in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { out_bit_depth 32 out_valid_bit_depth 32 } @@ -80,23 +89,25 @@ Class.Pipeline."mixout-gain-smart-amp-dai-copier-playback" { num_input_audio_formats 2 num_output_audio_formats 1 # 32-bit 48KHz 2ch - Object.Base.input_audio_format { - 1 { + Object.Base.input_audio_format [ + { input_pin_index 0 in_bit_depth 32 in_valid_bit_depth 32 } - 2 { + { input_pin_index 1 in_bit_depth 32 in_valid_bit_depth 32 } - } - Object.Base.output_audio_format.1 { + ] + Object.Base.output_audio_format [ + { output_pin_index 0 out_bit_depth 32 out_valid_bit_depth 32 - } + } + ] } pipeline."1" { diff --git a/tools/topology/topology2/include/pipelines/cavs/mixout-mixin.conf b/tools/topology/topology2/include/pipelines/cavs/mixout-mixin.conf index 0b895ae36fed..cdd40b90f9af 100644 --- a/tools/topology/topology2/include/pipelines/cavs/mixout-mixin.conf +++ b/tools/topology/topology2/include/pipelines/cavs/mixout-mixin.conf @@ -20,8 +20,6 @@ Class.Pipeline."mixout-mixin" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { diff --git a/tools/topology/topology2/include/pipelines/cavs/src-gain-mixin-playback.conf b/tools/topology/topology2/include/pipelines/cavs/src-gain-mixin-playback.conf index 36a2e29a7824..1394c45d411a 100644 --- a/tools/topology/topology2/include/pipelines/cavs/src-gain-mixin-playback.conf +++ b/tools/topology/topology2/include/pipelines/cavs/src-gain-mixin-playback.conf @@ -26,8 +26,6 @@ Class.Pipeline."src-gain-mixin-playback" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -61,22 +59,35 @@ Class.Pipeline."src-gain-mixin-playback" { gain."1" { num_input_audio_formats 3 num_output_audio_formats 3 - #16-bit 48KHz 2ch - Object.Base.audio_format.1 {} - - Object.Base.audio_format.2 { - in_bit_depth 32 - in_valid_bit_depth 24 - out_bit_depth 32 - out_valid_bit_depth 24 - } - - Object.Base.audio_format.3 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 16 + in_valid_bit_depth 16 + } + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_bit_depth 32 + in_valid_bit_depth 24 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_bit_depth 32 + out_valid_bit_depth 24 + } + ] + } mixin."1" { } diff --git a/tools/topology/topology2/include/pipelines/cavs/wov-detect.conf b/tools/topology/topology2/include/pipelines/cavs/wov-detect.conf index b804110a921f..b4d0466ea7be 100644 --- a/tools/topology/topology2/include/pipelines/cavs/wov-detect.conf +++ b/tools/topology/topology2/include/pipelines/cavs/wov-detect.conf @@ -17,7 +17,8 @@ # Where N is the unique pipeline ID within the same alsaconf node. # -<include/common/audio_format.conf> +<include/common/input_audio_format.conf> +<include/common/output_audio_format.conf> <include/components/dai-copier.conf> <include/components/micsel.conf> <include/components/wov.conf> @@ -26,8 +27,6 @@ Class.Pipeline."wov-detect" { - DefineAttribute."index" {} - <include/pipelines/pipeline-common.conf> attributes { @@ -61,39 +60,49 @@ Class.Pipeline."wov-detect" { } micsel."1" { - Object.Base.audio_format.1 { - in_rate 16000 - out_rate 16000 - in_channels 2 - out_channels 1 - in_ch_map $CHANNEL_MAP_STEREO - in_ch_cfg 1 - out_ch_map $CHANNEL_MAP_MONO - out_ch_cfg 0 - out_bit_depth 32 - in_bit_depth 32 - in_valid_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_rate 16000 + in_channels 2 + in_ch_map $CHANNEL_MAP_STEREO + in_ch_cfg 1 + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_rate 16000 + out_channels 1 + out_ch_map $CHANNEL_MAP_MONO + out_ch_cfg 0 + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } wov."1" { num_input_audio_formats 1 num_output_audio_formats 1 - Object.Base.audio_format.1 { - in_rate 16000 - out_rate 16000 - in_channels 1 - out_channels 1 - in_ch_cfg 0 - in_ch_map $CHANNEL_MAP_MONO - out_bit_depth 32 - in_bit_depth 32 - in_valid_bit_depth 32 - out_valid_bit_depth 32 - ibs 0x80 - obs 0x80 - } + Object.Base.input_audio_format [ + { + in_rate 16000 + in_channels 1 + in_ch_cfg 0 + in_ch_map $CHANNEL_MAP_MONO + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_rate 16000 + out_channels 1 + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } pipeline."1" { diff --git a/tools/topology/topology2/include/pipelines/volume-playback.conf b/tools/topology/topology2/include/pipelines/volume-playback.conf index d04830b2168a..fa007609ab4c 100644 --- a/tools/topology/topology2/include/pipelines/volume-playback.conf +++ b/tools/topology/topology2/include/pipelines/volume-playback.conf @@ -1,24 +1,26 @@ -# -# Volume playback pipeline -# -# A simple pipeline. All attributes defined herein are namespaced by alsatplg to -# "Object.Pipeline.volume-playback.N.attribute_name" -# -# Usage: this component can be used by declaring in the top-level topology conf file as follows: -# -# Object.Pipeline.volume-playback."N" { -# format "s16le" -# period 1000 -# time_domain "timer" -# channels 2 -# rate 48000 -# } -# -# where N is the unique pipeline_id for this pipeline object within the same alsaconf node. -# -# -# (source) host.N.playback -> buffer.N.1 -> volume.N.1 -> buffer.N.2 (sink endpoint) -# +## \struct volume_playback +## \brief Volume playback pipeline +## +## \par Instantiating volume-playback pipeline +## +## A simple pipeline. All attributes defined herein are namespaced by alsatplg +## to "Object.Pipeline.volume-playback.N.attribute_name" +## +## Usage: this component can be used by declaring in the top-level topology conf file as follows: +## +## Object.Pipeline.volume-playback."N" { +## format "s16le" +## period 1000 +## time_domain "timer" +## channels 2 +## rate 48000 +## } +## +## where N is the unique pipeline_id for this pipeline object within the same alsaconf node. +## +## +## (source) host.N.playback -> buffer.N.1 -> volume.N.1 -> buffer.N.2 (sink endpoint) +## <include/common/route.conf> <include/components/buffer.conf> @@ -31,7 +33,7 @@ Class.Pipeline."volume-playback" { <include/pipelines/pipeline-common.conf> attributes { - # pipeline name is constructed as "volume-playback.1" + ## pipeline name is constructed as "volume-playback.1" !constructor [ "index" ] @@ -49,9 +51,11 @@ Class.Pipeline."volume-playback" { } Object.Widget { + ## The pipeline object for captured playback pipeline."1" {} host."playback" { + ## "aif_in" is for playback type "aif_in" } diff --git a/tools/topology/topology2/platform/intel/bt-generic.conf b/tools/topology/topology2/platform/intel/bt-generic.conf index 57965f36b562..85c121a01026 100644 --- a/tools/topology/topology2/platform/intel/bt-generic.conf +++ b/tools/topology/topology2/platform/intel/bt-generic.conf @@ -26,34 +26,38 @@ Object.Pipeline { num_output_audio_formats 3 num_input_pins 1 - Object.Base.audio_format.0 { - in_bit_depth 16 - in_valid_bit_depth 16 - out_bit_depth 16 - out_valid_bit_depth 16 - in_channels 2 - out_channels 2 - } - Object.Base.audio_format.2 { - in_bit_depth 16 - in_valid_bit_depth 16 - out_bit_depth 16 - out_valid_bit_depth 16 - in_channels 1 - out_channels 1 - in_rate 8000 - out_rate 8000 - } - Object.Base.audio_format.3 { - in_bit_depth 16 - in_valid_bit_depth 16 - out_bit_depth 16 - out_valid_bit_depth 16 - in_channels 1 - out_channels 1 - in_rate 16000 - out_rate 16000 - } + CombineArrays.Object.Base.output_audio_format [ + # array of 2ch format with range of rates + { + out_rate [ + 8000 + 16000 + ] + out_channels [ 1 ] + } + # 2ch 16-bit 48k + { + out_bit_depth [ 16 ] + out_valid_bit_depth [ 16 ] + out_channels [ 2 ] + } + ] + CombineArrays.Object.Base.input_audio_format [ + # array of 2ch format with range of rates + { + in_rate [ + 8000 + 16000 + ] + in_channels [ 1 ] + } + # 2ch 16-bit 48k + { + in_bit_depth [ 16 ] + in_valid_bit_depth [ 16 ] + in_channels [ 2 ] + } + ] } } ] @@ -69,34 +73,38 @@ Object.Pipeline { pcm_id $BT_PCM_ID num_input_audio_formats 3 num_output_audio_formats 3 - Object.Base.audio_format.0 { - in_bit_depth 16 - in_valid_bit_depth 16 - out_bit_depth 16 - out_valid_bit_depth 16 - in_channels 2 - out_channels 2 - } - Object.Base.audio_format.2 { - in_bit_depth 16 - in_valid_bit_depth 16 - out_bit_depth 16 - out_valid_bit_depth 16 - in_channels 1 - out_channels 1 - in_rate 8000 - out_rate 8000 - } - Object.Base.audio_format.3 { - in_bit_depth 16 - in_valid_bit_depth 16 - out_bit_depth 16 - out_valid_bit_depth 16 - in_channels 1 - out_channels 1 - in_rate 16000 - out_rate 16000 - } + CombineArrays.Object.Base.output_audio_format [ + # array of 2ch format with range of rates + { + out_rate [ + 8000 + 16000 + ] + out_channels [ 1 ] + } + # 2ch 16-bit 48k + { + out_bit_depth [ 16 ] + out_valid_bit_depth [ 16 ] + out_channels [ 2 ] + } + ] + CombineArrays.Object.Base.input_audio_format [ + # array of 2ch format with range of rates + { + in_rate [ + 8000 + 16000 + ] + in_channels [ 1 ] + } + # 2ch 16-bit 48k + { + in_bit_depth [ 16 ] + in_valid_bit_depth [ 16 ] + in_channels [ 2 ] + } + ] } } ] @@ -113,34 +121,38 @@ Object.Pipeline { pcm_id $BT_PCM_ID num_input_audio_formats 3 num_output_audio_formats 3 - Object.Base.audio_format.0 { - in_bit_depth 16 - in_valid_bit_depth 16 - out_bit_depth 16 - out_valid_bit_depth 16 - in_channels 2 - out_channels 2 - } - Object.Base.audio_format.2 { - in_bit_depth 16 - in_valid_bit_depth 16 - out_bit_depth 16 - out_valid_bit_depth 16 - in_channels 1 - out_channels 1 - in_rate 8000 - out_rate 8000 - } - Object.Base.audio_format.3 { - in_bit_depth 16 - in_valid_bit_depth 16 - out_bit_depth 16 - out_valid_bit_depth 16 - in_channels 1 - out_channels 1 - in_rate 16000 - out_rate 16000 - } + CombineArrays.Object.Base.output_audio_format [ + # array of 2ch format with range of rates + { + out_rate [ + 8000 + 16000 + ] + out_channels [ 1 ] + } + # 2ch 16-bit 48k + { + out_bit_depth [ 16 ] + out_valid_bit_depth [ 16 ] + out_channels [ 2 ] + } + ] + CombineArrays.Object.Base.input_audio_format [ + # array of 2ch format with range of rates + { + in_rate [ + 8000 + 16000 + ] + in_channels [ 1 ] + } + # 2ch 16-bit 48k + { + in_bit_depth [ 16 ] + in_valid_bit_depth [ 16 ] + in_channels [ 2 ] + } + ] } } ] @@ -160,36 +172,40 @@ Object.Pipeline { copier_type "SSP" stream_name $BT_NAME node_type $I2S_LINK_INPUT_CLASS - num_input_audio_formats 4 - num_output_audio_formats 4 - Object.Base.audio_format.0 { - in_bit_depth 16 - in_valid_bit_depth 16 - out_bit_depth 16 - out_valid_bit_depth 16 - in_channels 2 - out_channels 2 - } - Object.Base.audio_format.1 { - in_bit_depth 16 - in_valid_bit_depth 16 - out_bit_depth 16 - out_valid_bit_depth 16 - in_channels 1 - out_channels 1 - in_rate 8000 - out_rate 8000 - } - Object.Base.audio_format.2 { - in_bit_depth 16 - in_valid_bit_depth 16 - out_bit_depth 16 - out_valid_bit_depth 16 - in_channels 1 - out_channels 1 - in_rate 16000 - out_rate 16000 - } + num_input_audio_formats 3 + num_output_audio_formats 3 + CombineArrays.Object.Base.output_audio_format [ + # array of 2ch format with range of rates + { + out_rate [ + 8000 + 16000 + ] + out_channels [ 1 ] + } + # 2ch 16-bit 48k + { + out_bit_depth [ 16 ] + out_valid_bit_depth [ 16 ] + out_channels [ 2 ] + } + ] + CombineArrays.Object.Base.input_audio_format [ + # array of 2ch format with range of rates + { + in_rate [ + 8000 + 16000 + ] + in_channels [ 1 ] + } + # 2ch 16-bit 48k + { + in_bit_depth [ 16 ] + in_valid_bit_depth [ 16 ] + in_channels [ 2 ] + } + ] } } ] diff --git a/tools/topology/topology2/platform/intel/bt-ssp-config-lbm.conf b/tools/topology/topology2/platform/intel/bt-ssp-config-lbm.conf index 694f6939e2f6..d4060ef53c09 100644 --- a/tools/topology/topology2/platform/intel/bt-ssp-config-lbm.conf +++ b/tools/topology/topology2/platform/intel/bt-ssp-config-lbm.conf @@ -23,7 +23,7 @@ Object.Dai.SSP [ tx_slots 1 rx_slots 1 Object.Base.link_config.1 { - clock_source 0 + clock_source 1 } } Object.Base.hw_config.2 { @@ -41,7 +41,7 @@ Object.Dai.SSP [ tx_slots 1 rx_slots 1 Object.Base.link_config.1 { - clock_source 0 + clock_source 1 } } Object.Base.hw_config.3 { @@ -58,7 +58,7 @@ Object.Dai.SSP [ tx_slots 3 rx_slots 3 Object.Base.link_config.1 { - clock_source 0 + clock_source 1 } } } diff --git a/tools/topology/topology2/platform/intel/bt-ssp-config.conf b/tools/topology/topology2/platform/intel/bt-ssp-config.conf index edce4b8d1399..1a5353890f5e 100644 --- a/tools/topology/topology2/platform/intel/bt-ssp-config.conf +++ b/tools/topology/topology2/platform/intel/bt-ssp-config.conf @@ -22,7 +22,7 @@ Object.Dai.SSP [ tx_slots 1 rx_slots 1 Object.Base.link_config.1 { - clock_source 0 + clock_source 1 } } Object.Base.hw_config.2 { @@ -40,7 +40,7 @@ Object.Dai.SSP [ tx_slots 1 rx_slots 1 Object.Base.link_config.1 { - clock_source 0 + clock_source 1 } } Object.Base.hw_config.3 { @@ -57,7 +57,7 @@ Object.Dai.SSP [ tx_slots 3 rx_slots 0 Object.Base.link_config.1 { - clock_source 0 + clock_source 1 } } } diff --git a/tools/topology/topology2/platform/intel/dmic-default.conf b/tools/topology/topology2/platform/intel/dmic-default.conf index 3f1e23526bc5..0bbb288e9e03 100644 --- a/tools/topology/topology2/platform/intel/dmic-default.conf +++ b/tools/topology/topology2/platform/intel/dmic-default.conf @@ -35,4 +35,5 @@ Define { DMIC1_PCM_CAPS 'Passthrough Capture 18' DMIC_CORE_ID 0 PASSTHROUGH "false" + DMIC_PIPELINE_PRIORITY 0 } diff --git a/tools/topology/topology2/platform/intel/dmic-generic.conf b/tools/topology/topology2/platform/intel/dmic-generic.conf index 006505ca011f..5ca0ec27c79b 100644 --- a/tools/topology/topology2/platform/intel/dmic-generic.conf +++ b/tools/topology/topology2/platform/intel/dmic-generic.conf @@ -82,46 +82,63 @@ IncludeByKey.PASSTHROUGH { pcm_id $DMIC0_PCM_ID num_input_audio_formats 2 num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] } Object.Widget.gain.1 { + curve_duration 500000 num_input_audio_formats 2 num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] Object.Control.mixer.1 { name '$DMIC0_PCM_NAME Capture Volume' } @@ -130,24 +147,32 @@ IncludeByKey.PASSTHROUGH { Object.Widget.module-copier."2" { num_input_audio_formats 2 num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] } Object.Widget.pipeline."1" { core $DMIC_CORE_ID @@ -180,6 +205,7 @@ IncludeByKey.PASSTHROUGH { } Object.Widget.pipeline."1" { core $DMIC_CORE_ID + priority $DMIC_PIPELINE_PRIORITY } } ] diff --git a/tools/topology/topology2/platform/intel/dmic-wov.conf b/tools/topology/topology2/platform/intel/dmic-wov.conf index 6dc4a2619b8b..0094941e0c74 100644 --- a/tools/topology/topology2/platform/intel/dmic-wov.conf +++ b/tools/topology/topology2/platform/intel/dmic-wov.conf @@ -10,28 +10,22 @@ Object.Pipeline { Object.Widget.host-copier.1 { stream_name $DMIC1_PCM_CAPS pcm_id 11 - Object.Base.audio_format.1 { - in_rate 16000 - in_bit_depth 32 - in_valid_bit_depth 32 - out_rate 16000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_rate 16000 - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_rate 16000 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + num_output_audio_formats 2 + Object.Base.output_audio_format [ + { + out_rate 16000 + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_rate 16000 + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] } } ] @@ -55,28 +49,37 @@ Object.Pipeline { node_type $DMIC_LINK_INPUT_CLASS num_input_audio_formats 2 num_output_audio_formats 2 - Object.Base.audio_format.1 { - in_rate 16000 - in_bit_depth 32 - in_valid_bit_depth 32 - out_rate 16000 - out_bit_depth 32 - out_valid_bit_depth 32 - } - Object.Base.audio_format.2 { - in_rate 16000 - in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 - out_rate 16000 - out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - in_ch_map $CHANNEL_MAP_3_POINT_1 - out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 - out_ch_map $CHANNEL_MAP_3_POINT_1 - } + Object.Base.input_audio_format [ + { + in_rate 16000 + in_bit_depth 32 + in_valid_bit_depth 32 + } + { + in_rate 16000 + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + + Object.Base.output_audio_format [ + { + out_rate 16000 + out_bit_depth 32 + out_valid_bit_depth 32 + } + { + out_rate 16000 + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] } Object.Widget.kpb.1 { diff --git a/tools/topology/topology2/platform/intel/efx-default.conf b/tools/topology/topology2/platform/intel/efx-default.conf index ed9304b4c062..6a152e68a1ef 100644 --- a/tools/topology/topology2/platform/intel/efx-default.conf +++ b/tools/topology/topology2/platform/intel/efx-default.conf @@ -3,4 +3,6 @@ Define { EFX_IIR_PARAMS 'passthrough' EFX_CROSSOVER_PARAMS '2way' EFX_DRC_PARAMS 'passthrough' + EFX_MBDRC_PARAMS 'passthrough' + EFX_DRC_COMPONENT 'singleband' } diff --git a/tools/topology/topology2/platform/intel/google-rtc-aec-reference.conf b/tools/topology/topology2/platform/intel/google-rtc-aec-reference.conf index b2e9a88ec1e9..336d31aac2e0 100644 --- a/tools/topology/topology2/platform/intel/google-rtc-aec-reference.conf +++ b/tools/topology/topology2/platform/intel/google-rtc-aec-reference.conf @@ -6,6 +6,7 @@ Object.Pipeline.google-rtc-aec-capture [ Object.Widget.pipeline.1 { stream_name "DMIC0 RTC AEC" core $GOOGLE_AEC_CORE_ID + priority $GOOGLE_AEC_PIPELINE_PRIORITY } Object.Widget.google-rtc-aec.1 { @@ -14,7 +15,7 @@ Object.Pipeline.google-rtc-aec-capture [ } Object.Base.input_pin_binding.2 { - input_pin_binding_name $GOOGLE_RTC_AEC_REF_SOURCE + input_pin_binding_name "dai-copier.SSP.$SPEAKER_CODEC_NAME.capture" } } } @@ -31,6 +32,7 @@ Object.Pipeline.host-gateway-capture[ } Object.Widget.pipeline."1" { core $GOOGLE_AEC_CORE_ID + priority $GOOGLE_AEC_HOST_PIPELINE_PRIORITY } } ] @@ -97,7 +99,7 @@ Object.Base.route [ sink module-copier.18.1 } { - source $GOOGLE_RTC_AEC_REF_SOURCE + source "dai-copier.SSP.$SPEAKER_CODEC_NAME.capture" sink "google-rtc-aec.18.1" } { diff --git a/tools/topology/topology2/platform/intel/sdw-amp-generic.conf b/tools/topology/topology2/platform/intel/sdw-amp-generic.conf index 57f3a089101d..c19423d62f2f 100644 --- a/tools/topology/topology2/platform/intel/sdw-amp-generic.conf +++ b/tools/topology/topology2/platform/intel/sdw-amp-generic.conf @@ -350,11 +350,6 @@ IncludeByKey.SDW_AMP_FEEDBACK { Object.Widget.host-copier.1 { stream_name "amp feedback" pcm_id 3 - Object.Base.audio_format.1 { - # 32 -> 16 bits conversion is done here, - # so in_bit_depth is 32 (and out_bit_depth is 16). - in_bit_depth 32 - } } } ] diff --git a/tools/topology/topology2/platform/intel/sdw-dmic-generic.conf b/tools/topology/topology2/platform/intel/sdw-dmic-generic.conf index 2d7e7e54f27f..e8b0ca2dbb31 100644 --- a/tools/topology/topology2/platform/intel/sdw-dmic-generic.conf +++ b/tools/topology/topology2/platform/intel/sdw-dmic-generic.conf @@ -30,11 +30,6 @@ Object.Pipeline { Object.Widget.host-copier.1 { stream_name "sdw dmic" pcm_id 4 - Object.Base.audio_format.1 { - # 32 -> 16 bits conversion is done here, - # so in_bit_depth is 32 (and out_bit_depth is 16). - in_bit_depth 32 - } } } ] diff --git a/tools/topology/topology2/platform/intel/sdw-jack-generic.conf b/tools/topology/topology2/platform/intel/sdw-jack-generic.conf index a05a441e5db2..1b7a4494728b 100644 --- a/tools/topology/topology2/platform/intel/sdw-jack-generic.conf +++ b/tools/topology/topology2/platform/intel/sdw-jack-generic.conf @@ -186,56 +186,85 @@ Object.Pipeline.host-gateway-capture [ Object.Widget.host-copier.1 { stream_name "Passthrough Capture 0" pcm_id 1 - num_input_audio_formats 9 + num_input_audio_formats 3 num_output_audio_formats 9 - Object.Base.audio_format.1 { - # 32/32 -> 16/16 bits conversion is done here - in_bit_depth 32 - in_valid_bit_depth 32 - } - # 32-bit 48KHz 1ch - Object.Base.input_audio_format.7 { - in_channels 1 - in_bit_depth 32 - in_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_MONO - in_ch_map $CHANNEL_MAP_MONO - } - Object.Base.output_audio_format.7 { - out_bit_depth 32 - out_valid_bit_depth 32 - out_channels 1 - out_ch_cfg $CHANNEL_CONFIG_MONO - out_ch_map $CHANNEL_MAP_MONO - } - # 24-bit 48KHz 1ch - Object.Base.input_audio_format.8 { - in_channels 1 - in_bit_depth 32 - in_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_MONO - in_ch_map $CHANNEL_MAP_MONO - } - Object.Base.output_audio_format.8 { - out_bit_depth 32 - out_valid_bit_depth 24 - out_channels 1 - out_ch_cfg $CHANNEL_CONFIG_MONO - out_ch_map $CHANNEL_MAP_MONO - } - # 16-bit 48KHz 1ch - Object.Base.input_audio_format.9 { - in_channels 1 - in_bit_depth 32 - in_valid_bit_depth 32 - in_ch_cfg $CHANNEL_CONFIG_MONO - in_ch_map $CHANNEL_MAP_MONO - } - Object.Base.output_audio_format.9 { - out_channels 1 - out_ch_cfg $CHANNEL_CONFIG_MONO - out_ch_map $CHANNEL_MAP_MONO - } + Object.Base.input_audio_format [ + # 32-bit 48KHz 2ch + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + # 32-bit 48KHz 4ch + { + in_bit_depth 32 + in_valid_bit_depth 32 + in_channels 4 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + # 32-bit 48KHz 1ch + { + in_channels 1 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_MONO + in_ch_map $CHANNEL_MAP_MONO + } + ] + + CombineArrays.Object.Base.output_audio_format [ + # array of 2ch formats with range of out valid bit depths + { + out_bit_depth [ 32 ] + out_valid_bit_depth [ + 24 + 32 + ] + } + # array of 4ch formats with range of out valid bit depths + { + out_bit_depth [ 32 ] + out_valid_bit_depth [ + 24 + 32 + ] + out_channels [ 4 ] + out_ch_cfg [ $CHANNEL_CONFIG_3_POINT_1 ] + out_ch_map [ $CHANNEL_MAP_3_POINT_1 ] + } + # array of 1ch formats with range of out valid bit depths + { + out_bit_depth [ 32 ] + out_valid_bit_depth [ + 24 + 32 + ] + out_channels [ 1 ] + out_ch_cfg [ $CHANNEL_CONFIG_MONO ] + out_ch_map [ $CHANNEL_MAP_MONO ] + } + # 16-bit 2ch + { + out_bit_depth [ 16 ] + out_valid_bit_depth [ 16 ] + } + # 16-bit 4ch + { + out_bit_depth [ 16 ] + out_valid_bit_depth [ 16 ] + out_channels [ 4 ] + out_ch_cfg [ $CHANNEL_CONFIG_3_POINT_1 ] + out_ch_map [ $CHANNEL_MAP_3_POINT_1 ] + } + # 16-bit 1ch + { + out_channels [ 1 ] + out_bit_depth [ 16 ] + out_valid_bit_depth [ 16 ] + out_ch_cfg [ $CHANNEL_CONFIG_MONO ] + out_ch_map [ $CHANNEL_MAP_MONO ] + } + ] } } ] @@ -253,12 +282,18 @@ Object.Widget { num_output_audio_formats 1 num_output_pins 1 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] } ] @@ -279,12 +314,18 @@ IncludeByKey.PASSTHROUGH { num_input_audio_formats 1 num_output_audio_formats 1 index 11 - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] Object.Control.bytes."1" { <include/components/eqiir/highpass_40hz_0db_48khz.conf> diff --git a/tools/topology/topology2/platform/intel/speaker-echo-ref.conf b/tools/topology/topology2/platform/intel/speaker-echo-ref.conf index 2ff5f3e22e5e..7119dd1568ad 100644 --- a/tools/topology/topology2/platform/intel/speaker-echo-ref.conf +++ b/tools/topology/topology2/platform/intel/speaker-echo-ref.conf @@ -1,25 +1,5 @@ -Define { - ECHO_REF_STREAM_NAME "Echo reference" -} - Object.Pipeline { - host-gateway-capture [ - { - index $ECHO_REF_HOST_PIPELINE_ID - core_id $ECHO_REF_CORE_ID - - Object.Widget.host-copier.1 { - core_id $ECHO_REF_CORE_ID - stream_name $ECHO_REF_STREAM_NAME - pcm_id $ECHO_REF_PCM_ID - } - Object.Widget.pipeline."1" { - core $ECHO_REF_CORE_ID - } - } - ] - - dai-copier-be [ + io-gateway-capture [ { index $ECHO_REF_DAI_PIPELINE_ID core_id $ECHO_REF_CORE_ID @@ -33,41 +13,25 @@ Object.Pipeline { copier_type "SSP" stream_name $SPEAKER_CODEC_NAME node_type $I2S_LINK_INPUT_CLASS - Object.Base.audio_format.1 { - in_bit_depth 32 - in_valid_bit_depth 32 - out_bit_depth 32 - out_valid_bit_depth 32 - } + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_bit_depth 16 + out_valid_bit_depth 16 + } + ] } Object.Widget.pipeline."1" { - core $ECHO_REF_CORE_ID + core $ECHO_REF_CORE_ID + priority $ECHO_REF_PIPELINE_PRIORITY } } ] } - -Object.PCM.pcm [ - { - name "EchoRef" - id $ECHO_REF_PCM_ID - direction "capture" - Object.Base.fe_dai.1 {} - - Object.PCM.pcm_caps.1 { - name $ECHO_REF_STREAM_NAME - formats 'S16_LE,S24_LE,S32_LE' - } - } -] - -Object.Base.route [ - { - source "dai-copier.SSP.$SPEAKER_CODEC_NAME.capture" - sink $ECHO_REF_COPIER_MODULE - } - { - source $ECHO_REF_COPIER_MODULE - sink "host-copier.$ECHO_REF_PCM_ID.capture" - } -] diff --git a/tools/topology/topology2/platform/intel/ssp_aux_config.conf b/tools/topology/topology2/platform/intel/ssp_aux_config.conf index 1a814edef07e..c084faa4195c 100644 --- a/tools/topology/topology2/platform/intel/ssp_aux_config.conf +++ b/tools/topology/topology2/platform/intel/ssp_aux_config.conf @@ -1,3 +1,5 @@ +## \struct mn_config + Class.Base."mn_config" { DefineAttribute."id" {} diff --git a/tools/topology/topology2/sof-ace-tplg/tplg-targets.cmake b/tools/topology/topology2/sof-ace-tplg/tplg-targets.cmake index 58837ccb7a5e..dd6402dc2c4f 100644 --- a/tools/topology/topology2/sof-ace-tplg/tplg-targets.cmake +++ b/tools/topology/topology2/sof-ace-tplg/tplg-targets.cmake @@ -35,6 +35,15 @@ SDW_JACK_OUT_STREAM=Playback-SimpleJack,SDW_JACK_IN_STREAM=Capture-SimpleJack" USE_CHAIN_DMA=true,NUM_SDW_AMP_LINKS=2,SDW_SPK_STREAM=SDW1-Playback,SDW_SPK_IN_STREAM=SDW1-Capture,\ SDW_DMIC_STREAM=SDW0-Capture" +"cavs-sdw\;sof-mtl-rt713-l0-rt1316-l12-rt1713-l3\;PLATFORM=mtl,NUM_SDW_AMP_LINKS=2,SDW_DMIC=1" + +# Jack codec + SmartAmp topology. No SDW_DMIC connection +"cavs-sdw\;sof-mtl-rt713-l0-rt1316-l12\;PLATFORM=mtl,NUM_SDW_AMP_LINKS=2,HDMI1_ID=4,HDMI2_ID=5,HDMI3_ID=6" + +"cavs-sdw\;sof-mtl-rt722-l0\;PLATFORM=mtl,SDW_DMIC=1,NUM_HDMIS=0,NUM_SDW_AMP_LINKS=1,\ +SDW_AMP_FEEDBACK=false,SDW_SPK_STREAM=Playback-SmartAmp,SDW_DMIC_STREAM=Capture-SmartMic,\ +SDW_JACK_OUT_STREAM=Playback-SimpleJack,SDW_JACK_IN_STREAM=Capture-SimpleJack" + # Below topologies are used on Chromebooks "cavs-rt5682\;sof-mtl-max98357a-rt5682\;PLATFORM=mtl,NUM_DMICS=4,PDM1_MIC_A_ENABLE=1,\ @@ -48,14 +57,14 @@ PDM1_MIC_B_ENABLE=1,DMIC0_PCM_ID=99,PREPROCESS_PLUGINS=nhlt,\ NHLT_BIN=nhlt-sof-mtl-max98357a-rt5682.bin,DEEPBUFFER_FW_DMA_MS=10,HEADSET_SSP_DAI_INDEX=2,\ SPK_ID=6,SPEAKER_SSP_DAI_INDEX=0,HEADSET_CODEC_NAME=SSP2-Codec,SPEAKER_CODEC_NAME=SSP0-Codec,\ BT_NAME=SSP1-BT,BT_INDEX=1,BT_ID=7,BT_PCM_NAME=Bluetooth,INCLUDE_ECHO_REF=true,USE_CHAIN_DMA=true,\ -DEEPBUFFER_D0I3_COMPATIBLE=true" +DEEPBUFFER_D0I3_COMPATIBLE=true,GOOGLE_RTC_AEC_SUPPORT=1" "cavs-rt5682\;sof-mtl-max98357a-rt5682-ssp2-ssp0-2ch-pdm1\;PLATFORM=mtl,NUM_DMICS=2,\ PDM0_MIC_A_ENABLE=0,PDM0_MIC_B_ENABLE=0,PDM1_MIC_A_ENABLE=1,PDM1_MIC_B_ENABLE=1,\ DMIC0_PCM_ID=99,PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-mtl-max98357a-rt5682-2ch.bin,\ HEADSET_SSP_DAI_INDEX=2,SPEAKER_SSP_DAI_INDEX=0,SPK_ID=6,HEADSET_CODEC_NAME=SSP2-Codec,SPEAKER_CODEC_NAME=SSP0-Codec,\ BT_NAME=SSP1-BT,BT_INDEX=1,BT_ID=7,BT_PCM_NAME=Bluetooth,INCLUDE_ECHO_REF=true,USE_CHAIN_DMA=true,\ -DEEPBUFFER_FW_DMA_MS=10,DEEPBUFFER_D0I3_COMPATIBLE=true" +DEEPBUFFER_FW_DMA_MS=10,DEEPBUFFER_D0I3_COMPATIBLE=true,GOOGLE_RTC_AEC_SUPPORT=1" "cavs-rt5682\;sof-mtl-rt1019-rt5682\;PLATFORM=mtl,NUM_DMICS=4,PDM1_MIC_A_ENABLE=1,\ PDM1_MIC_B_ENABLE=1,DMIC0_PCM_ID=99,SPK_ID=6,PREPROCESS_PLUGINS=nhlt,\ @@ -70,4 +79,12 @@ PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-mtl-sdw-cs42l42-l0-max98363-l2.bin,\ BT_NAME=SSP1-BT,BT_INDEX=1,BT_PCM_ID=20,BT_ID=8,BT_PCM_NAME=Bluetooth,ADD_BT=true,\ NUM_SDW_AMP_LINKS=1,SDW_SPK_STREAM=SDW2-Playback,SDW_AMP_FEEDBACK=false,\ SDW_JACK_CAPTURE_CH=1,DEEPBUFFER_FW_DMA_MS=100,DEEPBUFFER_D0I3_COMPATIBLE=true" + +# SDW topology for LNL RVP +"cavs-sdw\;sof-lnl-rt711-4ch\;PLATFORM=lnl,NUM_DMICS=4,PDM1_MIC_A_ENABLE=1,PDM1_MIC_B_ENABLE=1,\ +DMIC0_ID=2,DMIC1_ID=3,NUM_HDMIS=0,PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-lnl-rt711-4ch.bin,\ +DEEPBUFFER_FW_DMA_MS=100,DEEPBUFFER_D0I3_COMPATIBLE=true" + +"cavs-sdw\;sof-lnl-rt711-l0-rt1316-l23-rt714-l1\;PLATFORM=lnl,NUM_SDW_AMP_LINKS=2,SDW_DMIC=1,\ +NUM_HDMIS=0,SDW_SPK_STREAM=SDW2-Playback,SDW_SPK_IN_STREAM=SDW2-Capture,SDW_DMIC_STREAM=SDW1-Capture" ) diff --git a/tools/topology/topology2/sof-hda-generic.conf b/tools/topology/topology2/sof-hda-generic.conf index 1bd06bff796f..260cadb924bc 100644 --- a/tools/topology/topology2/sof-hda-generic.conf +++ b/tools/topology/topology2/sof-hda-generic.conf @@ -17,6 +17,7 @@ <mixout-gain-dai-copier-playback.conf> <mixout-aria-gain-mixin-playback.conf> <mixout-gain-efx-dai-copier-playback.conf> +<mixout-gain-efx-mbdrc-dai-copier-playback.conf> <mixout-gain-host-copier-capture.conf> <dai-copier-eqiir-module-copier-capture.conf> <gain-capture.conf> diff --git a/tools/tplg_parser/CMakeLists.txt b/tools/tplg_parser/CMakeLists.txt index 5ede07db75d6..749868fd2dd2 100644 --- a/tools/tplg_parser/CMakeLists.txt +++ b/tools/tplg_parser/CMakeLists.txt @@ -17,6 +17,12 @@ else() add_library(sof_tplg_parser SHARED "") endif() +if (CONFIG_IPC4) + set(tplg_ipc CONFIG_IPC_MAJOR_4) +else() + set(tplg_ipc CONFIG_IPC_MAJOR_3) +endif() + target_sources(sof_tplg_parser PUBLIC tokens.c process.c @@ -39,12 +45,10 @@ sof_append_relative_path_definitions(sof_tplg_parser) target_include_directories(sof_tplg_parser PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include) target_include_directories(sof_tplg_parser PRIVATE ${sof_source_directory}/src/include) +target_include_directories(sof_tplg_parser PRIVATE ${sof_source_directory}/src/audio) target_include_directories(sof_tplg_parser PRIVATE ${sof_source_directory}/src/arch/host/include) target_include_directories(sof_tplg_parser PRIVATE ${sof_source_directory}/src/platform/library/include) -target_include_directories(sof_tplg_parser PRIVATE ${sof_source_directory}/src/audio) - -# TODO: The topology parser should NOT need to include RTOS header. FIX. -target_include_directories(sof_tplg_parser PRIVATE ${sof_source_directory}/xtos/include) +target_include_directories(sof_tplg_parser PRIVATE ${sof_source_directory}/posix/include) # Configuration time, make copy configure_file(${default_asoc_h} ${CMAKE_CURRENT_BINARY_DIR}/include/alsa/sound/asoc.h) @@ -62,7 +66,7 @@ endif() target_compile_options(sof_tplg_parser PRIVATE -g -O -Wall -Werror -Wl,-EL -fPIC -DPIC -Wmissing-prototypes ${implicit_fallthrough} - -DCONFIG_LIBRARY -DCONFIG_IPC_MAJOR_3) + -DCONFIG_LIBRARY -D${tplg_ipc}) target_link_libraries(sof_tplg_parser PRIVATE -lm) diff --git a/tools/tplg_parser/include/tplg_parser/topology.h b/tools/tplg_parser/include/tplg_parser/topology.h index 83ddce2ced02..806af047e6f2 100644 --- a/tools/tplg_parser/include/tplg_parser/topology.h +++ b/tools/tplg_parser/include/tplg_parser/topology.h @@ -11,13 +11,16 @@ #define _COMMON_TPLG_H #include <stdbool.h> -#include<stdarg.h> +#include <stdarg.h> #include <stddef.h> #include <ipc/dai.h> #include <ipc/topology.h> #include <ipc/stream.h> +#include <ipc4/copier.h> +#include <ipc4/module.h> #include <kernel/tokens.h> #include <sof/list.h> +#include <volume/peak_volume.h> #ifdef TPLG_DEBUG #define DEBUG_MAX_LENGTH 256 @@ -46,6 +49,7 @@ static inline void tplg_debug(char *fmt, ...) {} #define TPLG_PARSER_SOF_DEV 1 #define TPLG_PARSER_FUZZER_DEV 2 +#define TPLG_MAX_PCM_PIPELINES 16 #define MOVE_POINTER_BY_BYTES(p, b) ((typeof(p))((uint8_t *)(p) + (b))) @@ -95,15 +99,31 @@ struct sof_ipc4_available_audio_format { uint32_t num_output_formats; }; +struct tplg_pipeline_info { + int id; + int instance_id; + int usage_count; + int mem_usage; + char *name; + struct list_item item; /* item in a list */ +}; + struct tplg_comp_info { + struct list_item item; /* item in a list */ + struct sof_ipc4_available_audio_format available_fmt; /* available formats in tplg */ + struct ipc4_module_init_instance module_init; + struct ipc4_base_module_cfg basecfg; + struct tplg_pipeline_info *pipe_info; + struct sof_uuid uuid; char *name; char *stream_name; int id; int type; int pipeline_id; void *ipc_payload; - struct list_item item; /* item in a list */ - struct sof_ipc4_available_audio_format available_fmt; /* available formats in tplg */ + int ipc_size; + int instance_id; + int module_id; }; struct tplg_route_info { @@ -112,12 +132,19 @@ struct tplg_route_info { struct list_item item; /* item in a list */ }; +struct tplg_pipeline_list { + int count; + struct tplg_pipeline_info *pipelines[TPLG_MAX_PCM_PIPELINES]; +}; + struct tplg_pcm_info { char *name; int id; struct tplg_comp_info *playback_host; struct tplg_comp_info *capture_host; struct list_item item; /* item in a list */ + struct tplg_pipeline_list playback_pipeline_list; + struct tplg_pipeline_list capture_pipeline_list; }; /* diff --git a/tools/tplg_parser/pga.c b/tools/tplg_parser/pga.c index 0a65cafa5cbb..5a23f349d679 100644 --- a/tools/tplg_parser/pga.c +++ b/tools/tplg_parser/pga.c @@ -14,11 +14,11 @@ #include <string.h> #include <math.h> #include <ipc/topology.h> -#include <volume/peak_volume.h> #include <sof/lib/uuid.h> #include <sof/ipc/topology.h> #include <tplg_parser/topology.h> #include <tplg_parser/tokens.h> +#include <volume/peak_volume.h> #define SOF_IPC4_VOL_ZERO_DB 0x7fffffff diff --git a/tools/tune/common/tplg2_write.m b/tools/tune/common/tplg2_write.m index 9453c5d7dd7b..1bb28b05e5c6 100644 --- a/tools/tune/common/tplg2_write.m +++ b/tools/tune/common/tplg2_write.m @@ -1,4 +1,4 @@ -function tplg2_write(fn, blob8, component, comment) +function tplg2_write(fn, blob8, component, comment, howto) % SPDX-License-Identifier: BSD-3-Clause % @@ -9,6 +9,9 @@ function tplg2_write(fn, blob8, component, comment) if nargin < 4 comment = 'Exported Control Bytes'; end +if nargin < 5 + howto = []; +end %% Check that blob length is multiple of 32 bits n_blob = length(blob8); @@ -23,6 +26,9 @@ function tplg2_write(fn, blob8, component, comment) fh = fopen(fn, 'w'); nl = 8; fprintf(fh, '# %s %s\n', comment, date()); +if ~isempty(howto) + fprintf(fh, '# %s\n', howto); +end fprintf(fh, 'Object.Base.data.\"%s\" {\n', component); fprintf(fh, '\tbytes \"\n'); for i = 1:nl:n_blob diff --git a/tools/tune/common/tplg_write.m b/tools/tune/common/tplg_write.m index 079aea77fd10..15692cfab295 100644 --- a/tools/tune/common/tplg_write.m +++ b/tools/tune/common/tplg_write.m @@ -1,8 +1,11 @@ -function tplg_write(fn, blob8, name, comment) +function tplg_write(fn, blob8, name, comment, howto) if nargin < 4 comment = 'Exported Control Bytes'; end +if nargin < 5 + howto = []; +end %% Pad blob length to multiple of four bytes n_orig = length(blob8); @@ -14,6 +17,9 @@ function tplg_write(fn, blob8, name, comment) fh = fopen(fn, 'w'); nl = 8; fprintf(fh, '# %s %s\n', comment, date()); +if ~isempty(howto) + fprintf(fh, '# %s\n', howto); +end fprintf(fh, 'CONTROLBYTES_PRIV(%s_priv,\n', name); fprintf(fh, '` bytes "'); for i = 1:nl:n_new @@ -33,5 +39,6 @@ function tplg_write(fn, blob8, name, comment) end fprintf(fh, ')\n'); fclose(fh); +fprintf('Blob size %d was written to file %s\n', n_new, fn); end diff --git a/tools/tune/dcblock/dcblock_build_blob.m b/tools/tune/dcblock/dcblock_build_blob.m index 43fa67f5c915..0b4293054f57 100644 --- a/tools/tune/dcblock/dcblock_build_blob.m +++ b/tools/tune/dcblock/dcblock_build_blob.m @@ -1,12 +1,15 @@ -function blob8 = dcblock_build_blob(R_coeffs, endian) +function blob8 = dcblock_build_blob(R_coeffs, endian, ipc_ver) %% Settings -bits_R = 32; %Q2.30 qy_R = 30; if nargin < 2 - endian = 'little' -endif + endian = 'little'; +end + +if nargin < 3 + ipc_ver = 3; +end %% Shift values for little/big endian switch lower(endian) @@ -24,7 +27,7 @@ %% Build Blob data_size = (num_of_coeffs)*4; -[abi_bytes, abi_size] = dcblock_get_abi(data_size); +[abi_bytes, abi_size] = get_abi(data_size, ipc_ver); blob_size = data_size + abi_size; blob8 = uint8(zeros(1, blob_size)); @@ -40,7 +43,7 @@ j=j+4; end -endfunction +end function bytes = word2byte(word, sh) bytes = uint8(zeros(1,4)); diff --git a/tools/tune/dcblock/dcblock_get_abi.m b/tools/tune/dcblock/dcblock_get_abi.m deleted file mode 100644 index b65988cb99ae..000000000000 --- a/tools/tune/dcblock/dcblock_get_abi.m +++ /dev/null @@ -1,17 +0,0 @@ -function [bytes, nbytes] = dcblock_get_abi(setsize) - -%% Use sof-ctl to write ABI header into a file -abifn = 'dcblock_get_abi.bin'; -cmd = sprintf('sof-ctl -g %d -b -o %s', setsize, abifn); -system(cmd); - -%% Read file and delete it -fh = fopen(abifn, 'r'); -if fh < 0 - error("Failed to get ABI header. Is sof-ctl installed?"); -end -[bytes, nbytes] = fread(fh, inf, 'uint8'); -fclose(fh); -delete(abifn); - -end diff --git a/tools/tune/dcblock/dcblock_plot_stepfn.m b/tools/tune/dcblock/dcblock_plot_stepfn.m index 724b4bcfcf40..e0c7c3d14db3 100644 --- a/tools/tune/dcblock/dcblock_plot_stepfn.m +++ b/tools/tune/dcblock/dcblock_plot_stepfn.m @@ -1,4 +1,4 @@ -function dcblock_plot_stepfn(R, fs); +function dcblock_plot_stepfn(R, fs) % Plot the step response of a DC Blocking Filter % For a DC Blocking filter: H(z) = (1-1/z)/(1 - R/z) % Therefore the coefficients are b = [1 -1], a = [1 -R] @@ -13,4 +13,4 @@ tstr = sprintf("DC Blocking Filter Step Response, R = %i", R); title(tstr); -endfunction +end diff --git a/tools/tune/dcblock/dcblock_plot_transferfn.m b/tools/tune/dcblock/dcblock_plot_transferfn.m index 8237222014a6..513a291f666b 100644 --- a/tools/tune/dcblock/dcblock_plot_transferfn.m +++ b/tools/tune/dcblock/dcblock_plot_transferfn.m @@ -1,4 +1,4 @@ -function dcblock_plot_transferfn(R, fs); +function dcblock_plot_transferfn(R, fs) % Plot the transfer function. % For a DC Blocking filter: H(z) = (1-1/z)/(1 - R/z) % Therefore the coefficients are b = [1 -1], a = [1 -R] @@ -7,11 +7,11 @@ f = linspace(1, fs/2, 500); -semilogx(f, 20*log10(freqz(b, a, f, fs))); +semilogx(f, 20*log10(abs(freqz(b, a, f, fs)))); grid on xlabel('Frequency (Hz)'); ylabel('Magnitude (dB)'); tstr = sprintf("DC Blocking Filter Frequency Response, R = %i", R); title(tstr); -endfunction +end diff --git a/tools/tune/dcblock/example_dcblock.m b/tools/tune/dcblock/example_dcblock.m index 74490e5ab159..6ffa179e5485 100644 --- a/tools/tune/dcblock/example_dcblock.m +++ b/tools/tune/dcblock/example_dcblock.m @@ -1,30 +1,128 @@ -function example_dcblock(); +function example_dcblock() + +% Default blob, about 150 Hz cut-off @ 48 kHz +prm.fc = []; +prm.fs = []; +prm.R_coeffs = [0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98]; +prm.id = "default"; +dcblock_blob_calculate(prm) + +% Generate a set configuration blobs for 16 and 48 kHz rate +% The selected high-pass cut-off frequencies are in range 20 - 200 Hz: +% 20, 30, 40, 50, 80, 100, and 200 Hz +% +% Select for applications one that is best tradeoff between DC level +% settle time and the lowest frequency that should pass without +% much attenuation. Cut-off frequency by definition is the point where +% the attenuation is 3.01 dB. + +prm.R_coeffs = []; +for fs = [16e3 48e3] + for fc = [20 30 40 50 80 100 200] + prm.id = sprintf("%dhz_%dkhz", round(fc), round(fs / 1000)); + prm.fs = fs; + prm.fc = fc; + dcblock_blob_calculate(prm) + end +end + +end + +function dcblock_blob_calculate(prm) % Set the parameters here -tplg_fn = "../../topology/topology1/m4/dcblock_coef_default.m4" % Control Bytes File +tplg1_fn = sprintf("../../topology/topology1/m4/dcblock_coef_%s.m4", prm.id); % Control Bytes File +tplg2_fn = sprintf("../../topology/topology2/include/components/dcblock/%s.conf", prm.id); % Use those files with sof-ctl to update the component's configuration -blob_fn = "../../ctl/dcblock_coef.blob" % Blob binary file -alsa_fn = "../../ctl/dcblock_coef.txt" % ALSA CSV format file +blob3_fn = sprintf("../../ctl/ipc3/dcblock/coef_%s.blob", prm.id); % Blob binary file +alsa3_fn = sprintf("../../ctl/ipc3/dcblock/coef_%s.txt", prm.id); % ALSA CSV format file +blob4_fn = sprintf("../../ctl/ipc4/dcblock/coef_%s.blob", prm.id); % Blob binary file +alsa4_fn = sprintf("../../ctl/ipc4/dcblock/coef_%s.txt", prm.id); % ALSA CSV format file endian = "little"; -R_coeffs = [0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98]; + +if isempty(prm.fc) + R_coeffs = prm.R_coeffs; +else + channels = 8; + R = dcblock_rval_calculate(prm.fs, prm.fc); + R_coeffs = R * ones(1, channels); +end + +addpath ./../common blob8 = dcblock_build_blob(R_coeffs, endian); +blob8_ipc4 = dcblock_build_blob(R_coeffs, endian, 4); % Generate output files -addpath ./../common +tplg_write(tplg1_fn, blob8, "DCBLOCK", ... + "Exported with script example_dcblock.m", ... + "cd tools/tune/dcblock; octave example_dcblock.m"); +blob_write(blob3_fn, blob8); +alsactl_write(alsa3_fn, blob8); -tplg_write(tplg_fn, blob8, "DCBLOCK"); -blob_write(blob_fn, blob8); -alsactl_write(alsa_fn, blob8); +tplg2_write(tplg2_fn, blob8_ipc4, "dcblock_config", ... + "Exported with script example_dcblock.m" , ... + "cd tools/tune/dcblock; octave example_dcblock.m"); +blob_write(blob4_fn, blob8_ipc4); +alsactl_write(alsa4_fn, blob8_ipc4); % Plot Filter's Transfer Function and Step Response % As an example, plot the graphs of the first coefficient -fs = 48e3 +fs = 48e3; dcblock_plot_transferfn(R_coeffs(1), fs); figure dcblock_plot_stepfn(R_coeffs(1), fs); rmpath ./../common -endfunction +end + +% Finds with iterative search parameter R for given cutoff frequency +function R = dcblock_rval_calculate(fs, fc_target) + +if (fc_target / fs < 10 / 48e3 || fc_target / fs > 1000 / 48e3) + error("Illegal fc_target"); +end + +h_target = 1 / sqrt(2); % -3.01 dB +R = 0.5; +R_step = 0.005; +sign = 1; +w = 2 * pi * fc_target / fs; +j = sqrt(-1); +z = exp(j * w); + +% Iteration 0 +h = (1 - z^-1) / (1 - R * z^-1); +err_prev = (h_target - abs(h))^2; +R = R + sign * R_step; + +% Do more iterations +for n = 1 : 200 + h = (1 - z^-1) / (1 - R * z^-1); + err = (h_target - abs(h))^2; + if (err > err_prev) + sign = -sign; + R_step = R_step / 2; + end + R = R + sign * R_step; + err_prev = err; +end + +% Sane result? +if R < eps || R > 1 - eps + error("Calculate of R iteration failed"); +end + +% Sane high-pass function? +f = [1 fc_target fs/2]; +b = [ 1 -1 ]; a = [ 1 -R ]; +h = freqz(b, a, f, fs); +h_db = 20*log10(abs(h)); +err_hfc = abs(20*log10(1/sqrt(2)) - h_db(2)); +if err_hfc > 0.01 || h_db(1) > -10 || h_db(3) < 0 || h_db(3) > 1 + error("Failed high-pass response"); +end + +end diff --git a/tools/tune/multiband_drc/example_multiband_drc.m b/tools/tune/multiband_drc/example_multiband_drc.m index 892c3fb41638..486e79dd88b2 100644 --- a/tools/tune/multiband_drc/example_multiband_drc.m +++ b/tools/tune/multiband_drc/example_multiband_drc.m @@ -139,7 +139,7 @@ function export_multiband_drc(prm) endian, 4); tplg_write(tplg1_fn, blob8, "MULTIBAND_DRC"); -tplg2_write(tplg2_fn, blob8_ipc4, "multiband_drc_config", 'Exported Control Bytes'); +tplg2_write(tplg2_fn, blob8_ipc4, "multiband_drc_config", "Exported with script example_multiband_drc.m"); blob_write(blob3_fn, blob8); alsactl_write(alsa3_fn, blob8); blob_write(blob4_fn, blob8_ipc4); diff --git a/tools/tune/tdfb/bf_blob_pack.m b/tools/tune/tdfb/bf_blob_pack.m index 097d04cee431..306c16a6ad99 100644 --- a/tools/tune/tdfb/bf_blob_pack.m +++ b/tools/tune/tdfb/bf_blob_pack.m @@ -1,4 +1,4 @@ -function blob8 = bf_blob_pack(bf) +function blob8 = bf_blob_pack(bf, ipc_version) %% Pack TDFB struct to bytes % @@ -143,7 +143,7 @@ nbytes_data = nb16 * 2; %% Get ABI information -[abi_bytes, nbytes_abi] = eq_get_abi(nbytes_data); +[abi_bytes, nbytes_abi] = get_abi(nbytes_data, ipc_version); %% Initialize uint8 array with correct size nbytes = nbytes_abi + nbytes_data; diff --git a/tools/tune/tdfb/bf_defaults.m b/tools/tune/tdfb/bf_defaults.m index 2d448d08fc3a..3bf4e834cf60 100644 --- a/tools/tune/tdfb/bf_defaults.m +++ b/tools/tune/tdfb/bf_defaults.m @@ -19,8 +19,10 @@ bf.array_angle = [0 0 0]; % Array rotation angles for xyz bf.tplg_fn = ''; bf.sofctl_fn = ''; -bf.tplg_path = '../../topology/topology1/m4/tdfb'; -bf.sofctl_path = '../../ctl/tdfb'; +bf.tplg1_path = '../../topology/topology1/m4/tdfb'; +bf.tplg2_path = '../../topology/topology2/include/components/tdfb'; +bf.sofctl3_path = '../../ctl/ipc3/tdfb'; +bf.sofctl4_path = '../../ctl/ipc4/tdfb'; bf.data_path = './data'; bf.endian = 'little'; bf.fn = 1; @@ -56,5 +58,6 @@ bf.diffuse_fn = {''}; bf.random_fn = {''}; bf.mat_fn = {''}; +bf.export_note = ''; end diff --git a/tools/tune/tdfb/bf_export.m b/tools/tune/tdfb/bf_export.m index 9f52bedf8a8a..7b39e71cfe02 100644 --- a/tools/tune/tdfb/bf_export.m +++ b/tools/tune/tdfb/bf_export.m @@ -1,8 +1,10 @@ % bf_export(bf) % % Inputs -% bf.sofctl_fn ..... filename of ascii text format blob -% bf.tplg_fn ....... filename of topology m4 format blob +% bf.sofctl3_fn .... filename of ascii text format blob +% bf.sofctl4_fn .... filename of ascii text format blob +% bf.tplg1_fn ...... filename of topology m4 format blob +% bf.tplg2_fn ...... filename of topology m4 format blob % bf ............... the design procedure output % SPDX-License-Identifier: BSD-3-Clause @@ -13,7 +15,8 @@ function bf = bf_export(bf) -% Use functionc from EQ tool, test utils +% Use functionc from common, test utils +addpath('../common'); addpath('../eq'); addpath('../../test/audio/test_utils'); @@ -73,23 +76,50 @@ %% Build blob bf.all_filters = filters; -bp = bf_blob_pack(bf); +bp3 = bf_blob_pack(bf, 3); +bp4 = bf_blob_pack(bf, 4); %% Export -if isempty(bf.sofctl_fn) - fprintf(1, 'No sof-ctl output file specified.\n'); +if isempty(bf.sofctl3_fn) + fprintf(1, 'No sof-ctl3 output file specified.\n'); else - fprintf(1, 'Exporting to %s\n', bf.sofctl_fn); - mkdir_check(bf.sofctl_path); - eq_alsactl_write(bf.sofctl_fn, bp); + fprintf(1, 'Exporting to %s\n', bf.sofctl3_fn); + mkdir_check(bf.sofctl3_path); + alsactl_write(bf.sofctl3_fn, bp3); end -if isempty(bf.tplg_fn) - fprintf(1, 'No topology output file specified.\n'); +if isempty(bf.sofctl4_fn) + fprintf(1, 'No sof-ctl4 output file specified.\n'); else - fprintf(1, 'Exporting to %s\n', bf.tplg_fn); - mkdir_check(bf.tplg_path); - eq_tplg_write(bf.tplg_fn, bp, 'DEF_TDFB_PRIV'); + fprintf(1, 'Exporting to %s\n', bf.sofctl4_fn); + mkdir_check(bf.sofctl4_path); + alsactl_write(bf.sofctl4_fn, bp4); end +if isempty(bf.export_note) + export_note = sprintf("Exported with script example_%s_array.m", bf.array); +else + export_note = bf.export_note; +end + +if isempty(bf.tplg1_fn) + fprintf(1, 'No topology1 output file specified.\n'); +else + fprintf(1, 'Exporting to %s\n', bf.tplg1_fn); + mkdir_check(bf.tplg1_path); + tplg_write(bf.tplg1_fn, bp3, 'DEF_TDFB_PRIV', export_note); +end + +if isempty(bf.tplg2_fn) + fprintf(1, 'No topology2 output file specified.\n'); +else + fprintf(1, 'Exporting to %s\n', bf.tplg2_fn); + mkdir_check(bf.tplg2_path); + tplg2_write(bf.tplg2_fn, bp4, "tdfb_config", export_note); +end + +rmpath('../../test/audio/test_utils'); +rmpath('../eq'); +rmpath('../common'); + end diff --git a/tools/tune/tdfb/bf_filenames_helper.m b/tools/tune/tdfb/bf_filenames_helper.m index dcd09531f479..7fd446df37b3 100644 --- a/tools/tune/tdfb/bf_filenames_helper.m +++ b/tools/tune/tdfb/bf_filenames_helper.m @@ -34,18 +34,26 @@ [az_str_pm] = angles_to_str(bf.steer_az); [el_str_pm] = angles_to_str(bf.steer_el); +if strcmp(bf.array, 'line') + el_str_show = ''; +else + el_str_show = sprintf('_el%s', el_str_pm); +end + if nargin > 1 - idstr = sprintf('%s_az%sel%sdeg_%dkhz', ... - id, az_str_pm, el_str_pm, round(bf.fs/1e3)); + idstr = sprintf('%s_az%s%s_%dkhz', ... + id, az_str_pm, el_str_show, round(bf.fs/1e3)); else - idstr = sprintf('%s%s_%smm_az%sel%sdeg_%dkhz', ... + idstr = sprintf('%s%s_%smm_az%s%s_%dkhz', ... bf.array, mic_n_str, mic_d_str, ... - az_str_pm, el_str_pm, round(bf.fs/1e3)); + az_str_pm, el_str_show, round(bf.fs/1e3)); end % Contain multiple (az, el) angles -bf.sofctl_fn = fullfile(bf.sofctl_path, sprintf('coef_%s.txt', idstr)); -bf.tplg_fn = fullfile(bf.tplg_path, sprintf('coef_%s.m4', idstr)); +bf.sofctl3_fn = fullfile(bf.sofctl3_path, sprintf('coef_%s.txt', idstr)); +bf.tplg1_fn = fullfile(bf.tplg1_path, sprintf('coef_%s.m4', idstr)); +bf.sofctl4_fn = fullfile(bf.sofctl4_path, sprintf('%s.txt', idstr)); +bf.tplg2_fn = fullfile(bf.tplg2_path, sprintf('%s.conf', idstr)); for n = 1:length(bf.steer_az) diff --git a/tools/tune/tdfb/example_line_0mm36mm146mm182mm.m b/tools/tune/tdfb/example_line_0mm36mm146mm182mm.m index c78ac881b240..d8532b240e4a 100644 --- a/tools/tune/tdfb/example_line_0mm36mm146mm182mm.m +++ b/tools/tune/tdfb/example_line_0mm36mm146mm182mm.m @@ -16,8 +16,10 @@ function example_line_0mm36mm146mm182mm() function line_xyz(fs, fir_length, az) -tplg_fn = sprintf('coef_line4_0mm36mm146mm182mm_%dkhz.m4', fs/1e3); -sofctl_fn = sprintf('coef_line4_0mm36mm146mm182mm_%dkhz.txt', fs/1e3); +tplg1_fn = sprintf('coef_line4_0mm36mm146mm182mm_%dkhz.m4', fs/1e3); +sofctl3_fn = sprintf('coef_line4_0mm36mm146mm182mm_%dkhz.txt', fs/1e3); +tplg2_fn = sprintf('line4_0mm36mm146mm182mm_%dkhz.conf', fs/1e3); +sofctl4_fn = sprintf('line4_0mm36mm146mm182mm_%dkhz.txt', fs/1e3); % Get defaults close all; @@ -52,6 +54,7 @@ function line_xyz(fs, fir_length, az) bf = bf_design(bf); % Export files for topology and sof-ctl +bf.export_note = 'Created with script example_line_0mm36mm146mm182mm.m'; bf_export(bf); end diff --git a/tools/tune/tdfb/example_pass_config.m b/tools/tune/tdfb/example_pass_config.m index 84b2251d242c..b65d48d218aa 100644 --- a/tools/tune/tdfb/example_pass_config.m +++ b/tools/tune/tdfb/example_pass_config.m @@ -27,8 +27,11 @@ function example_pass_config() bf.w = [1 0 0 0; 1 0 0 0]'; % Two FIR filters with first tap set to one % Files -bf.sofctl_fn = fullfile(bf.sofctl_path, 'coef_line2_pass.txt'); -bf.tplg_fn = fullfile(bf.tplg_path, 'coef_line2_pass.m4'); +bf.export_note = 'Exported with script example_pass_config.m'; +bf.sofctl3_fn = fullfile(bf.sofctl3_path, 'coef_line2_pass.txt'); +bf.tplg1_fn = fullfile(bf.tplg1_path, 'coef_line2_pass.m4'); +bf.sofctl4_fn = fullfile(bf.sofctl4_path, 'line2_pass.txt'); +bf.tplg2_fn = fullfile(bf.tplg2_path, 'line2_pass.conf'); bf_export(bf); % Setup for four channels @@ -43,8 +46,10 @@ function example_pass_config() bf.w = [1 0 0 0; 1 0 0 0; 1 0 0 0; 1 0 0 0]'; % Four FIR filters with first tap set to one % Files -bf.sofctl_fn = fullfile(bf.sofctl_path, 'coef_line4_pass.txt'); -bf.tplg_fn = fullfile(bf.tplg_path, 'coef_line4_pass.m4'); +bf.sofctl3_fn = fullfile(bf.sofctl3_path, 'coef_line4_pass.txt'); +bf.tplg1_fn = fullfile(bf.tplg1_path, 'coef_line4_pass.m4'); +bf.sofctl4_fn = fullfile(bf.sofctl4_path, 'line4_pass.txt'); +bf.tplg2_fn = fullfile(bf.tplg2_path, 'line4_pass.conf'); bf_export(bf); end diff --git a/tools/tune/tdfb/example_two_beams.m b/tools/tune/tdfb/example_two_beams.m index 65d998e61f78..5db6b9da094d 100644 --- a/tools/tune/tdfb/example_two_beams.m +++ b/tools/tune/tdfb/example_two_beams.m @@ -25,44 +25,54 @@ function example_two_beams() close all; %% 2 mic 50 mm array - tplg_fn = sprintf('coef_line2_50mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); - sofctl_fn = sprintf('coef_line2_50mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg1_fn = sprintf('coef_line2_50mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); + fn.sofctl3_fn = sprintf('coef_line2_50mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg2_fn = sprintf('line2_50mm_pm%sdeg_%dkhz.conf', azstr, fs/1e3); + fn.sofctl4_fn = sprintf('line2_50mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); d = 50e-3; % 50 mm spacing a1 = az; % Azimuth +az deg a2 = -az; % Azimuth -az deg - line2_two_beams(fs, d, a1, a2, tplg_fn, sofctl_fn, 1); + line2_two_beams(fs, d, a1, a2, fn, 1); %% 2 mic 68 mm array - tplg_fn = sprintf('coef_line2_68mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); - sofctl_fn = sprintf('coef_line2_68mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg1_fn = sprintf('coef_line2_68mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); + fn.sofctl3_fn = sprintf('coef_line2_68mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg2_fn = sprintf('line2_68mm_pm%sdeg_%dkhz.conf', azstr, fs/1e3); + fn.sofctl4_fn = sprintf('line2_68mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); d = 68e-3; % 68 mm spacing a1 = az; % Azimuth +az deg a2 = -az; % Azimuth -az deg - line2_two_beams(fs, d, a1, a2, tplg_fn, sofctl_fn, 1); + line2_two_beams(fs, d, a1, a2, fn, 1); %% 4 mic 28 mm spaced array - tplg_fn = sprintf('coef_line4_28mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); - sofctl_fn = sprintf('coef_line4_28mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg1_fn = sprintf('coef_line4_28mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); + fn.sofctl3_fn = sprintf('coef_line4_28mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg2_fn = sprintf('line4_28mm_pm%sdeg_%dkhz.conf', azstr, fs/1e3); + fn.sofctl4_fn = sprintf('line4_28mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); d = 28e-3; % 28 mm spacing a1 = az; % Azimuth +az deg a2 = -az; % Azimuth -az deg - line4_two_beams(fs, d, a1, a2, tplg_fn, sofctl_fn, 1); + line4_two_beams(fs, d, a1, a2, fn, 1); %% 4 mic 68 mm spaced array - tplg_fn = sprintf('coef_line4_68mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); - sofctl_fn = sprintf('coef_line4_68mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg1_fn = sprintf('coef_line4_68mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); + fn.sofctl3_fn = sprintf('coef_line4_68mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg2_fn = sprintf('line4_68mm_pm%sdeg_%dkhz.conf', azstr, fs/1e3); + fn.sofctl4_fn = sprintf('line4_68mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); d = 68e-3; % 68 mm spacing a1 = az; % Azimuth +az deg a2 = -az; % Azimuth -az deg - line4_two_beams(fs, d, a1, a2, tplg_fn, sofctl_fn, 1); + line4_two_beams(fs, d, a1, a2, fn, 1); %% 4 mic 78 mm spaced array - tplg_fn = sprintf('coef_line4_78mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); - sofctl_fn = sprintf('coef_line4_78mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg1_fn = sprintf('coef_line4_78mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); + fn.sofctl3_fn = sprintf('coef_line4_78mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg2_fn = sprintf('line4_78mm_pm%sdeg_%dkhz.conf', azstr, fs/1e3); + fn.sofctl4_fn = sprintf('line4_78mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); d = 78e-3; % 78 mm spacing a1 = az; % Azimuth +az deg a2 = -az; % Azimuth -az deg - line4_two_beams(fs, d, a1, a2, tplg_fn, sofctl_fn, 1); + line4_two_beams(fs, d, a1, a2, fn, 1); end %% Export blob with just +/- 90 deg beams for testbench beampattern check @@ -71,29 +81,35 @@ function example_two_beams() azstr = az_to_string(az); for fs = [16e3 48e3] %% 2 mic 50 mm array, disable beam off description in blob to force processing on - tplg_fn = sprintf('coef_line2_50mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); - sofctl_fn = sprintf('coef_line2_50mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg1_fn = sprintf('coef_line2_50mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); + fn.sofctl3_fn = sprintf('coef_line2_50mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg2_fn = sprintf('line2_50mm_pm%sdeg_%dkhz.conf', azstr, fs/1e3); + fn.sofctl4_fn = sprintf('line2_50mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); d = 50e-3; % 50 mm spacing a1 = az; % Azimuth +az deg a2 = -az; % Azimuth -az deg - line2_two_beams(fs, d, a1, a2, tplg_fn, sofctl_fn, 0); + line2_two_beams(fs, d, a1, a2, fn, 0); %% 4 mic 28 mm spaced array, no beam off configuration - tplg_fn = sprintf('coef_line4_28mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); - sofctl_fn = sprintf('coef_line4_28mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg1_fn = sprintf('coef_line4_28mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); + fn.sofctl3_fn = sprintf('coef_line4_28mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg2_fn = sprintf('line4_28mm_pm%sdeg_%dkhz.conf', azstr, fs/1e3); + fn.sofctl4_fn = sprintf('line4_28mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); d = 28e-3; % 28 mm spacing a1 = az; % Azimuth +az deg a2 = -az; % Azimuth -az deg - line4_two_beams(fs, d, a1, a2, tplg_fn, sofctl_fn, 0); + line4_two_beams(fs, d, a1, a2, fn, 0); end %% Circular array with two beams az = 30; azstr = az_to_string(az); for fs = [48e3 16e3] - tplg_fn = sprintf('coef_circular8_100mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); - sofctl_fn = sprintf('coef_circular8_100mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); - circular_two_beams(fs, 100e-3, 8, az, -az, tplg_fn, sofctl_fn, 0); + fn.tplg1_fn = sprintf('coef_circular8_100mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); + fn.sofctl3_fn = sprintf('coef_circular8_100mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg2_fn = sprintf('coef_circular8_100mm_pm%sdeg_%dkhz.conf', azstr, fs/1e3); + fn.sofctl4_fn = sprintf('coef_circular8_100mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + circular_two_beams(fs, 100e-3, 8, az, -az, fn, 0); end %% Creates beamformer with two beams for device with device with microphones @@ -110,7 +126,7 @@ function example_two_beams() end end -function line2_two_beams(fs, d, a1, a2, tplg_fn, sofctl_fn, add_beam_off); +function line2_two_beams(fs, d, a1, a2, fn, add_beam_off); % Get defaults bf1 = bf_defaults(); @@ -152,15 +168,18 @@ function example_two_beams() % Merge two beamformers into single description, set file names bfm = bf_merge(bf1, bf2); -bfm.sofctl_fn = fullfile(bfm.sofctl_path, sofctl_fn); -bfm.tplg_fn = fullfile(bfm.tplg_path, tplg_fn); +bfm.sofctl3_fn = fullfile(bfm.sofctl3_path, fn.sofctl3_fn); +bfm.tplg1_fn = fullfile(bfm.tplg1_path, fn.tplg1_fn); +bfm.sofctl4_fn = fullfile(bfm.sofctl4_path, fn.sofctl4_fn); +bfm.tplg2_fn = fullfile(bfm.tplg2_path, fn.tplg2_fn); % Export files for topology and sof-ctl +bfm.export_note = 'Created with script example_two_beams.m'; bf_export(bfm); end -function line4_two_beams(fs, d, a1, a2, tplg_fn, sofctl_fn, add_beam_off); +function line4_two_beams(fs, d, a1, a2, fn, add_beam_off); % Get defaults bf1 = bf_defaults(); @@ -201,15 +220,18 @@ function example_two_beams() % Merge two beamformers into single description, set file names bfm = bf_merge(bf1, bf2); -bfm.sofctl_fn = fullfile(bfm.sofctl_path, sofctl_fn); -bfm.tplg_fn = fullfile(bfm.tplg_path, tplg_fn); +bfm.sofctl3_fn = fullfile(bfm.sofctl3_path, fn.sofctl3_fn); +bfm.tplg1_fn = fullfile(bfm.tplg1_path, fn.tplg1_fn); +bfm.sofctl4_fn = fullfile(bfm.sofctl4_path, fn.sofctl4_fn); +bfm.tplg2_fn = fullfile(bfm.tplg2_path, fn.tplg2_fn); % Export files for topology and sof-ctl +bfm.export_note = 'Created with script example_two_beams.m'; bf_export(bfm); end -function circular_two_beams(fs, r, n, a1, a2, tplg_fn, sofctl_fn, add_beam_off) +function circular_two_beams(fs, r, n, a1, a2, fn, add_beam_off) % Get defaults and common settings bf1 = bf_defaults(); @@ -244,10 +266,13 @@ function circular_two_beams(fs, r, n, a1, a2, tplg_fn, sofctl_fn, add_beam_off) % Merge two beamformers into single description, set file names bfm = bf_merge(bf1, bf2); -bfm.sofctl_fn = fullfile(bfm.sofctl_path, sofctl_fn); -bfm.tplg_fn = fullfile(bfm.tplg_path, tplg_fn); +bfm.sofctl3_fn = fullfile(bfm.sofctl3_path, fn.sofctl3_fn); +bfm.tplg1_fn = fullfile(bfm.tplg1_path, fn.tplg1_fn); +bfm.sofctl4_fn = fullfile(bfm.sofctl4_path, fn.sofctl4_fn); +bfm.tplg2_fn = fullfile(bfm.tplg2_path, fn.tplg2_fn); % Export files for topology and sof-ctl +bfm.export_note = 'Created with script example_two_beams.m'; bf_export(bfm); end @@ -273,8 +298,10 @@ function line_xyz(fs) end % Setup array -tplg_fn = sprintf('coef_line4_0mm36mm146mm182mm_%s_%dkhz.m4', azstr, fs/1e3); -sofctl_fn = sprintf('coef_line4_0mm36mm146mm182mm_%s_%dkhz.txt', azstr, fs/1e3); +tplg1_fn = sprintf('coef_line4_0mm36mm146mm182mm_%s_%dkhz.m4', azstr, fs/1e3); +sofctl3_fn = sprintf('coef_line4_0mm36mm146mm182mm_%s_%dkhz.txt', azstr, fs/1e3); +tplg2_fn = sprintf('line4_0mm36mm146mm182mm_%s_%dkhz.conf', azstr, fs/1e3); +sofctl4_fn = sprintf('line4_0mm36mm146mm182mm_%s_%dkhz.txt', azstr, fs/1e3); a1 = az; % Azimuth +az deg a2 = -az; % Azimuth -az deg close all; @@ -317,10 +344,13 @@ function line_xyz(fs) % Merge two beamformers into single description, set file names bfm = bf_merge(bf1, bf2); -bfm.sofctl_fn = fullfile(bfm.sofctl_path, sofctl_fn); -bfm.tplg_fn = fullfile(bfm.tplg_path, tplg_fn); +bfm.sofctl3_fn = fullfile(bfm.sofctl3_path, sofctl3_fn); +bfm.tplg1_fn = fullfile(bfm.tplg1_path, tplg1_fn); +bfm.sofctl4_fn = fullfile(bfm.sofctl4_path, sofctl4_fn); +bfm.tplg2_fn = fullfile(bfm.tplg2_path, tplg2_fn); % Export files for topology and sof-ctl +bfm.export_note = 'Created with script example_two_beams.m'; bf_export(bfm); end diff --git a/west.yml b/west.yml index 5f4db594af5d..4602b625f255 100644 --- a/west.yml +++ b/west.yml @@ -33,19 +33,17 @@ manifest: # https://github.com/zephyrproject-rtos/zephyr/issues/58212 projects: - - name: rimage - repo-path: rimage - path: sof/rimage - revision: 4fb9fe00575bc2e9f14570803d811987fb27f010 - + # West convenience for Zephyr people who forgot --recursive when + # cloning sof.git. This adds the burden of keeping both tomlc99 + # SHA1s synchronized but in practice it barely ever moves. - name: tomlc99 repo-path: tomlc99 - path: sof/rimage/tomlc99 + path: sof/tools/rimage/tomlc99 revision: e3a03f5ec7d8d33be705c5ce8a632d998ce9b4d1 - name: zephyr repo-path: zephyr - revision: 2f90ef488a4e97c94c2cc5b95dacd1b15de32216 + revision: 460c2167e4f3f6489ff0d3f519466a5682d8146b remote: zephyrproject # Import some projects listed in zephyr/west.yml@revision diff --git a/xtos/include/sof/lib/dma.h b/xtos/include/sof/lib/dma.h index 85080e70c18b..2f0bfe940dea 100644 --- a/xtos/include/sof/lib/dma.h +++ b/xtos/include/sof/lib/dma.h @@ -75,6 +75,7 @@ struct comp_buffer; #define DMA_DEV_SP_VIRTUAL BIT(11) /**< connectable to ACP SP VIRTUAL I2S */ #define DMA_DEV_HS_VIRTUAL BIT(12) /**< connectable to ACP HS VIRTUAL I2S */ #define DMA_DEV_HS BIT(13) /**< connectable to ACP HS I2S */ +#define DMA_DEV_MICFIL BIT(14) /**< connectable to MICFIL fifo */ /* DMA access privilege flag */ #define DMA_ACCESS_EXCLUSIVE 1 @@ -254,8 +255,8 @@ struct dma_info { }; struct audio_stream; -typedef int (*dma_process_func)(const struct audio_stream __sparse_cache *source, - uint32_t ioffset, struct audio_stream __sparse_cache *sink, +typedef int (*dma_process_func)(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t frames); /** @@ -530,8 +531,8 @@ typedef void (*dma_process)(const struct audio_stream *, struct audio_stream *, uint32_t); /* copies data from DMA buffer using provided processing function */ -int dma_buffer_copy_from(struct comp_buffer __sparse_cache *source, - struct comp_buffer __sparse_cache *sink, +int dma_buffer_copy_from(struct comp_buffer *source, + struct comp_buffer *sink, dma_process_func process, uint32_t source_bytes); /* @@ -539,13 +540,13 @@ int dma_buffer_copy_from(struct comp_buffer __sparse_cache *source, * conversion function. DMA buffer consume should be performed after the data has been copied * to all sinks. */ -int dma_buffer_copy_from_no_consume(struct comp_buffer __sparse_cache *source, - struct comp_buffer __sparse_cache *sink, +int dma_buffer_copy_from_no_consume(struct comp_buffer *source, + struct comp_buffer *sink, dma_process_func process, uint32_t source_bytes); /* copies data to DMA buffer using provided processing function */ -int dma_buffer_copy_to(struct comp_buffer __sparse_cache *source, - struct comp_buffer __sparse_cache *sink, +int dma_buffer_copy_to(struct comp_buffer *source, + struct comp_buffer *sink, dma_process_func process, uint32_t sink_bytes); /* generic DMA DSP <-> Host copier */ diff --git a/xtos/include/sof/lib/mailbox.h b/xtos/include/sof/lib/mailbox.h index 86fc900138b3..06e2659a5847 100644 --- a/xtos/include/sof/lib/mailbox.h +++ b/xtos/include/sof/lib/mailbox.h @@ -69,9 +69,8 @@ void mailbox_dspbox_read(void *dest, size_t dest_size, #if CONFIG_LIBRARY -static inline -void mailbox_hostbox_write(size_t offset, const void *src, size_t bytes) -{} +#define mailbox_hostbox_write(_offset, _src, _bytes) \ + memcpy((char *)ipc->comp_data + _offset, _src, _bytes) #else diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index e531eaabb690..37a51de920d9 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -58,11 +58,11 @@ set(SOF_IPC_PATH "${SOF_SRC_PATH}/ipc") set(SOF_DEBUG_PATH "${SOF_SRC_PATH}/debug") set(SOF_MATH_PATH "${SOF_SRC_PATH}/math") set(SOF_TRACE_PATH "${SOF_SRC_PATH}/trace") +set(RIMAGE_TOP ${sof_top_dir}/tools/rimage) # Save path to rimage configuration files in cmake cache for later use by # rimage during the "west sign" stage -get_filename_component(RIMAGE_CONFIG "../rimage/config" ABSOLUTE) -set(RIMAGE_CONFIG_PATH ${RIMAGE_CONFIG} CACHE PATH +set(RIMAGE_CONFIG_PATH ${RIMAGE_TOP}/config CACHE PATH " Path to rimage board configuration files") include(ExternalProject) @@ -87,7 +87,7 @@ ExternalProject_Add(sof_logger_ep ) # default SOF includes -target_include_directories(SOF INTERFACE ${sof_top_dir}/rimage/src/include) +target_include_directories(SOF INTERFACE ${RIMAGE_TOP}/src/include) target_include_directories(SOF INTERFACE ${SOF_SRC_PATH}/include) target_include_directories(SOF INTERFACE ${SOF_SRC_PATH}/arch/${ARCH}/include) target_include_directories(SOF INTERFACE ${sof_top_dir}/third_party/include) @@ -239,6 +239,7 @@ if (CONFIG_SOC_SERIES_NXP_IMX8M) ${SOF_DRIVERS_PATH}/imx/sdma.c ${SOF_DRIVERS_PATH}/imx/sai.c ${SOF_DRIVERS_PATH}/imx/ipc.c + ${SOF_DRIVERS_PATH}/imx/micfil.c ${SOF_DRIVERS_PATH}/imx/interrupt-irqsteer.c ) @@ -362,6 +363,9 @@ zephyr_library_sources( lib.c ) +if(CONFIG_ZEPHYR_DP_SCHEDULER) + zephyr_library_sources(${SOF_AUDIO_PATH}/dp_queue.c) +endif() if(CONFIG_SCHEDULE_DMA_SINGLE_CHANNEL AND NOT(CONFIG_DMA_DOMAIN)) zephyr_library_sources(${SOF_SRC_PATH}/schedule/dma_single_chan_domain.c) endif() @@ -422,9 +426,19 @@ zephyr_library_sources_ifdef(CONFIG_COMP_FIR ${SOF_MATH_PATH}/fir_hifi3.c ) -zephyr_library_sources_ifdef(CONFIG_COMP_IIR - ${SOF_AUDIO_PATH}/eq_iir/eq_iir.c -) +if(CONFIG_IPC_MAJOR_3) + zephyr_library_sources_ifdef(CONFIG_COMP_IIR + ${SOF_AUDIO_PATH}/eq_iir/eq_iir.c + ${SOF_AUDIO_PATH}/eq_iir/eq_iir_ipc3.c + ${SOF_AUDIO_PATH}/eq_iir/eq_iir_generic.c + ) +elseif(CONFIG_IPC_MAJOR_4) + zephyr_library_sources_ifdef(CONFIG_COMP_IIR + ${SOF_AUDIO_PATH}/eq_iir/eq_iir.c + ${SOF_AUDIO_PATH}/eq_iir/eq_iir_ipc4.c + ${SOF_AUDIO_PATH}/eq_iir/eq_iir_generic.c + ) +endif() zephyr_library_sources_ifdef(CONFIG_MATH_IIR_DF1 ${SOF_MATH_PATH}/iir_df1_generic.c @@ -521,10 +535,19 @@ elseif(CONFIG_IPC_MAJOR_4) ) endif() +if(CONFIG_IPC_MAJOR_3) zephyr_library_sources_ifdef(CONFIG_COMP_MODULE_ADAPTER ${SOF_AUDIO_PATH}/module_adapter/module_adapter.c + ${SOF_AUDIO_PATH}/module_adapter/module_adapter_ipc3.c ${SOF_AUDIO_PATH}/module_adapter/module/generic.c ) +elseif(CONFIG_IPC_MAJOR_4) +zephyr_library_sources_ifdef(CONFIG_COMP_MODULE_ADAPTER + ${SOF_AUDIO_PATH}/module_adapter/module_adapter.c + ${SOF_AUDIO_PATH}/module_adapter/module_adapter_ipc4.c + ${SOF_AUDIO_PATH}/module_adapter/module/generic.c +) +endif() zephyr_library_sources_ifdef(CONFIG_LIBRARY_MANAGER ${SOF_SRC_PATH}/library_manager/lib_manager.c @@ -567,14 +590,29 @@ zephyr_library_sources_ifdef(CONFIG_COMP_CHAIN_DMA ${SOF_AUDIO_PATH}/chain_dma.c ) -zephyr_library_sources_ifdef(CONFIG_COMP_SRC - ${SOF_AUDIO_PATH}/src/src_hifi2ep.c - ${SOF_AUDIO_PATH}/src/src_generic.c - ${SOF_AUDIO_PATH}/src/src_hifi3.c - ${SOF_AUDIO_PATH}/src/src_hifi4.c - ${SOF_AUDIO_PATH}/src/src.c -) +if(CONFIG_IPC_MAJOR_3) + zephyr_library_sources_ifdef(CONFIG_COMP_SRC + ${SOF_AUDIO_PATH}/src/src_hifi2ep.c + ${SOF_AUDIO_PATH}/src/src_generic.c + ${SOF_AUDIO_PATH}/src/src_hifi3.c + ${SOF_AUDIO_PATH}/src/src_hifi4.c + ${SOF_AUDIO_PATH}/src/src.c + ${SOF_AUDIO_PATH}/src/src_ipc3.c + ) +elseif(CONFIG_IPC_MAJOR_4) + zephyr_library_sources_ifdef(CONFIG_COMP_SRC + ${SOF_AUDIO_PATH}/src/src_hifi2ep.c + ${SOF_AUDIO_PATH}/src/src_generic.c + ${SOF_AUDIO_PATH}/src/src_hifi3.c + ${SOF_AUDIO_PATH}/src/src_hifi4.c + ${SOF_AUDIO_PATH}/src/src.c + ${SOF_AUDIO_PATH}/src/src_ipc4.c + ) +endif() +zephyr_library_sources_ifdef(CONFIG_COMP_SRC_LITE + ${SOF_AUDIO_PATH}/src/src_lite.c +) zephyr_library_sources_ifdef(CONFIG_COMP_BASEFW_IPC4 ${SOF_AUDIO_PATH}/base_fw.c ) @@ -689,7 +727,7 @@ zephyr_library_sources_ifdef(CONFIG_COMP_MUX ) zephyr_library_sources_ifdef(CONFIG_COMP_GOOGLE_HOTWORD_DETECT - ${SOF_AUDIO_PATH}/google_hotword_detect.c + ${SOF_AUDIO_PATH}/google/google_hotword_detect.c ) zephyr_library_sources_ifdef(CONFIG_DTS_CODEC diff --git a/zephyr/Kconfig b/zephyr/Kconfig index 86c94a1de9a4..ea8c1d6e809f 100644 --- a/zephyr/Kconfig +++ b/zephyr/Kconfig @@ -56,4 +56,15 @@ config ZEPHYR_DP_SCHEDULER DP modules can be located in dieffrent cores than LL pipeline modules, may have different tick (i.e. 300ms for speech reccognition, etc.) +config CROSS_CORE_STREAM + bool "Enable cross-core connected pipelines" + default y if IPC_MAJOR_4 + help + Enables support for pipelines from different cores to be + connected together cross-core. So stream can travel from one + core to another. Note, this is different from "multicore" + support. In SOF "multicore" support means different streams + can be processed on different cores, however, each stream + is processed entirely on single core. + endif diff --git a/zephyr/lib/regions_mm.c b/zephyr/lib/regions_mm.c index cbf94e7f8fc8..dbb1aa087b26 100644 --- a/zephyr/lib/regions_mm.c +++ b/zephyr/lib/regions_mm.c @@ -132,8 +132,8 @@ struct vmh_heap *vmh_init_heap(const struct vmh_heap_config *cfg, new_heap->physical_blocks_allocators[i] = new_allocator; /* Fill allocators data based on config and virtual region data */ - new_allocator->num_blocks = cfg->block_bundles_table[i].number_of_blocks; - new_allocator->blk_sz_shift = ilog2(cfg->block_bundles_table[i].block_size); + new_allocator->info.num_blocks = cfg->block_bundles_table[i].number_of_blocks; + new_allocator->info.blk_sz_shift = ilog2(cfg->block_bundles_table[i].block_size); new_allocator->buffer = (uint8_t *)new_heap->virtual_region->addr + offset; /* Create bit array that is a part of mem_block kept as a ptr */ @@ -270,11 +270,11 @@ void *vmh_alloc(struct vmh_heap *heap, uint32_t alloc_size) * mem_block. */ block_size = - 1 << heap->physical_blocks_allocators[mem_block_iterator]->blk_sz_shift; + 1 << heap->physical_blocks_allocators[mem_block_iterator]->info.blk_sz_shift; block_count = SOF_DIV_ROUND_UP((uint64_t)alloc_size, (uint64_t)block_size); if (block_count > - heap->physical_blocks_allocators[mem_block_iterator]->num_blocks) + heap->physical_blocks_allocators[mem_block_iterator]->info.num_blocks) continue; /* Try span alloc on first available mem_block for non span * check if block size is sufficient. @@ -455,7 +455,7 @@ int vmh_free_heap(struct vmh_heap *heap) if (!heap->physical_blocks_allocators[i]) continue; if (!sys_bitarray_is_region_cleared(heap->physical_blocks_allocators[i]->bitmap, - heap->physical_blocks_allocators[i]->num_blocks, 0)) + heap->physical_blocks_allocators[i]->info.num_blocks, 0)) return -ENOTEMPTY; } @@ -492,24 +492,24 @@ int vmh_free(struct vmh_heap *heap, void *ptr) if (heap->core_id != cpu_get_id()) return -EINVAL; - size_t mem_block_iterator, i, size_to_free, block_size, ptr_bit_array_offset, + size_t mem_block_iter, i, size_to_free, block_size, ptr_bit_array_offset, ptr_bit_array_position, physical_block_count, check_offset, check_position, check_size; uintptr_t phys_aligned_ptr, phys_aligned_alloc_end, phys_block_ptr; bool ptr_range_found; /* Get allocator from which ptr was allocated */ - for (mem_block_iterator = 0, ptr_range_found = false; - mem_block_iterator < MAX_MEMORY_ALLOCATORS_COUNT; - mem_block_iterator++) { + for (mem_block_iter = 0, ptr_range_found = false; + mem_block_iter < MAX_MEMORY_ALLOCATORS_COUNT; + mem_block_iter++) { block_size = - 1 << heap->physical_blocks_allocators[mem_block_iterator]->blk_sz_shift; + 1 << heap->physical_blocks_allocators[mem_block_iter]->info.blk_sz_shift; if (vmh_is_ptr_in_memory_range((uintptr_t)ptr, (uintptr_t)heap->physical_blocks_allocators - [mem_block_iterator]->buffer, + [mem_block_iter]->buffer, heap->physical_blocks_allocators - [mem_block_iterator]->num_blocks * block_size)) { + [mem_block_iter]->info.num_blocks * block_size)) { ptr_range_found = true; break; } @@ -528,19 +528,19 @@ int vmh_free(struct vmh_heap *heap, void *ptr) /* Not sure if that is fastest way to find the size comments welcome */ ptr_bit_array_offset = (uintptr_t)ptr - - (uintptr_t)heap->physical_blocks_allocators[mem_block_iterator]->buffer; + - (uintptr_t)heap->physical_blocks_allocators[mem_block_iter]->buffer; ptr_bit_array_position = ptr_bit_array_offset / block_size; /* Allocation bit array check */ int bit_value, prev_bit_value = 0; - sys_bitarray_test_bit(heap->allocation_sizes[mem_block_iterator], + sys_bitarray_test_bit(heap->allocation_sizes[mem_block_iter], ptr_bit_array_position, &bit_value); /* If checked bit is in position 0 we assume it is valid * and assigned 0 for further logic */ if (ptr_bit_array_position) - sys_bitarray_test_bit(heap->allocation_sizes[mem_block_iterator], + sys_bitarray_test_bit(heap->allocation_sizes[mem_block_iter], ptr_bit_array_position - 1, &prev_bit_value); /* If bit is 1 we know we could be at the start of the allocation, @@ -556,7 +556,7 @@ int vmh_free(struct vmh_heap *heap, void *ptr) */ size_t bits_to_check = heap->physical_blocks_allocators - [mem_block_iterator]->num_blocks - ptr_bit_array_position; + [mem_block_iter]->info.num_blocks - ptr_bit_array_position; /* Neeeeeeeds optimization - thinking how to do it properly * each set bit in order after another means one allocated block. @@ -567,7 +567,7 @@ int vmh_free(struct vmh_heap *heap, void *ptr) i < bits_to_check; i++) { - sys_bitarray_test_bit(heap->allocation_sizes[mem_block_iterator], i, + sys_bitarray_test_bit(heap->allocation_sizes[mem_block_iter], i, &bit_value); if (bit_value) size_to_free += block_size; @@ -582,10 +582,10 @@ int vmh_free(struct vmh_heap *heap, void *ptr) } retval = sys_mem_blocks_free_contiguous( - heap->physical_blocks_allocators[mem_block_iterator], ptr, + heap->physical_blocks_allocators[mem_block_iter], ptr, size_to_free / block_size); } else { - retval = sys_mem_blocks_free(heap->physical_blocks_allocators[mem_block_iterator], + retval = sys_mem_blocks_free(heap->physical_blocks_allocators[mem_block_iter], 1, &ptr); } @@ -610,13 +610,13 @@ int vmh_free(struct vmh_heap *heap, void *ptr) phys_block_ptr = phys_aligned_ptr + i * CONFIG_MM_DRV_PAGE_SIZE; check_offset = phys_block_ptr - - (uintptr_t)heap->physical_blocks_allocators[mem_block_iterator]->buffer; + - (uintptr_t)heap->physical_blocks_allocators[mem_block_iter]->buffer; check_position = check_offset / block_size; check_size = CONFIG_MM_DRV_PAGE_SIZE / block_size; if (sys_bitarray_is_region_cleared( - heap->physical_blocks_allocators[mem_block_iterator]->bitmap, + heap->physical_blocks_allocators[mem_block_iter]->bitmap, check_size, check_offset)) sys_mm_drv_unmap_region((void *)phys_block_ptr, CONFIG_MM_DRV_PAGE_SIZE);