From 3ca31175742aba00d26c3b2427b28e7bd6372bb7 Mon Sep 17 00:00:00 2001 From: Jiho Chang Date: Sat, 7 Oct 2017 06:19:16 +0000 Subject: [PATCH] media: mfc: add performance measuring Change-Id: I347ddd5d3d2441ea2fc2eda7c838c1b42b72d9e4 Signed-off-by: Jiho Chang --- drivers/media/platform/exynos/mfc/Makefile | 2 +- drivers/media/platform/exynos/mfc/s5p_mfc.c | 6 + .../platform/exynos/mfc/s5p_mfc_data_struct.h | 15 +++ .../platform/exynos/mfc/s5p_mfc_debugfs.c | 3 + .../media/platform/exynos/mfc/s5p_mfc_inst.c | 5 + .../media/platform/exynos/mfc/s5p_mfc_irq.c | 3 + .../exynos/mfc/s5p_mfc_perf_measure.c | 26 +++++ .../exynos/mfc/s5p_mfc_perf_measure.h | 106 ++++++++++++++++++ .../media/platform/exynos/mfc/s5p_mfc_sync.c | 4 + 9 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 drivers/media/platform/exynos/mfc/s5p_mfc_perf_measure.c create mode 100644 drivers/media/platform/exynos/mfc/s5p_mfc_perf_measure.h diff --git a/drivers/media/platform/exynos/mfc/Makefile b/drivers/media/platform/exynos/mfc/Makefile index 75e203ebb218..36de58256e30 100644 --- a/drivers/media/platform/exynos/mfc/Makefile +++ b/drivers/media/platform/exynos/mfc/Makefile @@ -1,7 +1,7 @@ obj-$(CONFIG_VIDEO_EXYNOS_MFC) := s5p-mfc.o s5p-mfc-y += s5p_mfc.o s5p_mfc_irq.o s5p_mfc_dec.o s5p_mfc_dec_vb2_ops.o s5p_mfc_enc.o s5p_mfc_enc_vb2_ops.o s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_hwlock.o s5p_mfc_nal_q.o s5p_mfc_watchdog.o s5p_mfc_opr.o s5p_mfc_sync.o -s5p-mfc-y += s5p_mfc_pm.o s5p_mfc_inst.o s5p_mfc_cmd.o s5p_mfc_cal.o s5p_mfc_reg.o +s5p-mfc-y += s5p_mfc_pm.o s5p_mfc_inst.o s5p_mfc_cmd.o s5p_mfc_cal.o s5p_mfc_reg.o s5p_mfc_perf_measure.o s5p-mfc-y += s5p_mfc_dec_ops.o s5p_mfc_enc_ops.o s5p_mfc_enc_param.o s5p-mfc-y += s5p_mfc_queue.o s5p_mfc_buf.o s5p_mfc_utils.o s5p_mfc_qos.o s5p_mfc_mem.o s5p-mfc-y += s5p_mfc_debugfs.o s5p_mfc_otf.o diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc.c b/drivers/media/platform/exynos/mfc/s5p_mfc.c index 95c324807bac..d27b81f633ef 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc.c @@ -37,6 +37,7 @@ #include "s5p_mfc_inst.h" #include "s5p_mfc_pm.h" #include "s5p_mfc_cal.h" +#include "s5p_mfc_perf_measure.h" #include "s5p_mfc_reg.h" #include "s5p_mfc_qos.h" @@ -561,6 +562,7 @@ static int s5p_mfc_open(struct file *file) goto err_init_inst; } + s5p_mfc_perf_init(dev); trace_mfc_node_open(ctx->num, dev->num_inst, ctx->type, ctx->is_drm); mfc_info_ctx("MFC open completed [%d:%d] dev = 0x%p, ctx = 0x%p, version = %d\n", dev->num_drm_inst, dev->num_inst, dev, ctx, MFC_DRIVER_INFO); @@ -758,6 +760,8 @@ static int s5p_mfc_release(struct file *file) dev->ctx[ctx->num] = 0; kfree(ctx); + s5p_mfc_perf_print(); + mfc_info_dev("mfc driver release finished [%d:%d], dev = 0x%p\n", dev->num_drm_inst, dev->num_inst, dev); @@ -974,6 +978,8 @@ static int mfc_register_resource(struct platform_device *pdev, struct s5p_mfc_de struct resource *res; int ret; + s5p_mfc_perf_register(dev); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "failed to get memory region resource\n"); diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h b/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h index 1b1767038cff..fbbbfeeb1a2d 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h @@ -319,6 +319,7 @@ struct s5p_mfc_debugfs { struct dentry *nal_q_disable; struct dentry *nal_q_parallel_disable; struct dentry *otf_dump; + struct dentry *perf_measure_option; }; /** @@ -633,6 +634,18 @@ struct _otf_handle { }; /********************************************************************/ +struct s5p_mfc_perf { + void __iomem *regs_base0; + void __iomem *regs_base1; + + struct timeval begin; + struct timeval end; + + int new_start; + int count; + int drv_margin; +}; + /** * struct s5p_mfc_dev - The struct containing driver internal parameters. */ @@ -735,6 +748,8 @@ struct s5p_mfc_dev { #endif struct s5p_mfc_debugfs debugfs; + + struct s5p_mfc_perf perf; }; /** diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c b/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c index f29b008126ef..a3d1d838ddbc 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c @@ -27,6 +27,7 @@ unsigned int nal_q_dump; unsigned int nal_q_disable; unsigned int nal_q_parallel_disable; unsigned int otf_dump; +unsigned int perf_measure_option; static int mfc_info_show(struct seq_file *s, void *unused) { @@ -131,4 +132,6 @@ void s5p_mfc_init_debugfs(struct s5p_mfc_dev *dev) 0644, debugfs->root, &nal_q_parallel_disable); debugfs->otf_dump = debugfs_create_u32("otf_dump", 0644, debugfs->root, &otf_dump); + debugfs->perf_measure_option = debugfs_create_u32("perf_measure_option", + 0644, debugfs->root, &perf_measure_option); } diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_inst.c b/drivers/media/platform/exynos/mfc/s5p_mfc_inst.c index 72f39b30ac8d..e9fa1e03fc59 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_inst.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_inst.c @@ -15,6 +15,7 @@ #include "s5p_mfc_cmd.h" #include "s5p_mfc_enc_param.h" #include "s5p_mfc_cal.h" +#include "s5p_mfc_perf_measure.h" #include "s5p_mfc_reg.h" #include "s5p_mfc_utils.h" @@ -239,6 +240,8 @@ int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx, int last_frame) * is the last frame or not. */ switch (last_frame) { case 0: + s5p_mfc_perf_measure_on(dev); + s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_NAL_START); break; case 1: @@ -412,6 +415,8 @@ int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *ctx, int last_frame) * is the last frame or not. */ switch (last_frame) { case 0: + s5p_mfc_perf_measure_on(dev); + s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_NAL_START); break; case 1: diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c b/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c index bb06159d2f2a..76d039fb4e00 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c @@ -21,6 +21,7 @@ #include "s5p_mfc_pm.h" #include "s5p_mfc_cal.h" +#include "s5p_mfc_perf_measure.h" #include "s5p_mfc_reg.h" #include "s5p_mfc_qos.h" @@ -1277,6 +1278,8 @@ irqreturn_t s5p_mfc_top_half_irq(int irq, void *priv) dev->curr_ctx, reason, err); MFC_TRACE_CTX("<< INT(top): %d\n", reason); + s5p_mfc_perf_measure_off(dev); + return IRQ_WAKE_THREAD; } diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_perf_measure.c b/drivers/media/platform/exynos/mfc/s5p_mfc_perf_measure.c new file mode 100644 index 000000000000..47e7731ebf38 --- /dev/null +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_perf_measure.c @@ -0,0 +1,26 @@ +/* + * drivers/media/platform/exynos/mfc/s5p_mfc_perf_measure.c + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include "s5p_mfc_perf_measure.h" + +#ifndef PERF_MEASURE + +void s5p_mfc_perf_register(struct s5p_mfc_dev *dev) {} +void mfc_measure_init(void) {} +void mfc_measure_on(struct s5p_mfc_dev *dev) {} +void mfc_measure_off(struct s5p_mfc_dev *dev) {} +void mfc_measure_store(struct s5p_mfc_dev *dev, int diff) {} +void s5p_mfc_perf_print(void) {} + +#else + +#endif diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_perf_measure.h b/drivers/media/platform/exynos/mfc/s5p_mfc_perf_measure.h new file mode 100644 index 000000000000..7c4426bf4e11 --- /dev/null +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_perf_measure.h @@ -0,0 +1,106 @@ +/* + * drivers/media/platform/exynos/mfc/s5p_mfc_perf_measure.h + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __S5P_MFC_PERF_MEASURE_H +#define __S5P_MFC_PERF_MEASURE_H __FILE__ + +#include + +#include "s5p_mfc_reg.h" + +void s5p_mfc_perf_register(struct s5p_mfc_dev *dev); +void mfc_measure_init(void); +void mfc_measure_on(struct s5p_mfc_dev *dev); +void mfc_measure_off(struct s5p_mfc_dev *dev); +void mfc_measure_store(struct s5p_mfc_dev *dev, int diff); +void s5p_mfc_perf_print(void); + +//#define PERF_MEASURE + +#ifndef PERF_MEASURE + +static inline void s5p_mfc_perf_init(struct s5p_mfc_dev *dev) {} +static inline void s5p_mfc_perf_cancel_drv_margin(struct s5p_mfc_dev *dev) {} +static inline void s5p_mfc_perf_measure_on(struct s5p_mfc_dev *dev) {} +static inline void s5p_mfc_perf_measure_off(struct s5p_mfc_dev *dev) {} + +#else + +extern unsigned int perf_measure_option; + +static inline void s5p_mfc_perf_init(struct s5p_mfc_dev *dev) +{ + dev->perf.new_start = 0; + dev->perf.count = 0; + dev->perf.drv_margin = 0; + + mfc_measure_init(); + + mfc_info_dev("MFC frequency : %ld\n", clk_get_rate(dev->pm.clock)); +} + +static inline void s5p_mfc_perf_cancel_drv_margin(struct s5p_mfc_dev *dev) +{ + dev->perf.drv_margin = 0; +} + +static inline void s5p_mfc_perf_measure_on(struct s5p_mfc_dev *dev) +{ + int diff; + + if (dev->perf.drv_margin) { + do_gettimeofday(&dev->perf.end); + + diff = (dev->perf.end.tv_sec * 1000000 + dev->perf.end.tv_usec) + - (dev->perf.begin.tv_sec * 1000000 + dev->perf.begin.tv_usec); + + mfc_info_dev("IRQ -> NAL_START time(ms) = %03d.%03d\n", diff / 1000, diff % 1000); + + dev->perf.drv_margin = 0; + } + + do_gettimeofday(&dev->perf.begin); + + mfc_measure_on(dev); + + dev->perf.new_start = 1; + dev->perf.count++; +} + +static inline void s5p_mfc_perf_measure_off(struct s5p_mfc_dev *dev) +{ + unsigned int diff; + + if ((dev->perf.new_start) && (dev->perf.count > 0)) { + mfc_measure_off(dev); + + do_gettimeofday(&dev->perf.end); + + diff = (dev->perf.end.tv_sec * 1000000 + dev->perf.end.tv_usec) + - (dev->perf.begin.tv_sec * 1000000 + dev->perf.begin.tv_usec); + + mfc_measure_store(dev, diff); + + mfc_debug(3, "uDECtype :%d, uENCtype :%d, codectype :%d\n", + s5p_mfc_get_dec_frame_type(), s5p_mfc_get_enc_slice_type(), MFC_READL(S5P_FIMV_CODEC_TYPE)); + + dev->perf.drv_margin = 1; + + do_gettimeofday(&dev->perf.begin); + } + + dev->perf.new_start = 0; +} + +#endif + +#endif /* __S5P_MFC_PERF_MEASURE_H */ diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_sync.c b/drivers/media/platform/exynos/mfc/s5p_mfc_sync.c index a4ecf11f9595..66fbf1fbbc49 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_sync.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_sync.c @@ -12,6 +12,8 @@ #include "s5p_mfc_sync.h" +#include "s5p_mfc_perf_measure.h" + #include "s5p_mfc_queue.h" #define R2H_BIT(x) (((x) > 0) ? (1 << ((x) - 1)) : 0) @@ -230,6 +232,7 @@ int s5p_mfc_dec_ctx_ready(struct s5p_mfc_ctx *ctx) src_buf_queue_greater_than_0) return 1; + s5p_mfc_perf_cancel_drv_margin(dev); mfc_debug(2, "ctx is not ready.\n"); return 0; @@ -296,6 +299,7 @@ int s5p_mfc_enc_ctx_ready(struct s5p_mfc_ctx *ctx) src_buf_queue_greater_than_0 && dst_buf_queue_greater_than_0) return 1; + s5p_mfc_perf_cancel_drv_margin(dev); mfc_debug(2, "ctx is not ready.\n"); return 0; -- 2.20.1