2ebf68d33d57ae35134738d2b60525656b21e78c
[platform/kernel/linux-starfive.git] / drivers / media / platform / mediatek / vcodec / mtk_vcodec_dbgfs.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2023 MediaTek Inc.
4  * Author: Yunfei Dong <yunfei.dong@mediatek.com>
5  */
6
7 #include <linux/debugfs.h>
8
9 #include "mtk_vcodec_dbgfs.h"
10 #include "mtk_vcodec_drv.h"
11 #include "mtk_vcodec_util.h"
12
13 static void mtk_vdec_dbgfs_get_format_type(struct mtk_vcodec_ctx *ctx, char *buf,
14                                            int *used, int total)
15 {
16         int curr_len;
17
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");
22                 break;
23         case V4L2_PIX_FMT_VP8_FRAME:
24                 curr_len = snprintf(buf + *used, total - *used,
25                                     "\toutput format: vp8 slice\n");
26                 break;
27         case V4L2_PIX_FMT_VP9_FRAME:
28                 curr_len = snprintf(buf + *used, total - *used,
29                                     "\toutput format: vp9 slice\n");
30                 break;
31         default:
32                 curr_len = snprintf(buf + *used, total - *used,
33                                     "\tunsupported output format: 0x%x\n",
34                                     ctx->current_codec);
35         }
36         *used += curr_len;
37
38         switch (ctx->capture_fourcc) {
39         case V4L2_PIX_FMT_MM21:
40                 curr_len = snprintf(buf + *used, total - *used,
41                                     "\tcapture format: MM21\n");
42                 break;
43         case V4L2_PIX_FMT_MT21C:
44                 curr_len = snprintf(buf + *used, total - *used,
45                                     "\tcapture format: MT21C\n");
46                 break;
47         default:
48                 curr_len = snprintf(buf + *used, total - *used,
49                                     "\tunsupported capture format: 0x%x\n",
50                                     ctx->capture_fourcc);
51         }
52         *used += curr_len;
53 }
54
55 static void mtk_vdec_dbgfs_get_help(char *buf, int *used, int total)
56 {
57         int curr_len;
58
59         curr_len = snprintf(buf + *used, total - *used,
60                             "help: (1: echo -'info' > vdec 2: cat vdec)\n");
61         *used += curr_len;
62
63         curr_len = snprintf(buf + *used, total - *used,
64                             "\t-picinfo: get resolution\n");
65         *used += curr_len;
66
67         curr_len = snprintf(buf + *used, total - *used,
68                             "\t-format: get output & capture queue format\n");
69         *used += curr_len;
70 }
71
72 static ssize_t mtk_vdec_dbgfs_write(struct file *filp, const char __user *ubuf,
73                                     size_t count, loff_t *ppos)
74 {
75         struct mtk_vcodec_dev *vcodec_dev = filp->private_data;
76         struct mtk_vcodec_dbgfs *dbgfs = &vcodec_dev->dbgfs;
77
78         mutex_lock(&dbgfs->dbgfs_lock);
79         dbgfs->buf_size = simple_write_to_buffer(dbgfs->dbgfs_buf, sizeof(dbgfs->dbgfs_buf),
80                                                  ppos, ubuf, count);
81         mutex_unlock(&dbgfs->dbgfs_lock);
82         if (dbgfs->buf_size > 0)
83                 return count;
84
85         return dbgfs->buf_size;
86 }
87
88 static ssize_t mtk_vdec_dbgfs_read(struct file *filp, char __user *ubuf,
89                                    size_t count, loff_t *ppos)
90 {
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);
99
100         if (!buf)
101                 return -ENOMEM;
102
103         if (strstr(dbgfs->dbgfs_buf, "-help") || dbgfs->buf_size == 1) {
104                 mtk_vdec_dbgfs_get_help(buf, &used_len, total_len);
105                 goto read_buffer;
106         }
107
108         if (strstr(dbgfs->dbgfs_buf, "-picinfo"))
109                 dbgfs_index[MTK_VDEC_DBGFS_PICINFO] = true;
110
111         if (strstr(dbgfs->dbgfs_buf, "-format"))
112                 dbgfs_index[MTK_VDEC_DBGFS_FORMAT] = true;
113
114         mutex_lock(&dbgfs->dbgfs_lock);
115         list_for_each_entry(dbgfs_inst, &dbgfs->dbgfs_head, node) {
116                 ctx = dbgfs_inst->vcodec_ctx;
117
118                 curr_len = snprintf(buf + used_len, total_len - used_len,
119                                     "inst[%d]:\n ", ctx->id);
120                 used_len += curr_len;
121
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;
128                 }
129
130                 if (dbgfs_index[MTK_VDEC_DBGFS_FORMAT])
131                         mtk_vdec_dbgfs_get_format_type(ctx, buf, &used_len, total_len);
132         }
133         mutex_unlock(&dbgfs->dbgfs_lock);
134 read_buffer:
135         ret = simple_read_from_buffer(ubuf, count, ppos, buf, used_len);
136         kfree(buf);
137         return ret;
138 }
139
140 static const struct file_operations vdec_fops = {
141         .open = simple_open,
142         .write = mtk_vdec_dbgfs_write,
143         .read = mtk_vdec_dbgfs_read,
144 };
145
146 void mtk_vcodec_dbgfs_create(struct mtk_vcodec_ctx *ctx)
147 {
148         struct mtk_vcodec_dbgfs_inst *dbgfs_inst;
149         struct mtk_vcodec_dev *vcodec_dev = ctx->dev;
150
151         dbgfs_inst = kzalloc(sizeof(*dbgfs_inst), GFP_KERNEL);
152         if (!dbgfs_inst)
153                 return;
154
155         list_add_tail(&dbgfs_inst->node, &vcodec_dev->dbgfs.dbgfs_head);
156
157         vcodec_dev->dbgfs.inst_count++;
158
159         dbgfs_inst->inst_id = ctx->id;
160         dbgfs_inst->vcodec_ctx = ctx;
161 }
162 EXPORT_SYMBOL_GPL(mtk_vcodec_dbgfs_create);
163
164 void mtk_vcodec_dbgfs_remove(struct mtk_vcodec_dev *vcodec_dev, int ctx_id)
165 {
166         struct mtk_vcodec_dbgfs_inst *dbgfs_inst;
167
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);
172                         kfree(dbgfs_inst);
173                         return;
174                 }
175         }
176 }
177 EXPORT_SYMBOL_GPL(mtk_vcodec_dbgfs_remove);
178
179 void mtk_vcodec_dbgfs_init(struct mtk_vcodec_dev *vcodec_dev, bool is_encode)
180 {
181         struct dentry *vcodec_root;
182
183         if (is_encode)
184                 vcodec_dev->dbgfs.vcodec_root = debugfs_create_dir("vcodec-enc", NULL);
185         else
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));
190
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);
194
195         vcodec_dev->dbgfs.inst_count = 0;
196         if (is_encode)
197                 return;
198
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);
202 }
203 EXPORT_SYMBOL_GPL(mtk_vcodec_dbgfs_init);
204
205 void mtk_vcodec_dbgfs_deinit(struct mtk_vcodec_dev *vcodec_dev)
206 {
207         debugfs_remove_recursive(vcodec_dev->dbgfs.vcodec_root);
208 }
209 EXPORT_SYMBOL_GPL(mtk_vcodec_dbgfs_deinit);
210
211 MODULE_LICENSE("GPL v2");
212 MODULE_DESCRIPTION("Mediatek video codec driver");