• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) Rockchip Electronics Co., Ltd.
4  *
5  * Author:
6  *	Cerf Yu <cerf.yu@rock-chips.com>
7  *	Huang Lee <Putin.li@rock-chips.com>
8  */
9 
10 #define pr_fmt(fmt) "rga_debugger: " fmt
11 
12 #include <linux/slab.h>
13 #include <linux/delay.h>
14 #include <linux/syscalls.h>
15 #include <linux/debugfs.h>
16 #include <linux/proc_fs.h>
17 #include <linux/seq_file.h>
18 
19 #include "rga.h"
20 #include "rga_debugger.h"
21 #include "rga_drv.h"
22 #include "rga_mm.h"
23 
24 #define RGA_DEBUGGER_ROOT_NAME "rkrga"
25 
26 #define STR_ENABLE(en) (en ? "EN" : "DIS")
27 
28 int RGA_DEBUG_REG;
29 int RGA_DEBUG_MSG;
30 int RGA_DEBUG_TIME;
31 int RGA_DEBUG_CHECK_MODE;
32 int RGA_DEBUG_NONUSE;
33 int RGA_DEBUG_INT_FLAG;
34 
rga_debug_show(struct seq_file * m,void * data)35 static int rga_debug_show(struct seq_file *m, void *data)
36 {
37 	seq_printf(m, "REG [%s]\n"
38 		 "MSG [%s]\n"
39 		 "TIME [%s]\n"
40 		 "INT [%s]\n"
41 		 "CHECK [%s]\n"
42 		 "STOP [%s]\n",
43 		 STR_ENABLE(RGA_DEBUG_REG),
44 		 STR_ENABLE(RGA_DEBUG_MSG),
45 		 STR_ENABLE(RGA_DEBUG_TIME),
46 		 STR_ENABLE(RGA_DEBUG_CHECK_MODE),
47 		 STR_ENABLE(RGA_DEBUG_NONUSE),
48 		 STR_ENABLE(RGA_DEBUG_INT_FLAG));
49 
50 	seq_puts(m, "\nhelp:\n");
51 	seq_puts(m,
52 		 " 'echo reg > debug' to enable/disable register log printing.\n");
53 	seq_puts(m,
54 		 " 'echo msg > debug' to enable/disable message log printing.\n");
55 	seq_puts(m,
56 		 " 'echo time > debug' to enable/disable time log printing.\n");
57 	seq_puts(m,
58 		 " 'echo int > debug' to enable/disable interruppt log printing.\n");
59 	seq_puts(m, " 'echo check > debug' to enable/disable check mode.\n");
60 	seq_puts(m,
61 		 " 'echo stop > debug' to enable/disable stop using hardware\n");
62 
63 	return 0;
64 }
65 
rga_debug_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)66 static ssize_t rga_debug_write(struct file *file, const char __user *ubuf,
67 				 size_t len, loff_t *offp)
68 {
69 	char buf[14];
70 
71 	if (len > sizeof(buf) - 1)
72 		return -EINVAL;
73 	if (copy_from_user(buf, ubuf, len))
74 		return -EFAULT;
75 	buf[len - 1] = '\0';
76 
77 	if (strncmp(buf, "reg", 4) == 0) {
78 		if (RGA_DEBUG_REG) {
79 			RGA_DEBUG_REG = 0;
80 			pr_info("close rga reg!\n");
81 		} else {
82 			RGA_DEBUG_REG = 1;
83 			pr_info("open rga reg!\n");
84 		}
85 	} else if (strncmp(buf, "msg", 3) == 0) {
86 		if (RGA_DEBUG_MSG) {
87 			RGA_DEBUG_MSG = 0;
88 			pr_info("close rga test MSG!\n");
89 		} else {
90 			RGA_DEBUG_MSG = 1;
91 			pr_info("open rga test MSG!\n");
92 		}
93 	} else if (strncmp(buf, "time", 4) == 0) {
94 		if (RGA_DEBUG_TIME) {
95 			RGA_DEBUG_TIME = 0;
96 			pr_info("close rga test time!\n");
97 		} else {
98 			RGA_DEBUG_TIME = 1;
99 			pr_info("open rga test time!\n");
100 		}
101 	} else if (strncmp(buf, "check", 5) == 0) {
102 		if (RGA_DEBUG_CHECK_MODE) {
103 			RGA_DEBUG_CHECK_MODE = 0;
104 			pr_info("close rga check flag!\n");
105 		} else {
106 			RGA_DEBUG_CHECK_MODE = 1;
107 			pr_info("open rga check flag!\n");
108 		}
109 	} else if (strncmp(buf, "stop", 4) == 0) {
110 		if (RGA_DEBUG_NONUSE) {
111 			RGA_DEBUG_NONUSE = 0;
112 			pr_info("using rga hardware!\n");
113 		} else {
114 			RGA_DEBUG_NONUSE = 1;
115 			pr_info("stop using rga hardware!\n");
116 		}
117 	} else if (strncmp(buf, "int", 3) == 0) {
118 		if (RGA_DEBUG_INT_FLAG) {
119 			RGA_DEBUG_INT_FLAG = 0;
120 			pr_info("close inturrupt MSG!\n");
121 		} else {
122 			RGA_DEBUG_INT_FLAG = 1;
123 			pr_info("open inturrupt MSG!\n");
124 		}
125 	} else if (strncmp(buf, "slt", 3) == 0) {
126 		pr_err("Null");
127 	}
128 
129 	return len;
130 }
131 
rga_version_show(struct seq_file * m,void * data)132 static int rga_version_show(struct seq_file *m, void *data)
133 {
134 	seq_printf(m, "%s: v%s\n", DRIVER_DESC, DRIVER_VERSION);
135 
136 	return 0;
137 }
138 
rga_load_show(struct seq_file * m,void * data)139 static int rga_load_show(struct seq_file *m, void *data)
140 {
141 	struct rga_scheduler_t *rga_scheduler = NULL;
142 	unsigned long flags;
143 	int i;
144 	int load;
145 	u32 busy_time_total;
146 
147 	seq_printf(m, "num of scheduler = %d\n", rga_drvdata->num_of_scheduler);
148 	seq_printf(m, "================= load ==================\n");
149 
150 	for (i = 0; i < rga_drvdata->num_of_scheduler; i++) {
151 		rga_scheduler = rga_drvdata->rga_scheduler[i];
152 
153 		seq_printf(m, "scheduler[%d]: %s\n",
154 			i, dev_driver_string(rga_scheduler->dev));
155 
156 		spin_lock_irqsave(&rga_scheduler->irq_lock, flags);
157 
158 		busy_time_total = rga_scheduler->timer.busy_time_record;
159 
160 		spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags);
161 
162 		load = (busy_time_total * 100000 / RGA_LOAD_INTERVAL);
163 		seq_printf(m, "load = %d", load);
164 		seq_printf(m, "-----------------------------------\n");
165 	}
166 	return 0;
167 }
168 
rga_scheduler_show(struct seq_file * m,void * data)169 static int rga_scheduler_show(struct seq_file *m, void *data)
170 {
171 	struct rga_scheduler_t *rga_scheduler = NULL;
172 	int i;
173 
174 	seq_printf(m, "num of scheduler = %d\n", rga_drvdata->num_of_scheduler);
175 	seq_printf(m, "===================================\n");
176 
177 	for (i = 0; i < rga_drvdata->num_of_scheduler; i++) {
178 		rga_scheduler = rga_drvdata->rga_scheduler[i];
179 
180 		seq_printf(m, "scheduler[%d]: %s\n",
181 			i, dev_driver_string(rga_scheduler->dev));
182 		seq_printf(m, "-----------------------------------\n");
183 		seq_printf(m, "pd_ref = %d\n", rga_scheduler->pd_refcount);
184 	}
185 
186 	return 0;
187 }
188 
rga_mm_session_show(struct seq_file * m,void * data)189 static int rga_mm_session_show(struct seq_file *m, void *data)
190 {
191 	int id, i;
192 	struct rga_mm *mm_session = NULL;
193 	struct rga_internal_buffer *dump_buffer;
194 
195 	mm_session = rga_drvdata->mm;
196 
197 	mutex_lock(&mm_session->lock);
198 
199 	seq_puts(m, "rga_mm dump:\n");
200 	seq_printf(m, "buffer count = %d\n", mm_session->buffer_count);
201 	seq_puts(m, "===============================================================\n");
202 
203 	idr_for_each_entry(&mm_session->memory_idr, dump_buffer, id) {
204 		seq_printf(m, "handle = %d	refcount = %d	mm_flag = 0x%x\n",
205 			   dump_buffer->handle, kref_read(&dump_buffer->refcount),
206 			   dump_buffer->mm_flag);
207 
208 		switch (dump_buffer->type) {
209 		case RGA_DMA_BUFFER:
210 			seq_puts(m, "dma_buffer:\n");
211 			for (i = 0; i < dump_buffer->dma_buffer_size; i++) {
212 				seq_printf(m, "\t core %d:\n", dump_buffer->dma_buffer[i].core);
213 				seq_printf(m, "\t\t dma_buf = %p, iova = 0x%lx\n",
214 					   dump_buffer->dma_buffer[i].dma_buf,
215 					   (unsigned long)dump_buffer->dma_buffer[i].iova);
216 			}
217 			break;
218 		case RGA_VIRTUAL_ADDRESS:
219 			seq_puts(m, "virtual address:\n");
220 			seq_printf(m, "\t va = 0x%lx, pages = %p, size = %ld\n",
221 				   (unsigned long)dump_buffer->virt_addr->addr,
222 				   dump_buffer->virt_addr->pages,
223 				   dump_buffer->virt_addr->size);
224 
225 			for (i = 0; i < dump_buffer->dma_buffer_size; i++) {
226 				seq_printf(m, "\t core %d:\n", dump_buffer->dma_buffer[i].core);
227 				seq_printf(m, "\t\t iova = 0x%lx, sgt = %p, size = %ld\n",
228 					   (unsigned long)dump_buffer->dma_buffer[i].iova,
229 					   dump_buffer->dma_buffer[i].sgt,
230 					   dump_buffer->dma_buffer[i].size);
231 			}
232 			break;
233 		case RGA_PHYSICAL_ADDRESS:
234 			seq_puts(m, "physical address:\n");
235 			seq_printf(m, "\t pa = 0x%lx\n", (unsigned long)dump_buffer->phys_addr);
236 			break;
237 		default:
238 			seq_puts(m, "Illegal external buffer!\n");
239 			break;
240 		}
241 
242 		seq_puts(m, "---------------------------------------------------------------\n");
243 	}
244 	mutex_unlock(&mm_session->lock);
245 
246 	return 0;
247 }
248 
249 struct rga_debugger_list rga_debugger_root_list[] = {
250 	{"debug", rga_debug_show, rga_debug_write, NULL},
251 	{"driver_version", rga_version_show, NULL, NULL},
252 	{"load", rga_load_show, NULL, NULL},
253 	{"scheduler_status", rga_scheduler_show, NULL, NULL},
254 	{"mm_session", rga_mm_session_show, NULL, NULL},
255 };
256 
rga_debugger_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)257 static ssize_t rga_debugger_write(struct file *file, const char __user *ubuf,
258 				 size_t len, loff_t *offp)
259 {
260 	struct seq_file *priv = file->private_data;
261 	struct rga_debugger_node *node = priv->private;
262 
263 	if (node->info_ent->write)
264 		return node->info_ent->write(file, ubuf, len, offp);
265 	else
266 		return len;
267 }
268 
269 #ifdef CONFIG_ROCKCHIP_RGA_DEBUG_FS
rga_debugfs_open(struct inode * inode,struct file * file)270 static int rga_debugfs_open(struct inode *inode, struct file *file)
271 {
272 	struct rga_debugger_node *node = inode->i_private;
273 
274 	return single_open(file, node->info_ent->show, node);
275 }
276 
277 static const struct file_operations rga_debugfs_fops = {
278 	.owner = THIS_MODULE,
279 	.open = rga_debugfs_open,
280 	.read = seq_read,
281 	.llseek = seq_lseek,
282 	.release = single_release,
283 	.write = rga_debugger_write,
284 };
285 
rga_debugfs_remove_files(struct rga_debugger * debugger)286 static int rga_debugfs_remove_files(struct rga_debugger *debugger)
287 {
288 	struct rga_debugger_node *pos, *q;
289 	struct list_head *entry_list;
290 
291 	mutex_lock(&debugger->debugfs_lock);
292 
293 	/* Delete debugfs entry list */
294 	entry_list = &debugger->debugfs_entry_list;
295 	list_for_each_entry_safe(pos, q, entry_list, list) {
296 		if (pos->dent == NULL)
297 			continue;
298 		list_del(&pos->list);
299 		kfree(pos);
300 		pos = NULL;
301 	}
302 
303 	/* Delete all debugfs node in this directory */
304 	debugfs_remove_recursive(debugger->debugfs_dir);
305 	debugger->debugfs_dir = NULL;
306 
307 	mutex_unlock(&debugger->debugfs_lock);
308 
309 	return 0;
310 }
311 
rga_debugfs_create_files(const struct rga_debugger_list * files,int count,struct dentry * root,struct rga_debugger * debugger)312 static int rga_debugfs_create_files(const struct rga_debugger_list *files,
313 					int count, struct dentry *root,
314 					struct rga_debugger *debugger)
315 {
316 	int i;
317 	struct dentry *ent;
318 	struct rga_debugger_node *tmp;
319 
320 	for (i = 0; i < count; i++) {
321 		tmp = kmalloc(sizeof(struct rga_debugger_node), GFP_KERNEL);
322 		if (tmp == NULL) {
323 			pr_err("Cannot alloc node path /sys/kernel/debug/%pd/%s\n",
324 				 root, files[i].name);
325 			goto MALLOC_FAIL;
326 		}
327 
328 		tmp->info_ent = &files[i];
329 		tmp->debugger = debugger;
330 
331 		ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO,
332 					 root, tmp, &rga_debugfs_fops);
333 		if (!ent) {
334 			pr_err("Cannot create /sys/kernel/debug/%pd/%s\n", root,
335 				 files[i].name);
336 			goto CREATE_FAIL;
337 		}
338 
339 		tmp->dent = ent;
340 
341 		mutex_lock(&debugger->debugfs_lock);
342 		list_add_tail(&tmp->list, &debugger->debugfs_entry_list);
343 		mutex_unlock(&debugger->debugfs_lock);
344 	}
345 
346 	return 0;
347 
348 CREATE_FAIL:
349 	kfree(tmp);
350 MALLOC_FAIL:
351 	rga_debugfs_remove_files(debugger);
352 
353 	return -1;
354 }
355 
rga_debugfs_remove(void)356 int rga_debugfs_remove(void)
357 {
358 	struct rga_debugger *debugger;
359 
360 	debugger = rga_drvdata->debugger;
361 
362 	rga_debugfs_remove_files(debugger);
363 
364 	return 0;
365 }
366 
rga_debugfs_init(void)367 int rga_debugfs_init(void)
368 {
369 	int ret;
370 	struct rga_debugger *debugger;
371 
372 	debugger = rga_drvdata->debugger;
373 
374 	debugger->debugfs_dir =
375 		debugfs_create_dir(RGA_DEBUGGER_ROOT_NAME, NULL);
376 	if (IS_ERR_OR_NULL(debugger->debugfs_dir)) {
377 		pr_err("failed on mkdir /sys/kernel/debug/%s\n",
378 			 RGA_DEBUGGER_ROOT_NAME);
379 		debugger->debugfs_dir = NULL;
380 		return -EIO;
381 	}
382 
383 	ret = rga_debugfs_create_files(rga_debugger_root_list, ARRAY_SIZE(rga_debugger_root_list),
384 					 debugger->debugfs_dir, debugger);
385 	if (ret) {
386 		pr_err("Could not install rga_debugger_root_list debugfs\n");
387 		goto CREATE_FAIL;
388 	}
389 
390 	return 0;
391 
392 CREATE_FAIL:
393 	rga_debugfs_remove();
394 
395 	return ret;
396 }
397 #endif /* #ifdef CONFIG_ROCKCHIP_RGA_DEBUG_FS */
398 
399 #ifdef CONFIG_ROCKCHIP_RGA2_PROC_FS
rga_procfs_open(struct inode * inode,struct file * file)400 static int rga_procfs_open(struct inode *inode, struct file *file)
401 {
402 	struct rga_debugger_node *node = PDE_DATA(inode);
403 
404 	return single_open(file, node->info_ent->show, node);
405 }
406 
407 static const struct file_operations rga_procfs_fops = {
408 	.owner = THIS_MODULE,
409 	.open = rga_procfs_open,
410 	.read = seq_read,
411 	.llseek = seq_lseek,
412 	.release = single_release,
413 	.write = rga_debugger_write,
414 };
415 
rga_procfs_remove_files(struct rga_debugger * debugger)416 static int rga_procfs_remove_files(struct rga_debugger *debugger)
417 {
418 	struct rga_debugger_node *pos, *q;
419 	struct list_head *entry_list;
420 
421 	mutex_lock(&debugger->procfs_lock);
422 
423 	/* Delete procfs entry list */
424 	entry_list = &debugger->procfs_entry_list;
425 	list_for_each_entry_safe(pos, q, entry_list, list) {
426 		if (pos->pent == NULL)
427 			continue;
428 		list_del(&pos->list);
429 		kfree(pos);
430 		pos = NULL;
431 	}
432 
433 	/* Delete all procfs node in this directory */
434 	proc_remove(debugger->procfs_dir);
435 	debugger->procfs_dir = NULL;
436 
437 	mutex_unlock(&debugger->procfs_lock);
438 
439 	return 0;
440 }
441 
rga_procfs_create_files(const struct rga_debugger_list * files,int count,struct proc_dir_entry * root,struct rga_debugger * debugger)442 static int rga_procfs_create_files(const struct rga_debugger_list *files,
443 				 int count, struct proc_dir_entry *root,
444 				 struct rga_debugger *debugger)
445 {
446 	int i;
447 	struct proc_dir_entry *ent;
448 	struct rga_debugger_node *tmp;
449 
450 	for (i = 0; i < count; i++) {
451 		tmp = kmalloc(sizeof(struct rga_debugger_node), GFP_KERNEL);
452 		if (tmp == NULL) {
453 			pr_err("Cannot alloc node path for /proc/%s/%s\n",
454 				 RGA_DEBUGGER_ROOT_NAME, files[i].name);
455 			goto MALLOC_FAIL;
456 		}
457 
458 		tmp->info_ent = &files[i];
459 		tmp->debugger = debugger;
460 
461 		ent = proc_create_data(files[i].name, S_IFREG | S_IRUGO,
462 					 root, &rga_procfs_fops, tmp);
463 		if (!ent) {
464 			pr_err("Cannot create /proc/%s/%s\n",
465 				 RGA_DEBUGGER_ROOT_NAME, files[i].name);
466 			goto CREATE_FAIL;
467 		}
468 
469 		tmp->pent = ent;
470 
471 		mutex_lock(&debugger->procfs_lock);
472 		list_add_tail(&tmp->list, &debugger->procfs_entry_list);
473 		mutex_unlock(&debugger->procfs_lock);
474 	}
475 
476 	return 0;
477 
478 CREATE_FAIL:
479 	kfree(tmp);
480 MALLOC_FAIL:
481 	rga_procfs_remove_files(debugger);
482 	return -1;
483 }
484 
rga_procfs_remove(void)485 int rga_procfs_remove(void)
486 {
487 	struct rga_debugger *debugger;
488 
489 	debugger = rga_drvdata->debugger;
490 
491 	rga_procfs_remove_files(debugger);
492 
493 	return 0;
494 }
495 
rga_procfs_init(void)496 int rga_procfs_init(void)
497 {
498 	int ret;
499 	struct rga_debugger *debugger;
500 
501 	debugger = rga_drvdata->debugger;
502 
503 	debugger->procfs_dir = proc_mkdir(RGA_DEBUGGER_ROOT_NAME, NULL);
504 	if (IS_ERR_OR_NULL(debugger->procfs_dir)) {
505 		pr_err("failed on mkdir /proc/%s\n", RGA_DEBUGGER_ROOT_NAME);
506 		debugger->procfs_dir = NULL;
507 		return -EIO;
508 	}
509 
510 	ret = rga_procfs_create_files(rga_debugger_root_list, ARRAY_SIZE(rga_debugger_root_list),
511 					 debugger->procfs_dir, debugger);
512 	if (ret) {
513 		pr_err("Could not install rga_debugger_root_list procfs\n");
514 		goto CREATE_FAIL;
515 	}
516 
517 	return 0;
518 
519 CREATE_FAIL:
520 	rga_procfs_remove();
521 
522 	return ret;
523 }
524 #endif /* #ifdef CONFIG_ROCKCHIP_RGA_PROC_FS */
525 
rga_cmd_print_debug_info(struct rga_req * req)526 void rga_cmd_print_debug_info(struct rga_req *req)
527 {
528 	pr_info("============= start ==============\n");
529 	pr_info("render_mode = %d, bitblit_mode=%d, rotate_mode = %d\n",
530 		req->render_mode, req->bsfilter_flag,
531 		req->rotate_mode);
532 
533 	pr_info("src: y = %lx uv = %lx v = %lx aw = %d ah = %d vw = %d vh = %d\n",
534 		 (unsigned long)req->src.yrgb_addr,
535 		 (unsigned long)req->src.uv_addr,
536 		 (unsigned long)req->src.v_addr,
537 		 req->src.act_w, req->src.act_h,
538 		 req->src.vir_w, req->src.vir_h);
539 	pr_info("src: xoff = %d, yoff = %d, format = 0x%x, rd_mode = %d\n",
540 		req->src.x_offset, req->src.y_offset,
541 		 req->src.format, req->src.rd_mode);
542 
543 	if (req->pat.yrgb_addr != 0 || req->pat.uv_addr != 0
544 		|| req->pat.v_addr != 0) {
545 		pr_info("pat: y=%lx uv=%lx v=%lx aw=%d ah=%d vw=%d vh=%d\n",
546 			 (unsigned long)req->pat.yrgb_addr,
547 			 (unsigned long)req->pat.uv_addr,
548 			 (unsigned long)req->pat.v_addr,
549 			 req->pat.act_w, req->pat.act_h,
550 			 req->pat.vir_w, req->pat.vir_h);
551 		pr_info("pat: xoff = %d yoff = %d, format = 0x%x, rd_mode = %d\n",
552 			req->pat.x_offset, req->pat.y_offset,
553 			req->pat.format, req->pat.rd_mode);
554 	}
555 
556 	pr_info("dst: y=%lx uv=%lx v=%lx aw=%d ah=%d vw=%d vh=%d\n",
557 		 (unsigned long)req->dst.yrgb_addr,
558 		 (unsigned long)req->dst.uv_addr,
559 		 (unsigned long)req->dst.v_addr,
560 		 req->dst.act_w, req->dst.act_h,
561 		 req->dst.vir_w, req->dst.vir_h);
562 	pr_info("dst: xoff = %d, yoff = %d, format = 0x%x, rd_mode = %d\n",
563 		req->dst.x_offset, req->dst.y_offset,
564 		req->dst.format, req->dst.rd_mode);
565 
566 	pr_info("mmu: mmu_flag=%x en=%x\n",
567 		req->mmu_info.mmu_flag, req->mmu_info.mmu_en);
568 	pr_info("alpha: rop_mode = %x\n", req->alpha_rop_mode);
569 	pr_info("yuv2rgb mode is %x\n", req->yuv2rgb_mode);
570 	pr_info("set core = %d, priority = %d, in_fence_fd = %d\n",
571 		req->core, req->priority, req->in_fence_fd);
572 }
573