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