1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2023 MediaTek Inc.
4 * Author: Yunfei Dong <yunfei.dong@mediatek.com>
7 #include <linux/debugfs.h>
9 #include "mtk_vcodec_dbgfs.h"
10 #include "mtk_vcodec_drv.h"
11 #include "mtk_vcodec_util.h"
13 static void mtk_vdec_dbgfs_get_format_type(struct mtk_vcodec_ctx *ctx, char *buf,
18 switch (ctx->current_codec) {
19 case V4L2_PIX_FMT_H264_SLICE:
20 curr_len = snprintf(buf + *used, total - *used,
21 "\toutput format: h264 slice\n");
23 case V4L2_PIX_FMT_VP8_FRAME:
24 curr_len = snprintf(buf + *used, total - *used,
25 "\toutput format: vp8 slice\n");
27 case V4L2_PIX_FMT_VP9_FRAME:
28 curr_len = snprintf(buf + *used, total - *used,
29 "\toutput format: vp9 slice\n");
32 curr_len = snprintf(buf + *used, total - *used,
33 "\tunsupported output format: 0x%x\n",
38 switch (ctx->capture_fourcc) {
39 case V4L2_PIX_FMT_MM21:
40 curr_len = snprintf(buf + *used, total - *used,
41 "\tcapture format: MM21\n");
43 case V4L2_PIX_FMT_MT21C:
44 curr_len = snprintf(buf + *used, total - *used,
45 "\tcapture format: MT21C\n");
48 curr_len = snprintf(buf + *used, total - *used,
49 "\tunsupported capture format: 0x%x\n",
55 static void mtk_vdec_dbgfs_get_help(char *buf, int *used, int total)
59 curr_len = snprintf(buf + *used, total - *used,
60 "help: (1: echo -'info' > vdec 2: cat vdec)\n");
63 curr_len = snprintf(buf + *used, total - *used,
64 "\t-picinfo: get resolution\n");
67 curr_len = snprintf(buf + *used, total - *used,
68 "\t-format: get output & capture queue format\n");
72 static ssize_t mtk_vdec_dbgfs_write(struct file *filp, const char __user *ubuf,
73 size_t count, loff_t *ppos)
75 struct mtk_vcodec_dev *vcodec_dev = filp->private_data;
76 struct mtk_vcodec_dbgfs *dbgfs = &vcodec_dev->dbgfs;
78 mutex_lock(&dbgfs->dbgfs_lock);
79 dbgfs->buf_size = simple_write_to_buffer(dbgfs->dbgfs_buf, sizeof(dbgfs->dbgfs_buf),
81 mutex_unlock(&dbgfs->dbgfs_lock);
82 if (dbgfs->buf_size > 0)
85 return dbgfs->buf_size;
88 static ssize_t mtk_vdec_dbgfs_read(struct file *filp, char __user *ubuf,
89 size_t count, loff_t *ppos)
91 struct mtk_vcodec_dev *vcodec_dev = filp->private_data;
92 struct mtk_vcodec_dbgfs *dbgfs = &vcodec_dev->dbgfs;
93 struct mtk_vcodec_dbgfs_inst *dbgfs_inst;
94 struct mtk_vcodec_ctx *ctx;
95 int total_len = 200 * (dbgfs->inst_count == 0 ? 1 : dbgfs->inst_count);
96 int used_len = 0, curr_len, ret;
97 bool dbgfs_index[MTK_VDEC_DBGFS_MAX] = {0};
98 char *buf = kmalloc(total_len, GFP_KERNEL);
103 if (strstr(dbgfs->dbgfs_buf, "-help") || dbgfs->buf_size == 1) {
104 mtk_vdec_dbgfs_get_help(buf, &used_len, total_len);
108 if (strstr(dbgfs->dbgfs_buf, "-picinfo"))
109 dbgfs_index[MTK_VDEC_DBGFS_PICINFO] = true;
111 if (strstr(dbgfs->dbgfs_buf, "-format"))
112 dbgfs_index[MTK_VDEC_DBGFS_FORMAT] = true;
114 mutex_lock(&dbgfs->dbgfs_lock);
115 list_for_each_entry(dbgfs_inst, &dbgfs->dbgfs_head, node) {
116 ctx = dbgfs_inst->vcodec_ctx;
118 curr_len = snprintf(buf + used_len, total_len - used_len,
119 "inst[%d]:\n ", ctx->id);
120 used_len += curr_len;
122 if (dbgfs_index[MTK_VDEC_DBGFS_PICINFO]) {
123 curr_len = snprintf(buf + used_len, total_len - used_len,
124 "\treal(%dx%d)=>align(%dx%d)\n",
125 ctx->picinfo.pic_w, ctx->picinfo.pic_h,
126 ctx->picinfo.buf_w, ctx->picinfo.buf_h);
127 used_len += curr_len;
130 if (dbgfs_index[MTK_VDEC_DBGFS_FORMAT])
131 mtk_vdec_dbgfs_get_format_type(ctx, buf, &used_len, total_len);
133 mutex_unlock(&dbgfs->dbgfs_lock);
135 ret = simple_read_from_buffer(ubuf, count, ppos, buf, used_len);
140 static const struct file_operations vdec_fops = {
142 .write = mtk_vdec_dbgfs_write,
143 .read = mtk_vdec_dbgfs_read,
146 void mtk_vcodec_dbgfs_create(struct mtk_vcodec_ctx *ctx)
148 struct mtk_vcodec_dbgfs_inst *dbgfs_inst;
149 struct mtk_vcodec_dev *vcodec_dev = ctx->dev;
151 dbgfs_inst = kzalloc(sizeof(*dbgfs_inst), GFP_KERNEL);
155 list_add_tail(&dbgfs_inst->node, &vcodec_dev->dbgfs.dbgfs_head);
157 vcodec_dev->dbgfs.inst_count++;
159 dbgfs_inst->inst_id = ctx->id;
160 dbgfs_inst->vcodec_ctx = ctx;
162 EXPORT_SYMBOL_GPL(mtk_vcodec_dbgfs_create);
164 void mtk_vcodec_dbgfs_remove(struct mtk_vcodec_dev *vcodec_dev, int ctx_id)
166 struct mtk_vcodec_dbgfs_inst *dbgfs_inst;
168 list_for_each_entry(dbgfs_inst, &vcodec_dev->dbgfs.dbgfs_head, node) {
169 if (dbgfs_inst->inst_id == ctx_id) {
170 vcodec_dev->dbgfs.inst_count--;
171 list_del(&dbgfs_inst->node);
177 EXPORT_SYMBOL_GPL(mtk_vcodec_dbgfs_remove);
179 void mtk_vcodec_dbgfs_init(struct mtk_vcodec_dev *vcodec_dev, bool is_encode)
181 struct dentry *vcodec_root;
184 vcodec_dev->dbgfs.vcodec_root = debugfs_create_dir("vcodec-enc", NULL);
186 vcodec_dev->dbgfs.vcodec_root = debugfs_create_dir("vcodec-dec", NULL);
187 if (IS_ERR(vcodec_dev->dbgfs.vcodec_root))
188 dev_err(&vcodec_dev->plat_dev->dev, "create vcodec dir err:%d\n",
189 IS_ERR(vcodec_dev->dbgfs.vcodec_root));
191 vcodec_root = vcodec_dev->dbgfs.vcodec_root;
192 debugfs_create_x32("mtk_v4l2_dbg_level", 0644, vcodec_root, &mtk_v4l2_dbg_level);
193 debugfs_create_x32("mtk_vcodec_dbg", 0644, vcodec_root, &mtk_vcodec_dbg);
195 vcodec_dev->dbgfs.inst_count = 0;
199 INIT_LIST_HEAD(&vcodec_dev->dbgfs.dbgfs_head);
200 debugfs_create_file("vdec", 0200, vcodec_root, vcodec_dev, &vdec_fops);
201 mutex_init(&vcodec_dev->dbgfs.dbgfs_lock);
203 EXPORT_SYMBOL_GPL(mtk_vcodec_dbgfs_init);
205 void mtk_vcodec_dbgfs_deinit(struct mtk_vcodec_dev *vcodec_dev)
207 debugfs_remove_recursive(vcodec_dev->dbgfs.vcodec_root);
209 EXPORT_SYMBOL_GPL(mtk_vcodec_dbgfs_deinit);
211 MODULE_LICENSE("GPL v2");
212 MODULE_DESCRIPTION("Mediatek video codec driver");