calculate the percentage of cpu cyle based on the CCOUNT register. which can tell the percentage of cpu cycle usage. It is the rough calculation.
Signed-off-by: Wu Zhigang zhigang.wu@linux.intel.com --- src/audio/dai.c | 22 ++++++++++++++++++++++ src/include/sof/wait.h | 8 ++++++++ src/tasks/audio.c | 10 ++++++++++ 3 files changed, 40 insertions(+)
diff --git a/src/audio/dai.c b/src/audio/dai.c index f6f16d7..11b20c5 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -43,11 +43,14 @@ #include <sof/audio/component.h> #include <sof/audio/pipeline.h> #include <platform/dma.h> +#include <platform/clk.h> #include <arch/cache.h>
#define DAI_PLAYBACK_STREAM 0 #define DAI_CAPTURE_STREAM 1
+#define CPU_CYCLE_PER_MS (CLK_DEFAULT_CPU_HZ / 1000) + /* tracing */ #define trace_dai(__e) trace_event(TRACE_CLASS_DAI, __e) #define trace_dai_error(__e) trace_error(TRACE_CLASS_DAI, __e) @@ -72,6 +75,22 @@ struct dai_data { uint64_t wallclock; /* wall clock at stream start */ };
+static void calc_cpu_usage(struct pipeline *p) +{ + uint32_t delta = 0; + + delta = global_cycle; + global_cycle = 0; + if (delta > CPU_CYCLE_PER_MS) + delta = CPU_CYCLE_PER_MS; + delta = (delta * 100) / CPU_CYCLE_PER_MS; + + trace_dai_error("PcT"); + + /* the percentage of the cpu usage in 1ms */ + trace_error_value(100 - delta); +} + /* this is called by DMA driver every time descriptor has completed */ static void dai_dma_cb(void *data, uint32_t type, struct dma_sg_elem *next) { @@ -81,6 +100,9 @@ static void dai_dma_cb(void *data, uint32_t type, struct dma_sg_elem *next)
tracev_dai("irq");
+ if (dev->params.direction == SOF_IPC_STREAM_PLAYBACK) + calc_cpu_usage(dev->pipeline); + /* stop dma copy for pause/stop/xrun */ if (dev->state != COMP_STATE_ACTIVE || dd->xrun) {
diff --git a/src/include/sof/wait.h b/src/include/sof/wait.h index feb8b29..4baa8de 100644 --- a/src/include/sof/wait.h +++ b/src/include/sof/wait.h @@ -43,6 +43,7 @@ #include <sof/trace.h> #include <sof/lock.h> #include <platform/interrupt.h> +#include <xtensa/hal.h>
#if DEBUG_LOCKS #define wait_atomic_check \ @@ -157,4 +158,11 @@ static inline void wait_delay(uint64_t number_of_clks) idelay(PLATFORM_DEFAULT_DELAY); }
+uint32_t global_cycle; + +static inline uint32_t platform_get_cpu_count(void) +{ + return xthal_get_ccount(); +} + #endif diff --git a/src/tasks/audio.c b/src/tasks/audio.c index 5beae08..1a79808 100644 --- a/src/tasks/audio.c +++ b/src/tasks/audio.c @@ -51,6 +51,9 @@ struct audio_data { struct pipeline *p; };
+uint32_t global_cycle; +static uint32_t c1, c2; + int do_task(struct sof *sof) { #ifdef STATIC_PIPE @@ -78,13 +81,20 @@ int do_task(struct sof *sof) /* let host know DSP boot is complete */ platform_boot_complete(0);
+ global_cycle = 0; + /* main audio IPC processing loop */ while (1) {
+ c1 = platform_get_cpu_count(); + /* sleep until next IPC or DMA */ sa_enter_idle(sof); wait_for_interrupt(0);
+ c2 = platform_get_cpu_count(); + global_cycle += c2 - c1; + /* now process any IPC messages from host */ ipc_process_msg_queue();