1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2020 Rockchip Electronics Co., Ltd.
4 * Author: Cerf Yu <cerf.yu@rock-chips.com>
5 */
6
7 #include <linux/slab.h>
8 #include <linux/delay.h>
9 #include <linux/syscalls.h>
10 #include <linux/debugfs.h>
11 #include <linux/proc_fs.h>
12 #include <linux/seq_file.h>
13
14 #include "rga2.h"
15 #include "RGA2_API.h"
16 #include "rga2_mmu_info.h"
17 #include "rga2_debugger.h"
18
19 #define RGA_DEBUGGER_ROOT_NAME "rkrga"
20
21 #define STR_ENABLE(en) ((en) ? "EN" : "DIS")
22
23 void rga2_slt(void);
24
25 int RGA2_TEST_REG;
26 int RGA2_TEST_MSG;
27 int RGA2_TEST_TIME;
28 int RGA2_CHECK_MODE;
29 int RGA2_NONUSE;
30 int RGA2_INT_FLAG;
31
rga_debug_show(struct seq_file * m,void * data)32 static int rga_debug_show(struct seq_file *m, void *data)
33 {
34 seq_printf(m,
35 "REG [%s]\n"
36 "MSG [%s]\n"
37 "TIME [%s]\n"
38 "INT [%s]\n"
39 "CHECK [%s]\n"
40 "STOP [%s]\n",
41 STR_ENABLE(RGA2_TEST_REG), STR_ENABLE(RGA2_TEST_MSG), STR_ENABLE(RGA2_TEST_TIME),
42 STR_ENABLE(RGA2_CHECK_MODE), STR_ENABLE(RGA2_NONUSE), STR_ENABLE(RGA2_INT_FLAG));
43
44 seq_puts(m, "\nhelp:\n");
45 seq_puts(m, " 'echo reg > debug' to enable/disable register log printing.\n");
46 seq_puts(m, " 'echo msg > debug' to enable/disable message log printing.\n");
47 seq_puts(m, " 'echo time > debug' to enable/disable time log printing.\n");
48 seq_puts(m, " 'echo int > debug' to enable/disable interruppt log printing.\n");
49 seq_puts(m, " 'echo check > debug' to enable/disable check mode.\n");
50 seq_puts(m, " 'echo stop > debug' to enable/disable stop using hardware\n");
51
52 return 0;
53 }
54
rga_debug_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)55 static ssize_t rga_debug_write(struct file *file, const char __user *ubuf, size_t len, loff_t *offp)
56 {
57 char buf[14];
58
59 if (len > sizeof(buf) - 1) {
60 return -EINVAL;
61 }
62 if (copy_from_user(buf, ubuf, len)) {
63 return -EFAULT;
64 }
65 buf[len - 1] = '\0';
66
67 if (strncmp(buf, "reg", 4) == 0) {
68 if (RGA2_TEST_REG) {
69 RGA2_TEST_REG = 0;
70 INFO("close rga2 reg!\n");
71 } else {
72 RGA2_TEST_REG = 1;
73 INFO("open rga2 reg!\n");
74 }
75 } else if (strncmp(buf, "msg", 3) == 0) {
76 if (RGA2_TEST_MSG) {
77 RGA2_TEST_MSG = 0;
78 INFO("close rga2 test MSG!\n");
79 } else {
80 RGA2_TEST_MSG = 1;
81 INFO("open rga2 test MSG!\n");
82 }
83 } else if (strncmp(buf, "time", 4) == 0) {
84 if (RGA2_TEST_TIME) {
85 RGA2_TEST_TIME = 0;
86 INFO("close rga2 test time!\n");
87 } else {
88 RGA2_TEST_TIME = 1;
89 INFO("open rga2 test time!\n");
90 }
91 } else if (strncmp(buf, "check", 5) == 0) {
92 if (RGA2_CHECK_MODE) {
93 RGA2_CHECK_MODE = 0;
94 INFO("close rga2 check flag!\n");
95 } else {
96 RGA2_CHECK_MODE = 1;
97 INFO("open rga2 check flag!\n");
98 }
99 } else if (strncmp(buf, "stop", 4) == 0) {
100 if (RGA2_NONUSE) {
101 RGA2_NONUSE = 0;
102 INFO("stop using rga hardware!\n");
103 } else {
104 RGA2_NONUSE = 1;
105 INFO("use rga hardware!\n");
106 }
107 } else if (strncmp(buf, "int", 3) == 0) {
108 if (RGA2_INT_FLAG) {
109 RGA2_INT_FLAG = 0;
110 INFO("close inturrupt MSG!\n");
111 } else {
112 RGA2_INT_FLAG = 1;
113 INFO("open inturrupt MSG!\n");
114 }
115 } else if (strncmp(buf, "slt", 3) == 0) {
116 rga2_slt();
117 }
118
119 return len;
120 }
121
rga_version_show(struct seq_file * m,void * data)122 static int rga_version_show(struct seq_file *m, void *data)
123 {
124 seq_printf(m, "%s: v%s\n", DRIVER_DESC, DRIVER_VERSION);
125
126 return 0;
127 }
128
129 struct rga_debugger_list rga_root_list[] = {
130 {"debug", rga_debug_show, rga_debug_write, NULL},
131 {"driver_version", rga_version_show, NULL, NULL},
132 };
133
rga_debugger_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)134 static ssize_t rga_debugger_write(struct file *file, const char __user *ubuf, size_t len, loff_t *offp)
135 {
136 struct seq_file *priv = file->private_data;
137 struct rga_debugger_node *node = priv->private;
138
139 if (node->info_ent->write) {
140 return node->info_ent->write(file, ubuf, len, offp);
141 } else {
142 return len;
143 }
144 }
145
146 #ifdef CONFIG_ROCKCHIP_RGA2_DEBUG_FS
rga_debugfs_open(struct inode * inode,struct file * file)147 static int rga_debugfs_open(struct inode *inode, struct file *file)
148 {
149 struct rga_debugger_node *node = inode->i_private;
150
151 return single_open(file, node->info_ent->show, node);
152 }
153
154 static const struct file_operations rga_debugfs_fops = {
155 .owner = THIS_MODULE,
156 .open = rga_debugfs_open,
157 .read = seq_read,
158 .llseek = seq_lseek,
159 .release = single_release,
160 .write = rga_debugger_write,
161 };
162
rga_debugfs_remove_files(struct rga_debugger * debugger)163 static int rga_debugfs_remove_files(struct rga_debugger *debugger)
164 {
165 struct rga_debugger_node *pos, *q;
166 struct list_head *entry_list;
167
168 mutex_lock(&debugger->debugfs_lock);
169
170 /* Delete debugfs entry list */
171 entry_list = &debugger->debugfs_entry_list;
172 list_for_each_entry_safe(pos, q, entry_list, list)
173 {
174 if (pos->dent == NULL) {
175 continue;
176 }
177 list_del(&pos->list);
178 kfree(pos);
179 pos = NULL;
180 }
181
182 /* Delete all debugfs node in this directory */
183 debugfs_remove_recursive(debugger->debugfs_dir);
184 debugger->debugfs_dir = NULL;
185
186 mutex_unlock(&debugger->debugfs_lock);
187
188 return 0;
189 }
190
rga_debugfs_create_files(const struct rga_debugger_list * files,int count,struct dentry * root,struct rga_debugger * debugger)191 static int rga_debugfs_create_files(const struct rga_debugger_list *files, int count, struct dentry *root,
192 struct rga_debugger *debugger)
193 {
194 int i;
195 struct dentry *ent;
196 struct rga_debugger_node *tmp;
197
198 for (i = 0; i < count; i++) {
199 tmp = kmalloc(sizeof(struct rga_debugger_node), GFP_KERNEL);
200 if (tmp == NULL) {
201 ERR("Cannot alloc rga_debugger_node for /sys/kernel/debug/%pd/%s\n", root, files[i].name);
202 goto MALLOC_FAIL;
203 }
204
205 tmp->info_ent = &files[i];
206 tmp->debugger = debugger;
207
208 ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO, root, tmp, &rga_debugfs_fops);
209 if (!ent) {
210 ERR("Cannot create /sys/kernel/debug/%pd/%s\n", root, files[i].name);
211 goto CREATE_FAIL;
212 }
213
214 tmp->dent = ent;
215
216 mutex_lock(&debugger->debugfs_lock);
217 list_add_tail(&tmp->list, &debugger->debugfs_entry_list);
218 mutex_unlock(&debugger->debugfs_lock);
219 }
220
221 return 0;
222
223 CREATE_FAIL:
224 kfree(tmp);
225 MALLOC_FAIL:
226 rga_debugfs_remove_files(debugger);
227
228 return -1;
229 }
230
rga2_debugfs_remove(void)231 int rga2_debugfs_remove(void)
232 {
233 struct rga_debugger *debugger;
234
235 debugger = rga2_drvdata->debugger;
236
237 rga_debugfs_remove_files(debugger);
238
239 return 0;
240 }
241
rga2_debugfs_init(void)242 int rga2_debugfs_init(void)
243 {
244 int ret;
245 struct rga_debugger *debugger;
246
247 debugger = rga2_drvdata->debugger;
248
249 debugger->debugfs_dir = debugfs_create_dir(RGA_DEBUGGER_ROOT_NAME, NULL);
250 if (IS_ERR_OR_NULL(debugger->debugfs_dir)) {
251 ERR("failed on mkdir /sys/kernel/debug/%s\n", RGA_DEBUGGER_ROOT_NAME);
252 debugger->debugfs_dir = NULL;
253 return -EIO;
254 }
255
256 ret = rga_debugfs_create_files(rga_root_list, ARRAY_SIZE(rga_root_list), debugger->debugfs_dir, debugger);
257 if (ret) {
258 ERR("Could not install rga_root_list debugfs\n");
259 goto CREATE_FAIL;
260 }
261
262 return 0;
263
264 CREATE_FAIL:
265 rga2_debugfs_remove();
266
267 return ret;
268 }
269 #endif /* #ifdef CONFIG_ROCKCHIP_RGA2_DEBUG_FS */
270
271 #ifdef CONFIG_ROCKCHIP_RGA2_PROC_FS
rga_procfs_open(struct inode * inode,struct file * file)272 static int rga_procfs_open(struct inode *inode, struct file *file)
273 {
274 struct rga_debugger_node *node = PDE_DATA(inode);
275
276 return single_open(file, node->info_ent->show, node);
277 }
278
279 static const struct file_operations rga_procfs_fops = {
280 .owner = THIS_MODULE,
281 .open = rga_procfs_open,
282 .read = seq_read,
283 .llseek = seq_lseek,
284 .release = single_release,
285 .write = rga_debugger_write,
286 };
287
rga_procfs_remove_files(struct rga_debugger * debugger)288 static int rga_procfs_remove_files(struct rga_debugger *debugger)
289 {
290 struct rga_debugger_node *pos, *q;
291 struct list_head *entry_list;
292
293 mutex_lock(&debugger->procfs_lock);
294
295 /* Delete procfs entry list */
296 entry_list = &debugger->procfs_entry_list;
297 list_for_each_entry_safe(pos, q, entry_list, list)
298 {
299 if (pos->pent == NULL) {
300 continue;
301 }
302 list_del(&pos->list);
303 kfree(pos);
304 pos = NULL;
305 }
306
307 /* Delete all procfs node in this directory */
308 proc_remove(debugger->procfs_dir);
309 debugger->procfs_dir = NULL;
310
311 mutex_unlock(&debugger->procfs_lock);
312
313 return 0;
314 }
315
rga_procfs_create_files(const struct rga_debugger_list * files,int count,struct proc_dir_entry * root,struct rga_debugger * debugger)316 static int rga_procfs_create_files(const struct rga_debugger_list *files, int count, struct proc_dir_entry *root,
317 struct rga_debugger *debugger)
318 {
319 int i;
320 struct proc_dir_entry *ent;
321 struct rga_debugger_node *tmp;
322
323 for (i = 0; i < count; i++) {
324 tmp = kmalloc(sizeof(struct rga_debugger_node), GFP_KERNEL);
325 if (tmp == NULL) {
326 ERR("Cannot alloc rga_debugger_node for /proc/%s/%s\n", RGA_DEBUGGER_ROOT_NAME, files[i].name);
327 goto MALLOC_FAIL;
328 }
329
330 tmp->info_ent = &files[i];
331 tmp->debugger = debugger;
332
333 ent = proc_create_data(files[i].name, S_IFREG | S_IRUGO, root, &rga_procfs_fops, tmp);
334 if (!ent) {
335 ERR("Cannot create /proc/%s/%s\n", RGA_DEBUGGER_ROOT_NAME, files[i].name);
336 goto CREATE_FAIL;
337 }
338
339 tmp->pent = ent;
340
341 mutex_lock(&debugger->procfs_lock);
342 list_add_tail(&tmp->list, &debugger->procfs_entry_list);
343 mutex_unlock(&debugger->procfs_lock);
344 }
345
346 return 0;
347
348 CREATE_FAIL:
349 kfree(tmp);
350 MALLOC_FAIL:
351 rga_procfs_remove_files(debugger);
352 return -1;
353 }
354
rga2_procfs_remove(void)355 int rga2_procfs_remove(void)
356 {
357 struct rga_debugger *debugger;
358
359 debugger = rga2_drvdata->debugger;
360
361 rga_procfs_remove_files(debugger);
362
363 return 0;
364 }
365
rga2_procfs_init(void)366 int rga2_procfs_init(void)
367 {
368 int ret;
369 struct rga_debugger *debugger;
370
371 debugger = rga2_drvdata->debugger;
372
373 debugger->procfs_dir = proc_mkdir(RGA_DEBUGGER_ROOT_NAME, NULL);
374 if (IS_ERR_OR_NULL(debugger->procfs_dir)) {
375 ERR("failed on mkdir /proc/%s\n", RGA_DEBUGGER_ROOT_NAME);
376 debugger->procfs_dir = NULL;
377 return -EIO;
378 }
379
380 ret = rga_procfs_create_files(rga_root_list, ARRAY_SIZE(rga_root_list), debugger->procfs_dir, debugger);
381 if (ret) {
382 ERR("Could not install rga_root_list procfs\n");
383 goto CREATE_FAIL;
384 }
385
386 return 0;
387
388 CREATE_FAIL:
389 rga2_procfs_remove();
390
391 return ret;
392 }
393 #endif /* #ifdef CONFIG_ROCKCHIP_RGA2_PROC_FS */
394