From 12eda76939d5f8cc72ebacda3f834fae40832a08 Mon Sep 17 00:00:00 2001 From: Andy Ross Date: Mon, 6 Jun 2022 07:49:27 -0700 Subject: [PATCH] arch/xtensa: Add CCOUNT-based timing API Expose the Xtenesa CCOUNT timing register (the lowest level CPU cycle counter) using the arch_timing_*() API. This is the simplest possible way to get this working. Future work might focus on moving the rate configuration into devicetree in a standard way, integrating with the platform clock driver on intel_adsp such that the reported cycle rate tracks runtime changes (though IIRC this is not a SOF requirement), and adding better test coverage to the timing layer, which right now isn't exercised anywhere but in benchmarks. Signed-off-by: Andy Ross --- arch/Kconfig | 1 + arch/xtensa/Kconfig | 7 +++ arch/xtensa/core/CMakeLists.txt | 2 +- arch/xtensa/core/timing.c | 58 +++++++++++++++++++++++++ soc/xtensa/intel_adsp/Kconfig.defconfig | 4 ++ 5 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 arch/xtensa/core/timing.c diff --git a/arch/Kconfig b/arch/Kconfig index e1657266aab..944bb959fb7 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -123,6 +123,7 @@ config XTENSA select USE_SWITCH select USE_SWITCH_SUPPORTED select IRQ_OFFLOAD_NESTED if IRQ_OFFLOAD + select ARCH_HAS_TIMING_FUNCTIONS imply ATOMIC_OPERATIONS_ARCH help Xtensa architecture diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 52fc7b38e16..637dd4bc837 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -87,4 +87,11 @@ config XTENSA_UNCACHED_REGION As for XTENSA_CACHED_REGION, this specifies which 512M region (0-7) contains the "uncached" mapping. +config XTENSA_CCOUNT_HZ + int "CCOUNT cycle rate" + default 1000000 + help + Rate in HZ of the Xtensa core as measured by the value of + the CCOUNT register. + endmenu diff --git a/arch/xtensa/core/CMakeLists.txt b/arch/xtensa/core/CMakeLists.txt index 4306e0a370c..ba9d820e505 100644 --- a/arch/xtensa/core/CMakeLists.txt +++ b/arch/xtensa/core/CMakeLists.txt @@ -19,7 +19,7 @@ zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c) zephyr_library_sources_ifdef(CONFIG_XTENSA_ENABLE_BACKTRACE xtensa_backtrace.c) zephyr_library_sources_ifdef(CONFIG_XTENSA_ENABLE_BACKTRACE debug_helpers_asm.S) zephyr_library_sources_ifdef(CONFIG_DEBUG_COREDUMP coredump.c) - +zephyr_library_sources_ifdef(CONFIG_TIMING_FUNCTIONS timing.c) zephyr_library_sources_ifdef(CONFIG_GDBSTUB gdbstub.c) if("${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "xcc") diff --git a/arch/xtensa/core/timing.c b/arch/xtensa/core/timing.c new file mode 100644 index 00000000000..64c7efc68be --- /dev/null +++ b/arch/xtensa/core/timing.c @@ -0,0 +1,58 @@ +/* Copyright (c) 2022 Intel Corporation + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +void arch_timing_init(void) +{ +} + +void arch_timing_start(void) +{ +} + +void arch_timing_stop(void) +{ +} + +uint64_t arch_timing_freq_get(void) +{ + return CONFIG_XTENSA_CCOUNT_HZ; +} + +timing_t arch_timing_counter_get(void) +{ + uint32_t ccount; + + __asm__ volatile ("rsr %0, CCOUNT" : "=r"(ccount)); + + return ccount; +} + +uint64_t arch_timing_cycles_get(volatile timing_t *const start, + volatile timing_t *const end) +{ + int64_t dt = (int64_t) (*end - *start); + + if (dt < 0) { + dt += 0x100000000ULL; + } + + return (uint64_t) dt; +} + +uint64_t arch_timing_cycles_to_ns(uint64_t cycles) +{ + return cycles * (1000000000ULL / CONFIG_XTENSA_CCOUNT_HZ); +} + +uint64_t arch_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count) +{ + /* Why is this an arch API? This is just math! */ + return cycles / (uint64_t) count; +} + +uint32_t arch_timing_freq_get_mhz(void) +{ + return arch_timing_freq_get() / 1000000ULL; +} diff --git a/soc/xtensa/intel_adsp/Kconfig.defconfig b/soc/xtensa/intel_adsp/Kconfig.defconfig index 953ac9f16fe..f697aa953af 100644 --- a/soc/xtensa/intel_adsp/Kconfig.defconfig +++ b/soc/xtensa/intel_adsp/Kconfig.defconfig @@ -27,4 +27,8 @@ config I2S_CAVS default y depends on I2S +config XTENSA_CCOUNT_HZ + default 400000000 if SOC_SERIES_INTEL_CAVS_V25 + default 200000000 + endif # INTEL_ADSP_CAVS