From 1303d48c49a61f14a2d9acf32ebaa4664539b731 Mon Sep 17 00:00:00 2001 From: Ayoung Sim Date: Wed, 14 Mar 2018 10:52:30 +0900 Subject: [PATCH] media: mfc: DRV3.2: support the SFR dump mode Whenever we want to check the SFRs, we can control by as below sysfs command. ex) echo 8 > /d/mfc/sfr_dump Change-Id: I152cb042c1c2ef2217e840c9e38575ed6c0709a8 Signed-off-by: Ayoung Sim --- .../media/platform/exynos/mfc/s5p_mfc_cmd.c | 8 +++++++ .../platform/exynos/mfc/s5p_mfc_data_struct.h | 15 +++++++++++++ .../media/platform/exynos/mfc/s5p_mfc_debug.h | 1 + .../platform/exynos/mfc/s5p_mfc_debugfs.c | 15 +++++++++++++ .../platform/exynos/mfc/s5p_mfc_dec_vb2_ops.c | 1 + .../platform/exynos/mfc/s5p_mfc_hwlock.c | 2 +- .../media/platform/exynos/mfc/s5p_mfc_inst.c | 20 ++++++++++++++++++ .../media/platform/exynos/mfc/s5p_mfc_irq.c | 8 ++++++- .../media/platform/exynos/mfc/s5p_mfc_irq.h | 21 +++---------------- .../media/platform/exynos/mfc/s5p_mfc_nal_q.c | 1 - .../media/platform/exynos/mfc/s5p_mfc_utils.h | 17 +++++++++++++++ .../platform/exynos/mfc/s5p_mfc_watchdog.c | 1 + 12 files changed, 89 insertions(+), 21 deletions(-) diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_cmd.c b/drivers/media/platform/exynos/mfc/s5p_mfc_cmd.c index 1131d35bfc26..0d7e5c8a2a01 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_cmd.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_cmd.c @@ -239,6 +239,10 @@ int s5p_mfc_cmd_dec_init_buffers(struct s5p_mfc_ctx *ctx) } MFC_WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID); + + if (sfr_dump & MFC_DUMP_DEC_INIT_BUFS) + call_dop(dev, dump_regs, dev); + s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_INIT_BUFFERS); return ret; @@ -285,6 +289,10 @@ int s5p_mfc_cmd_enc_init_buffers(struct s5p_mfc_ctx *ctx) } MFC_WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID); + + if (sfr_dump & MFC_DUMP_ENC_INIT_BUFS) + call_dop(dev, dump_regs, dev); + s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_INIT_BUFFERS); return ret; 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 19dcf6aa1805..d892b6df4fc8 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h @@ -312,6 +312,18 @@ struct s5p_mfc_variant { int num_entities; }; +enum mfc_sfr_dump_type { + MFC_DUMP_NONE = 0, + MFC_DUMP_DEC_SEQ_START = (1 << 0), + MFC_DUMP_DEC_INIT_BUFS = (1 << 1), + MFC_DUMP_DEC_NAL_START = (1 << 2), + MFC_DUMP_ENC_SEQ_START = (1 << 3), + MFC_DUMP_ENC_INIT_BUFS = (1 << 4), + MFC_DUMP_ENC_NAL_START = (1 << 5), + MFC_DUMP_ERR_INT = (1 << 6), + MFC_DUMP_WARN_INT = (1 << 7), +}; + struct s5p_mfc_debugfs { struct dentry *root; struct dentry *mfc_info; @@ -324,6 +336,7 @@ struct s5p_mfc_debugfs { struct dentry *nal_q_parallel_disable; struct dentry *otf_dump; struct dentry *perf_measure_option; + struct dentry *sfr_dump; }; /** @@ -652,6 +665,7 @@ struct s5p_mfc_perf { extern struct s5p_mfc_dump_ops mfc_dump_ops; struct s5p_mfc_dump_ops { + void (*dump_regs)(struct s5p_mfc_dev *dev); void (*dump_and_stop_always)(struct s5p_mfc_dev *dev); }; @@ -1358,6 +1372,7 @@ struct s5p_mfc_ctx { struct _otf_handle *otf_handle; int batch_mode; + bool check_dump; }; #endif /* __S5P_MFC_DATA_STRUCT_H */ diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h b/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h index f3fb64544126..c3eebc00893f 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h @@ -24,6 +24,7 @@ extern unsigned int nal_q_dump; extern unsigned int nal_q_disable; extern unsigned int nal_q_parallel_disable; extern unsigned int otf_dump; +extern unsigned int sfr_dump; #define mfc_debug(level, fmt, args...) \ do { \ diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c b/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c index a3d1d838ddbc..ec2f015a9dd1 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c @@ -28,6 +28,7 @@ unsigned int nal_q_disable; unsigned int nal_q_parallel_disable; unsigned int otf_dump; unsigned int perf_measure_option; +unsigned int sfr_dump; static int mfc_info_show(struct seq_file *s, void *unused) { @@ -77,6 +78,18 @@ static int mfc_info_show(struct seq_file *s, void *unused) static int mfc_debug_info_show(struct seq_file *s, void *unused) { seq_puts(s, ">> MFC debug information\n"); + + seq_puts(s, "-----SFR dump options (bit setting)\n"); + seq_puts(s, "ex) echo 0xff > /d/mfc/sfr_dump (all dump mode)\n"); + seq_puts(s, "1 (1 << 0): dec SEQ_START\n"); + seq_puts(s, "2 (1 << 1): dec INIT_BUFS\n"); + seq_puts(s, "4 (1 << 2): dec NAL_START\n"); + seq_puts(s, "8 (1 << 3): enc SEQ_START\n"); + seq_puts(s, "16 (1 << 4): enc INIT_BUFS\n"); + seq_puts(s, "32 (1 << 5): enc NAL_START\n"); + seq_puts(s, "64 (1 << 6): ERR interrupt\n"); + seq_puts(s, "128 (1 << 7): WARN interrupt\n"); + return 0; } @@ -134,4 +147,6 @@ void s5p_mfc_init_debugfs(struct s5p_mfc_dev *dev) 0644, debugfs->root, &otf_dump); debugfs->perf_measure_option = debugfs_create_u32("perf_measure_option", 0644, debugfs->root, &perf_measure_option); + debugfs->sfr_dump = debugfs_create_u32("sfr_dump", + 0644, debugfs->root, &sfr_dump); } diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_dec_vb2_ops.c b/drivers/media/platform/exynos/mfc/s5p_mfc_dec_vb2_ops.c index f5e48ed46678..500163bb3653 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_dec_vb2_ops.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_dec_vb2_ops.c @@ -419,6 +419,7 @@ static void mfc_dec_src_stop_streaming(struct s5p_mfc_ctx *ctx) dec->consumed = 0; dec->remained_size = 0; + ctx->check_dump = 0; s5p_mfc_init_queue(&ctx->src_buf_queue); diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_hwlock.c b/drivers/media/platform/exynos/mfc/s5p_mfc_hwlock.c index 21c7beab17cb..095cd3a9c6a0 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_hwlock.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_hwlock.c @@ -857,7 +857,7 @@ int s5p_mfc_just_run(struct s5p_mfc_dev *dev, int new_ctx_index) s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->src_buf_queue), s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->dst_buf_queue), ctx->state, ctx->dpb_count); - mfc_debug(2, "ctx->state=%d\n", ctx->state); + mfc_debug(2, "ctx->state = %d\n", ctx->state); /* Last frame has already been sent to MFC * Now obtaining frames from MFC buffer */ diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_inst.c b/drivers/media/platform/exynos/mfc/s5p_mfc_inst.c index e9fa1e03fc59..4832435be307 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_inst.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_inst.c @@ -189,6 +189,10 @@ int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx) mfc_debug(2, "SEI enable was set, 0x%x\n", MFC_READL(S5P_FIMV_D_SEI_ENABLE)); MFC_WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID); + + if (sfr_dump & MFC_DUMP_DEC_SEQ_START) + call_dop(dev, dump_regs, dev); + s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_SEQ_HEADER); mfc_debug_leave(); @@ -236,6 +240,12 @@ int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx, int last_frame) MFC_WRITEL(MFC_TIMEOUT_VALUE, S5P_FIMV_DEC_TIMEOUT_VALUE); MFC_WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID); + + if ((sfr_dump & MFC_DUMP_DEC_NAL_START) && !ctx->check_dump) { + call_dop(dev, dump_regs, dev); + ctx->check_dump = 1; + } + /* Issue different commands to instance basing on whether it * is the last frame or not. */ switch (last_frame) { @@ -286,6 +296,10 @@ int s5p_mfc_init_encode(struct s5p_mfc_ctx *ctx) MFC_READL(S5P_FIMV_E_RC_MODE)); MFC_WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID); + + if (sfr_dump & MFC_DUMP_ENC_SEQ_START) + call_dop(dev, dump_regs, dev); + s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_SEQ_HEADER); mfc_debug(2, "--\n"); @@ -411,6 +425,12 @@ int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *ctx, int last_frame) } MFC_WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID); + + if ((sfr_dump & MFC_DUMP_ENC_NAL_START) && !ctx->check_dump) { + call_dop(dev, dump_regs, dev); + ctx->check_dump = 1; + } + /* Issue different commands to instance basing on whether it * is the last frame or not. */ switch (last_frame) { diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c b/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c index 957edd69a945..af512fa88347 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c @@ -25,7 +25,6 @@ #include "s5p_mfc_qos.h" #include "s5p_mfc_queue.h" -#include "s5p_mfc_utils.h" #include "s5p_mfc_buf.h" #include "s5p_mfc_mem.h" @@ -1539,6 +1538,13 @@ irqreturn_t s5p_mfc_irq(int irq, void *priv) if (dbg_enable && (reason != S5P_FIMV_R2H_CMD_QUEUE_DONE_RET)) s5p_mfc_dbg_disable(dev); + if ((sfr_dump & MFC_DUMP_ERR_INT) && (reason == S5P_FIMV_R2H_CMD_ERR_RET)) + call_dop(dev, dump_regs, dev); + + if ((sfr_dump & MFC_DUMP_WARN_INT) && + (err && (reason != S5P_FIMV_R2H_CMD_ERR_RET))) + call_dop(dev, dump_regs, dev); + #ifdef NAL_Q_ENABLE if (dev->nal_q_handle) { ret = mfc_nal_q_irq(dev, reason, err); diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_irq.h b/drivers/media/platform/exynos/mfc/s5p_mfc_irq.h index 1aa1799a66b3..9ef20f87f994 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_irq.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_irq.h @@ -16,32 +16,17 @@ #include #include "s5p_mfc_common.h" -#include "s5p_mfc_reg.h" + +#include "s5p_mfc_utils.h" irqreturn_t s5p_mfc_top_half_irq(int irq, void *priv); irqreturn_t s5p_mfc_irq(int irq, void *priv); -static inline int s5p_mfc_dec_status_decoding(unsigned int dst_frame_status) -{ - if (dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_DISPLAY || - dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_ONLY) - return 1; - return 0; -} - -static inline int s5p_mfc_dec_status_display(unsigned int dst_frame_status) -{ - if (dst_frame_status == S5P_FIMV_DEC_STATUS_DISPLAY_ONLY || - dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_DISPLAY) - return 1; - - return 0; -} - static inline void s5p_mfc_handle_force_change_status(struct s5p_mfc_ctx *ctx) { if (ctx->state != MFCINST_ABORT && ctx->state != MFCINST_HEAD_PARSED && ctx->state != MFCINST_RES_CHANGE_FLUSH) s5p_mfc_change_state(ctx, MFCINST_RUNNING); } + #endif /* __S5P_MFC_IRQ_H */ diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c b/drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c index d6e097b48d85..399690b1dc2d 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c @@ -23,7 +23,6 @@ #include "s5p_mfc_utils.h" #include "s5p_mfc_buf.h" #include "s5p_mfc_mem.h" -#include "s5p_mfc_irq.h" #ifdef NAL_Q_ENABLE #define CBR_I_LIMIT_MAX 5 diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_utils.h b/drivers/media/platform/exynos/mfc/s5p_mfc_utils.h index 27c9166b4258..e933321f3fdb 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_utils.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_utils.h @@ -146,6 +146,23 @@ static inline void s5p_mfc_clear_assigned_dpb(struct s5p_mfc_ctx *ctx) dec->assigned_dpb[i] = NULL; } +static inline int s5p_mfc_dec_status_decoding(unsigned int dst_frame_status) +{ + if (dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_DISPLAY || + dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_ONLY) + return 1; + return 0; +} + +static inline int s5p_mfc_dec_status_display(unsigned int dst_frame_status) +{ + if (dst_frame_status == S5P_FIMV_DEC_STATUS_DISPLAY_ONLY || + dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_DISPLAY) + return 1; + + return 0; +} + void s5p_mfc_cleanup_assigned_dpb(struct s5p_mfc_ctx *ctx); void s5p_mfc_unprotect_released_dpb(struct s5p_mfc_ctx *ctx, unsigned int released_flag); void s5p_mfc_protect_dpb(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *dst_mb); diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_watchdog.c b/drivers/media/platform/exynos/mfc/s5p_mfc_watchdog.c index 0009f79cdf26..c80d9636dcaf 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_watchdog.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_watchdog.c @@ -320,5 +320,6 @@ void s5p_mfc_watchdog_worker(struct work_struct *work) } struct s5p_mfc_dump_ops mfc_dump_ops = { + .dump_regs = mfc_dump_regs, .dump_and_stop_always = mfc_dump_info_and_stop_hw, }; -- 2.20.1