From: Jeonghee Kim Date: Mon, 20 Aug 2018 07:22:15 +0000 (+0900) Subject: [COMMON] media: mfc: added register test mode X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=859c56e3be467d5746db6aaa3bfbda20f228b677;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git [COMMON] media: mfc: added register test mode It is added for OTF bit-matching test. However, it can be used anytime when performing an encoding test using register dump. Change-Id: I0f68cbf0690ef920a73b892c46d9b2ece85ba463 Signed-off-by: Jeonghee Kim --- diff --git a/drivers/media/platform/exynos/mfc/mfc_cmd.c b/drivers/media/platform/exynos/mfc/mfc_cmd.c index c9278aa86b1f..9323384d08fc 100644 --- a/drivers/media/platform/exynos/mfc/mfc_cmd.c +++ b/drivers/media/platform/exynos/mfc/mfc_cmd.c @@ -260,6 +260,9 @@ int mfc_cmd_enc_seq_header(struct mfc_ctx *ctx) MFC_WRITEL(ctx->inst_no, MFC_REG_INSTANCE_ID); + if (reg_test) + mfc_set_test_params(dev); + if (sfr_dump & MFC_DUMP_ENC_SEQ_START) call_dop(dev, dump_regs, dev); diff --git a/drivers/media/platform/exynos/mfc/mfc_data_struct.h b/drivers/media/platform/exynos/mfc/mfc_data_struct.h index 282997639e2d..953370b20e6b 100644 --- a/drivers/media/platform/exynos/mfc/mfc_data_struct.h +++ b/drivers/media/platform/exynos/mfc/mfc_data_struct.h @@ -320,6 +320,10 @@ struct mfc_debugfs { struct dentry *root; struct dentry *mfc_info; struct dentry *debug_info; +#ifdef CONFIG_MFC_REG_TEST + struct dentry *reg_info; + struct dentry *reg_test; +#endif struct dentry *debug_level; struct dentry *debug_ts; struct dentry *dbg_enable; @@ -838,6 +842,10 @@ struct mfc_dev { struct notifier_block itmon_nb; #endif int itmon_notified; + + char *reg_buf; + unsigned int *reg_val; + unsigned int reg_cnt; }; /** diff --git a/drivers/media/platform/exynos/mfc/mfc_debug.h b/drivers/media/platform/exynos/mfc/mfc_debug.h index 22eda0a3bfbf..b18b0a8788f7 100644 --- a/drivers/media/platform/exynos/mfc/mfc_debug.h +++ b/drivers/media/platform/exynos/mfc/mfc_debug.h @@ -28,6 +28,7 @@ extern unsigned int sfr_dump; extern unsigned int mmcache_dump; extern unsigned int mmcache_disable; extern unsigned int perf_boost_mode; +extern unsigned int reg_test; #define mfc_debug(level, fmt, args...) \ do { \ diff --git a/drivers/media/platform/exynos/mfc/mfc_debugfs.c b/drivers/media/platform/exynos/mfc/mfc_debugfs.c index dfa8e7cbc3bf..824471bd00fa 100644 --- a/drivers/media/platform/exynos/mfc/mfc_debugfs.c +++ b/drivers/media/platform/exynos/mfc/mfc_debugfs.c @@ -32,6 +32,7 @@ unsigned int sfr_dump; unsigned int mmcache_dump; unsigned int mmcache_disable; unsigned int perf_boost_mode; +unsigned int reg_test; static int __mfc_info_show(struct seq_file *s, void *unused) { @@ -123,6 +124,76 @@ static int __mfc_debug_info_show(struct seq_file *s, void *unused) return 0; } +#ifdef CONFIG_MFC_REG_TEST +static int __mfc_reg_info_show(struct seq_file *s, void *unused) +{ + struct mfc_dev *dev = g_mfc_dev; + unsigned int i; + + seq_puts(s, ">> MFC REG test(encoder)\n"); + + seq_printf(s, "-----Register test on/off: %s\n", reg_test ? "on" : "off"); + seq_printf(s, "-----Register number: %d\n", dev->reg_cnt); + + if (dev->reg_val) { + seq_puts(s, "-----Register values\n"); + for (i = 0; i < dev->reg_cnt; i++) { + seq_printf(s, "%08x ", dev->reg_val[i]); + if ((i % 8) == 7) + seq_printf(s, "\n"); + } + } else { + seq_puts(s, "-----There is no reg_buf, set the register value\n"); + } + + return 0; +} + +static ssize_t __mfc_reg_info_write(struct file *file, const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct mfc_dev *dev = g_mfc_dev; + ssize_t len; + unsigned int index = 0; + char temp_char; + + if (!dev->reg_buf) { + dev->reg_buf = kzalloc(SZ_1M, GFP_KERNEL); + mfc_info_dev("[REGTEST] alloc reg_buf\n"); + } + + if (!dev->reg_val) { + dev->reg_val = kzalloc(SZ_1M, GFP_KERNEL); + mfc_info_dev("[REGTEST] alloc reg_val\n"); + } + + len = simple_write_to_buffer(dev->reg_buf, SZ_1M - 1, + ppos, user_buf, count); + if (len <= 0) + return len; + + mfc_info_dev("[REGTEST] len: %d, ppos: %llu\n", len, *ppos); + + dev->reg_buf[*ppos] = '\0'; + + dev->reg_cnt = 0; + while (index + 7 < *ppos) { + temp_char = dev->reg_buf[index]; + if ((temp_char >= '0' && temp_char <= '9') || + (temp_char >= 'A' && temp_char <= 'F') || + (temp_char >= 'a' && temp_char <= 'f')) { + sscanf(&dev->reg_buf[index], "%08x", &dev->reg_val[dev->reg_cnt]); + index += 8; + dev->reg_cnt++; + } else { + index++; + } + } + + return len; +} +#endif + static int __mfc_info_open(struct inode *inode, struct file *file) { return single_open(file, __mfc_info_show, inode->i_private); @@ -133,6 +204,13 @@ static int __mfc_debug_info_open(struct inode *inode, struct file *file) return single_open(file, __mfc_debug_info_show, inode->i_private); } +#ifdef CONFIG_MFC_REG_TEST +static int __mfc_reg_info_open(struct inode *inode, struct file *file) +{ + return single_open(file, __mfc_reg_info_show, inode->i_private); +} +#endif + static const struct file_operations mfc_info_fops = { .open = __mfc_info_open, .read = seq_read, @@ -147,13 +225,23 @@ static const struct file_operations debug_info_fops = { .release = single_release, }; +#ifdef CONFIG_MFC_REG_TEST +static const struct file_operations reg_info_fops = { + .open = __mfc_reg_info_open, + .read = seq_read, + .write = __mfc_reg_info_write, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + void mfc_init_debugfs(struct mfc_dev *dev) { struct mfc_debugfs *debugfs = &dev->debugfs; debugfs->root = debugfs_create_dir("mfc", NULL); if (!debugfs->root) { - mfc_err_dev("debugfs: failed to create root derectory\n"); + mfc_err_dev("debugfs: failed to create root directory\n"); return; } @@ -161,6 +249,12 @@ void mfc_init_debugfs(struct mfc_dev *dev) 0444, debugfs->root, dev, &mfc_info_fops); debugfs->debug_info = debugfs_create_file("debug_info", 0444, debugfs->root, dev, &debug_info_fops); +#ifdef CONFIG_MFC_REG_TEST + debugfs->reg_info = debugfs_create_file("reg_info", + 0644, debugfs->root, dev, ®_info_fops); + debugfs->reg_test = debugfs_create_u32("reg_test", + 0644, debugfs->root, ®_test); +#endif debugfs->debug_level = debugfs_create_u32("debug", 0644, debugfs->root, &debug_level); debugfs->debug_ts = debugfs_create_u32("debug_ts", diff --git a/drivers/media/platform/exynos/mfc/mfc_debugfs.h b/drivers/media/platform/exynos/mfc/mfc_debugfs.h index 97f2ba086d15..1ffb1f21a39f 100644 --- a/drivers/media/platform/exynos/mfc/mfc_debugfs.h +++ b/drivers/media/platform/exynos/mfc/mfc_debugfs.h @@ -15,6 +15,8 @@ #include "mfc_common.h" +extern struct mfc_dev *g_mfc_dev; + void mfc_init_debugfs(struct mfc_dev *dev); #endif /* __MFC_DEBUGFS_H */ diff --git a/drivers/media/platform/exynos/mfc/mfc_enc_param.c b/drivers/media/platform/exynos/mfc/mfc_enc_param.c index c72b3de1c965..ddf79f4e8f26 100644 --- a/drivers/media/platform/exynos/mfc/mfc_enc_param.c +++ b/drivers/media/platform/exynos/mfc/mfc_enc_param.c @@ -372,7 +372,7 @@ static void __mfc_set_fmo_slice_map_h264(struct mfc_ctx *ctx, struct mfc_h264_en } } -void mfc_set_enc_params_h264(struct mfc_ctx *ctx) +static void __mfc_set_enc_params_h264(struct mfc_ctx *ctx) { struct mfc_dev *dev = ctx->dev; struct mfc_enc *enc = ctx->enc_priv; @@ -584,7 +584,7 @@ void mfc_set_enc_params_h264(struct mfc_ctx *ctx) mfc_debug_leave(); } -void mfc_set_enc_params_mpeg4(struct mfc_ctx *ctx) +static void __mfc_set_enc_params_mpeg4(struct mfc_ctx *ctx) { struct mfc_dev *dev = ctx->dev; struct mfc_enc *enc = ctx->enc_priv; @@ -658,7 +658,7 @@ void mfc_set_enc_params_mpeg4(struct mfc_ctx *ctx) mfc_debug_leave(); } -void mfc_set_enc_params_h263(struct mfc_ctx *ctx) +static void __mfc_set_enc_params_h263(struct mfc_ctx *ctx) { struct mfc_dev *dev = ctx->dev; struct mfc_enc *enc = ctx->enc_priv; @@ -715,7 +715,7 @@ void mfc_set_enc_params_h263(struct mfc_ctx *ctx) mfc_debug_leave(); } -void mfc_set_enc_params_vp8(struct mfc_ctx *ctx) +static void __mfc_set_enc_params_vp8(struct mfc_ctx *ctx) { struct mfc_dev *dev = ctx->dev; struct mfc_enc *enc = ctx->enc_priv; @@ -829,7 +829,7 @@ void mfc_set_enc_params_vp8(struct mfc_ctx *ctx) mfc_debug_leave(); } -void mfc_set_enc_params_vp9(struct mfc_ctx *ctx) +static void __mfc_set_enc_params_vp9(struct mfc_ctx *ctx) { struct mfc_dev *dev = ctx->dev; struct mfc_enc *enc = ctx->enc_priv; @@ -969,7 +969,7 @@ void mfc_set_enc_params_vp9(struct mfc_ctx *ctx) mfc_debug_leave(); } -void mfc_set_enc_params_hevc(struct mfc_ctx *ctx) +static void __mfc_set_enc_params_hevc(struct mfc_ctx *ctx) { struct mfc_dev *dev = ctx->dev; struct mfc_enc *enc = ctx->enc_priv; @@ -1221,7 +1221,7 @@ void mfc_set_enc_params_hevc(struct mfc_ctx *ctx) mfc_debug_leave(); } -void mfc_set_enc_params_bpg(struct mfc_ctx *ctx) +static void __mfc_set_enc_params_bpg(struct mfc_ctx *ctx) { struct mfc_dev *dev = ctx->dev; struct mfc_enc *enc = ctx->enc_priv; @@ -1255,19 +1255,19 @@ int mfc_set_enc_params(struct mfc_ctx *ctx) struct mfc_dev *dev = ctx->dev; if (IS_H264_ENC(ctx)) - mfc_set_enc_params_h264(ctx); + __mfc_set_enc_params_h264(ctx); else if (IS_MPEG4_ENC(ctx)) - mfc_set_enc_params_mpeg4(ctx); + __mfc_set_enc_params_mpeg4(ctx); else if (IS_H263_ENC(ctx)) - mfc_set_enc_params_h263(ctx); + __mfc_set_enc_params_h263(ctx); else if (IS_VP8_ENC(ctx)) - mfc_set_enc_params_vp8(ctx); + __mfc_set_enc_params_vp8(ctx); else if (IS_VP9_ENC(ctx)) - mfc_set_enc_params_vp9(ctx); + __mfc_set_enc_params_vp9(ctx); else if (IS_HEVC_ENC(ctx)) - mfc_set_enc_params_hevc(ctx); + __mfc_set_enc_params_hevc(ctx); else if (IS_BPG_ENC(ctx)) - mfc_set_enc_params_bpg(ctx); + __mfc_set_enc_params_bpg(ctx); else { mfc_err_ctx("Unknown codec for encoding (%x)\n", ctx->codec_mode); @@ -1282,3 +1282,26 @@ int mfc_set_enc_params(struct mfc_ctx *ctx) return 0; } + +void mfc_set_test_params(struct mfc_dev *dev) +{ + + unsigned int base_addr = 0xF000; + unsigned int i; + + if (!dev->reg_val) { + mfc_err_dev("[REGTEST] There is no reg_val set the register value\n"); + return; + } + + mfc_info_dev("[REGTEST] Overwrite register value for encoder register test\n"); + + for (i = 0; i < dev->reg_cnt; i++) + if (((base_addr + (i * 4)) != MFC_REG_E_STREAM_BUFFER_ADDR) && + ((base_addr + (i * 4)) != MFC_REG_E_SOURCE_FIRST_STRIDE) && + ((base_addr + (i * 4)) != MFC_REG_E_SOURCE_SECOND_STRIDE) && + ((base_addr + (i * 4)) != MFC_REG_E_SOURCE_THIRD_STRIDE) && + ((base_addr + (i * 4)) != MFC_REG_PIXEL_FORMAT)) + MFC_RAW_WRITEL(dev->reg_val[i], base_addr + (i * 4)); + +} diff --git a/drivers/media/platform/exynos/mfc/mfc_enc_param.h b/drivers/media/platform/exynos/mfc/mfc_enc_param.h index 383c3a198c39..8c75491519d3 100644 --- a/drivers/media/platform/exynos/mfc/mfc_enc_param.h +++ b/drivers/media/platform/exynos/mfc/mfc_enc_param.h @@ -18,5 +18,6 @@ void mfc_set_slice_mode(struct mfc_ctx *ctx); void mfc_set_aso_slice_order_h264(struct mfc_ctx *ctx); int mfc_set_enc_params(struct mfc_ctx *ctx); +void mfc_set_test_params(struct mfc_dev *dev); #endif /* __MFC_ENC_PARAM_H */ diff --git a/drivers/media/platform/exynos/mfc/mfc_otf.c b/drivers/media/platform/exynos/mfc/mfc_otf.c index e0d232637422..5b6f9137af02 100644 --- a/drivers/media/platform/exynos/mfc/mfc_otf.c +++ b/drivers/media/platform/exynos/mfc/mfc_otf.c @@ -387,14 +387,46 @@ int mfc_otf_ctx_ready(struct mfc_ctx *ctx) return 0; } +static int __check_disable_header_gen(struct mfc_dev *dev) +{ + unsigned int base_addr = 0xF000; + unsigned int shift = 6; + unsigned int mask = 1; + + if (!dev->reg_val) + return 0; + + if ((dev->reg_val[MFC_REG_E_ENC_OPTIONS - base_addr] >> shift) & mask) + return 1; + + return 0; +} + int mfc_otf_run_enc_init(struct mfc_ctx *ctx) { + struct mfc_dev *dev = ctx->dev; + struct mfc_raw_info *raw = &ctx->raw_buf; +#ifdef CONFIG_VIDEO_EXYNOS_TSMUX + struct packetizing_param packet_param; +#endif + int ret; mfc_debug_enter(); mfc_set_enc_stride(ctx); mfc_clean_ctx_int_flags(ctx); + + if (reg_test && !__check_disable_header_gen(dev)) { +#ifdef CONFIG_VIDEO_EXYNOS_TSMUX + packet_param.time_stamp = 0; + ret = packetize(&packet_param); + if (ret) + return ret; +#endif + mfc_otf_set_stream_size(ctx, raw->total_plane_size); + } + ret = mfc_cmd_enc_seq_header(ctx); mfc_debug_leave(); diff --git a/drivers/media/platform/exynos/mfc/mfc_run.c b/drivers/media/platform/exynos/mfc/mfc_run.c index 2301dc5a7af3..f38c33d0d20c 100644 --- a/drivers/media/platform/exynos/mfc/mfc_run.c +++ b/drivers/media/platform/exynos/mfc/mfc_run.c @@ -570,7 +570,9 @@ int mfc_run_enc_frame(struct mfc_ctx *ctx) if (IS_H264_ENC(ctx)) mfc_set_aso_slice_order_h264(ctx); - mfc_set_slice_mode(ctx); + + if (!reg_test) + mfc_set_slice_mode(ctx); mfc_cmd_enc_one_frame(ctx, last_frame);