• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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