xref: /OK3568_Linux_fs/kernel/drivers/video/rockchip/rga3/rga_debugger.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) Rockchip Electronics Co., Ltd.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Author:
6*4882a593Smuzhiyun  *	Cerf Yu <cerf.yu@rock-chips.com>
7*4882a593Smuzhiyun  *	Huang Lee <Putin.li@rock-chips.com>
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #define pr_fmt(fmt) "rga_debugger: " fmt
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun #include <linux/delay.h>
14*4882a593Smuzhiyun #include <linux/syscalls.h>
15*4882a593Smuzhiyun #include <linux/debugfs.h>
16*4882a593Smuzhiyun #include <linux/proc_fs.h>
17*4882a593Smuzhiyun #include <linux/seq_file.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include "rga.h"
20*4882a593Smuzhiyun #include "rga_debugger.h"
21*4882a593Smuzhiyun #include "rga_drv.h"
22*4882a593Smuzhiyun #include "rga_mm.h"
23*4882a593Smuzhiyun #include "rga_common.h"
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #define RGA_DEBUGGER_ROOT_NAME "rkrga"
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #define STR_ENABLE(en) (en ? "EN" : "DIS")
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun int RGA_DEBUG_REG;
30*4882a593Smuzhiyun int RGA_DEBUG_MSG;
31*4882a593Smuzhiyun int RGA_DEBUG_TIME;
32*4882a593Smuzhiyun int RGA_DEBUG_INT_FLAG;
33*4882a593Smuzhiyun int RGA_DEBUG_MM;
34*4882a593Smuzhiyun int RGA_DEBUG_CHECK_MODE;
35*4882a593Smuzhiyun int RGA_DEBUG_NONUSE;
36*4882a593Smuzhiyun int RGA_DEBUG_DEBUG_MODE;
37*4882a593Smuzhiyun int RGA_DEBUG_DUMP_IMAGE;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #ifdef CONFIG_NO_GKI
40*4882a593Smuzhiyun static char g_dump_path[100] = "/data";
41*4882a593Smuzhiyun #endif
42*4882a593Smuzhiyun 
rga_debug_show(struct seq_file * m,void * data)43*4882a593Smuzhiyun static int rga_debug_show(struct seq_file *m, void *data)
44*4882a593Smuzhiyun {
45*4882a593Smuzhiyun 	seq_printf(m, "REG [%s]\n"
46*4882a593Smuzhiyun 		 "MSG [%s]\n"
47*4882a593Smuzhiyun 		 "TIME [%s]\n"
48*4882a593Smuzhiyun 		 "INT [%s]\n"
49*4882a593Smuzhiyun 		 "MM [%s]\n"
50*4882a593Smuzhiyun 		 "CHECK [%s]\n"
51*4882a593Smuzhiyun 		 "STOP [%s]\n",
52*4882a593Smuzhiyun 		 STR_ENABLE(RGA_DEBUG_REG),
53*4882a593Smuzhiyun 		 STR_ENABLE(RGA_DEBUG_MSG),
54*4882a593Smuzhiyun 		 STR_ENABLE(RGA_DEBUG_TIME),
55*4882a593Smuzhiyun 		 STR_ENABLE(RGA_DEBUG_INT_FLAG),
56*4882a593Smuzhiyun 		 STR_ENABLE(RGA_DEBUG_MM),
57*4882a593Smuzhiyun 		 STR_ENABLE(RGA_DEBUG_CHECK_MODE),
58*4882a593Smuzhiyun 		 STR_ENABLE(RGA_DEBUG_NONUSE));
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	seq_puts(m, "\nhelp:\n");
61*4882a593Smuzhiyun 	seq_puts(m, " 'echo reg > debug' to enable/disable register log printing.\n");
62*4882a593Smuzhiyun 	seq_puts(m, " 'echo msg > debug' to enable/disable message log printing.\n");
63*4882a593Smuzhiyun 	seq_puts(m, " 'echo time > debug' to enable/disable time log printing.\n");
64*4882a593Smuzhiyun 	seq_puts(m, " 'echo int > debug' to enable/disable interruppt log printing.\n");
65*4882a593Smuzhiyun 	seq_puts(m, " 'echo mm > debug' to enable/disable memory manager log printing.\n");
66*4882a593Smuzhiyun 	seq_puts(m, " 'echo check > debug' to enable/disable check mode.\n");
67*4882a593Smuzhiyun 	seq_puts(m, " 'echo stop > debug' to enable/disable stop using hardware\n");
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	return 0;
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun 
rga_debug_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)72*4882a593Smuzhiyun static ssize_t rga_debug_write(struct file *file, const char __user *ubuf,
73*4882a593Smuzhiyun 				 size_t len, loff_t *offp)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun 	char buf[14];
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 	if (len > sizeof(buf) - 1)
78*4882a593Smuzhiyun 		return -EINVAL;
79*4882a593Smuzhiyun 	if (copy_from_user(buf, ubuf, len))
80*4882a593Smuzhiyun 		return -EFAULT;
81*4882a593Smuzhiyun 	buf[len - 1] = '\0';
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	if (strncmp(buf, "reg", 4) == 0) {
84*4882a593Smuzhiyun 		if (RGA_DEBUG_REG) {
85*4882a593Smuzhiyun 			RGA_DEBUG_REG = 0;
86*4882a593Smuzhiyun 			pr_info("close rga reg!\n");
87*4882a593Smuzhiyun 		} else {
88*4882a593Smuzhiyun 			RGA_DEBUG_REG = 1;
89*4882a593Smuzhiyun 			pr_info("open rga reg!\n");
90*4882a593Smuzhiyun 		}
91*4882a593Smuzhiyun 	} else if (strncmp(buf, "msg", 3) == 0) {
92*4882a593Smuzhiyun 		if (RGA_DEBUG_MSG) {
93*4882a593Smuzhiyun 			RGA_DEBUG_MSG = 0;
94*4882a593Smuzhiyun 			pr_info("close rga test MSG!\n");
95*4882a593Smuzhiyun 		} else {
96*4882a593Smuzhiyun 			RGA_DEBUG_MSG = 1;
97*4882a593Smuzhiyun 			pr_info("open rga test MSG!\n");
98*4882a593Smuzhiyun 		}
99*4882a593Smuzhiyun 	} else if (strncmp(buf, "time", 4) == 0) {
100*4882a593Smuzhiyun 		if (RGA_DEBUG_TIME) {
101*4882a593Smuzhiyun 			RGA_DEBUG_TIME = 0;
102*4882a593Smuzhiyun 			pr_info("close rga test time!\n");
103*4882a593Smuzhiyun 		} else {
104*4882a593Smuzhiyun 			RGA_DEBUG_TIME = 1;
105*4882a593Smuzhiyun 			pr_info("open rga test time!\n");
106*4882a593Smuzhiyun 		}
107*4882a593Smuzhiyun 	} else if (strncmp(buf, "int", 3) == 0) {
108*4882a593Smuzhiyun 		if (RGA_DEBUG_INT_FLAG) {
109*4882a593Smuzhiyun 			RGA_DEBUG_INT_FLAG = 0;
110*4882a593Smuzhiyun 			pr_info("close inturrupt MSG!\n");
111*4882a593Smuzhiyun 		} else {
112*4882a593Smuzhiyun 			RGA_DEBUG_INT_FLAG = 1;
113*4882a593Smuzhiyun 			pr_info("open inturrupt MSG!\n");
114*4882a593Smuzhiyun 		}
115*4882a593Smuzhiyun 	} else if (strncmp(buf, "mm", 2) == 0) {
116*4882a593Smuzhiyun 		if (RGA_DEBUG_MM) {
117*4882a593Smuzhiyun 			RGA_DEBUG_MM = 0;
118*4882a593Smuzhiyun 			pr_info("close rga mm log!\n");
119*4882a593Smuzhiyun 		} else {
120*4882a593Smuzhiyun 			RGA_DEBUG_MM = 1;
121*4882a593Smuzhiyun 			pr_info("open rga mm log!\n");
122*4882a593Smuzhiyun 		}
123*4882a593Smuzhiyun 	} else if (strncmp(buf, "check", 5) == 0) {
124*4882a593Smuzhiyun 		if (RGA_DEBUG_CHECK_MODE) {
125*4882a593Smuzhiyun 			RGA_DEBUG_CHECK_MODE = 0;
126*4882a593Smuzhiyun 			pr_info("close rga check flag!\n");
127*4882a593Smuzhiyun 		} else {
128*4882a593Smuzhiyun 			RGA_DEBUG_CHECK_MODE = 1;
129*4882a593Smuzhiyun 			pr_info("open rga check flag!\n");
130*4882a593Smuzhiyun 		}
131*4882a593Smuzhiyun 	} else if (strncmp(buf, "stop", 4) == 0) {
132*4882a593Smuzhiyun 		if (RGA_DEBUG_NONUSE) {
133*4882a593Smuzhiyun 			RGA_DEBUG_NONUSE = 0;
134*4882a593Smuzhiyun 			pr_info("using rga hardware!\n");
135*4882a593Smuzhiyun 		} else {
136*4882a593Smuzhiyun 			RGA_DEBUG_NONUSE = 1;
137*4882a593Smuzhiyun 			pr_info("stop using rga hardware!\n");
138*4882a593Smuzhiyun 		}
139*4882a593Smuzhiyun 	} else if (strncmp(buf, "debug", 3) == 0) {
140*4882a593Smuzhiyun 		if (RGA_DEBUG_DEBUG_MODE) {
141*4882a593Smuzhiyun 			RGA_DEBUG_REG = 0;
142*4882a593Smuzhiyun 			RGA_DEBUG_MSG = 0;
143*4882a593Smuzhiyun 			RGA_DEBUG_TIME = 0;
144*4882a593Smuzhiyun 			RGA_DEBUG_INT_FLAG = 0;
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 			RGA_DEBUG_DEBUG_MODE = 0;
147*4882a593Smuzhiyun 			pr_info("close debug mode!\n");
148*4882a593Smuzhiyun 		} else {
149*4882a593Smuzhiyun 			RGA_DEBUG_REG = 1;
150*4882a593Smuzhiyun 			RGA_DEBUG_MSG = 1;
151*4882a593Smuzhiyun 			RGA_DEBUG_TIME = 1;
152*4882a593Smuzhiyun 			RGA_DEBUG_INT_FLAG = 1;
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 			RGA_DEBUG_DEBUG_MODE = 1;
155*4882a593Smuzhiyun 			pr_info("open debug mode!\n");
156*4882a593Smuzhiyun 		}
157*4882a593Smuzhiyun 	} else if (strncmp(buf, "slt", 3) == 0) {
158*4882a593Smuzhiyun 		pr_err("Null");
159*4882a593Smuzhiyun 	}
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	return len;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun 
rga_version_show(struct seq_file * m,void * data)164*4882a593Smuzhiyun static int rga_version_show(struct seq_file *m, void *data)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun 	seq_printf(m, "%s: v%s\n", DRIVER_DESC, DRIVER_VERSION);
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun 	return 0;
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun 
rga_load_show(struct seq_file * m,void * data)171*4882a593Smuzhiyun static int rga_load_show(struct seq_file *m, void *data)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun 	struct rga_scheduler_t *scheduler = NULL;
174*4882a593Smuzhiyun 	struct rga_session_manager *session_manager = NULL;
175*4882a593Smuzhiyun 	struct rga_session *session = NULL;
176*4882a593Smuzhiyun 	unsigned long flags;
177*4882a593Smuzhiyun 	int id = 0;
178*4882a593Smuzhiyun 	int i;
179*4882a593Smuzhiyun 	int load;
180*4882a593Smuzhiyun 	u32 busy_time_total;
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	session_manager = rga_drvdata->session_manager;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	seq_printf(m, "num of scheduler = %d\n", rga_drvdata->num_of_scheduler);
185*4882a593Smuzhiyun 	seq_printf(m, "================= load ==================\n");
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	for (i = 0; i < rga_drvdata->num_of_scheduler; i++) {
188*4882a593Smuzhiyun 		scheduler = rga_drvdata->scheduler[i];
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 		seq_printf(m, "scheduler[%d]: %s\n",
191*4882a593Smuzhiyun 			i, dev_driver_string(scheduler->dev));
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 		spin_lock_irqsave(&scheduler->irq_lock, flags);
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 		busy_time_total = scheduler->timer.busy_time_record;
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 		spin_unlock_irqrestore(&scheduler->irq_lock, flags);
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 		load = (busy_time_total * 100 / RGA_LOAD_INTERVAL_US);
200*4882a593Smuzhiyun 		if (load > 100)
201*4882a593Smuzhiyun 			load = 100;
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 		seq_printf(m, "\t load = %d%%\n", load);
204*4882a593Smuzhiyun 		seq_printf(m, "-----------------------------------\n");
205*4882a593Smuzhiyun 	}
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	mutex_lock(&session_manager->lock);
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 	idr_for_each_entry(&session_manager->ctx_id_idr, session, id)
210*4882a593Smuzhiyun 		seq_printf(m, "\t process %d: pid = %d, name: %s\n", id,
211*4882a593Smuzhiyun 			session->tgid, session->pname);
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	mutex_unlock(&session_manager->lock);
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	return 0;
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun 
rga_scheduler_show(struct seq_file * m,void * data)218*4882a593Smuzhiyun static int rga_scheduler_show(struct seq_file *m, void *data)
219*4882a593Smuzhiyun {
220*4882a593Smuzhiyun 	struct rga_scheduler_t *scheduler = NULL;
221*4882a593Smuzhiyun 	int i;
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	seq_printf(m, "num of scheduler = %d\n", rga_drvdata->num_of_scheduler);
224*4882a593Smuzhiyun 	seq_printf(m, "===================================\n");
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	for (i = 0; i < rga_drvdata->num_of_scheduler; i++) {
227*4882a593Smuzhiyun 		scheduler = rga_drvdata->scheduler[i];
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 		seq_printf(m, "scheduler[%d]: %s\n",
230*4882a593Smuzhiyun 			i, dev_driver_string(scheduler->dev));
231*4882a593Smuzhiyun 		seq_printf(m, "-----------------------------------\n");
232*4882a593Smuzhiyun 		seq_printf(m, "pd_ref = %d\n", scheduler->pd_refcount);
233*4882a593Smuzhiyun 	}
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	return 0;
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun 
rga_mm_session_show(struct seq_file * m,void * data)238*4882a593Smuzhiyun static int rga_mm_session_show(struct seq_file *m, void *data)
239*4882a593Smuzhiyun {
240*4882a593Smuzhiyun 	int id;
241*4882a593Smuzhiyun 	struct rga_mm *mm_session = NULL;
242*4882a593Smuzhiyun 	struct rga_internal_buffer *dump_buffer;
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	mm_session = rga_drvdata->mm;
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	mutex_lock(&mm_session->lock);
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	seq_puts(m, "rga_mm dump:\n");
249*4882a593Smuzhiyun 	seq_printf(m, "buffer count = %d\n", mm_session->buffer_count);
250*4882a593Smuzhiyun 	seq_puts(m, "===============================================================\n");
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	idr_for_each_entry(&mm_session->memory_idr, dump_buffer, id) {
253*4882a593Smuzhiyun 		seq_printf(m, "handle = %d refcount = %d mm_flag = 0x%x	tgid = %d\n",
254*4882a593Smuzhiyun 			   dump_buffer->handle, kref_read(&dump_buffer->refcount),
255*4882a593Smuzhiyun 			   dump_buffer->mm_flag, dump_buffer->session->tgid);
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 		switch (dump_buffer->type) {
258*4882a593Smuzhiyun 		case RGA_DMA_BUFFER:
259*4882a593Smuzhiyun 		case RGA_DMA_BUFFER_PTR:
260*4882a593Smuzhiyun 			if (rga_mm_is_invalid_dma_buffer(dump_buffer->dma_buffer))
261*4882a593Smuzhiyun 				break;
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 			seq_puts(m, "dma_buffer:\n");
264*4882a593Smuzhiyun 			seq_printf(m, "\t dma_buf = %p, iova = 0x%lxsgt = 0x%p, size = %ld, map_core = 0x%x\n",
265*4882a593Smuzhiyun 				   dump_buffer->dma_buffer->dma_buf,
266*4882a593Smuzhiyun 				   (unsigned long)dump_buffer->dma_buffer->iova,
267*4882a593Smuzhiyun 				   dump_buffer->dma_buffer->sgt,
268*4882a593Smuzhiyun 				   dump_buffer->dma_buffer->size,
269*4882a593Smuzhiyun 				   dump_buffer->dma_buffer->scheduler->core);
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 			if (dump_buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS)
272*4882a593Smuzhiyun 				seq_printf(m, "\t is contiguous, pa = 0x%lx\n",
273*4882a593Smuzhiyun 					   (unsigned long)dump_buffer->phys_addr);
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 			break;
276*4882a593Smuzhiyun 		case RGA_VIRTUAL_ADDRESS:
277*4882a593Smuzhiyun 			if (dump_buffer->virt_addr == NULL)
278*4882a593Smuzhiyun 				break;
279*4882a593Smuzhiyun 			seq_puts(m, "virtual address:\n");
280*4882a593Smuzhiyun 			seq_printf(m, "\t va = 0x%lx, pages = 0x%p, size = %ld\n",
281*4882a593Smuzhiyun 				   (unsigned long)dump_buffer->virt_addr->addr,
282*4882a593Smuzhiyun 				   dump_buffer->virt_addr->pages,
283*4882a593Smuzhiyun 				   dump_buffer->virt_addr->size);
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 			if (rga_mm_is_invalid_dma_buffer(dump_buffer->dma_buffer))
286*4882a593Smuzhiyun 				break;
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 			seq_printf(m, "\t iova = 0x%lx, offset = 0x%lx, sgt = 0x%p, size = %ld, map_core = 0x%x\n",
289*4882a593Smuzhiyun 				   (unsigned long)dump_buffer->dma_buffer->iova,
290*4882a593Smuzhiyun 				   (unsigned long)dump_buffer->dma_buffer->offset,
291*4882a593Smuzhiyun 				   dump_buffer->dma_buffer->sgt,
292*4882a593Smuzhiyun 				   dump_buffer->dma_buffer->size,
293*4882a593Smuzhiyun 				   dump_buffer->dma_buffer->scheduler->core);
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 			if (dump_buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS)
296*4882a593Smuzhiyun 				seq_printf(m, "\t is contiguous, pa = 0x%lx\n",
297*4882a593Smuzhiyun 					   (unsigned long)dump_buffer->phys_addr);
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 			break;
300*4882a593Smuzhiyun 		case RGA_PHYSICAL_ADDRESS:
301*4882a593Smuzhiyun 			seq_puts(m, "physical address:\n");
302*4882a593Smuzhiyun 			seq_printf(m, "\t pa = 0x%lx\n", (unsigned long)dump_buffer->phys_addr);
303*4882a593Smuzhiyun 			break;
304*4882a593Smuzhiyun 		default:
305*4882a593Smuzhiyun 			seq_puts(m, "Illegal external buffer!\n");
306*4882a593Smuzhiyun 			break;
307*4882a593Smuzhiyun 		}
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 		seq_puts(m, "---------------------------------------------------------------\n");
310*4882a593Smuzhiyun 	}
311*4882a593Smuzhiyun 	mutex_unlock(&mm_session->lock);
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 	return 0;
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun 
rga_request_manager_show(struct seq_file * m,void * data)316*4882a593Smuzhiyun static int rga_request_manager_show(struct seq_file *m, void *data)
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun 	int id, i;
319*4882a593Smuzhiyun 	struct rga_pending_request_manager *request_manager;
320*4882a593Smuzhiyun 	struct rga_request *request;
321*4882a593Smuzhiyun 	struct rga_req *task_list;
322*4882a593Smuzhiyun 	unsigned long flags;
323*4882a593Smuzhiyun 	int task_count = 0;
324*4882a593Smuzhiyun 	int finished_task_count = 0, failed_task_count = 0;
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 	request_manager = rga_drvdata->pend_request_manager;
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun 	seq_puts(m, "rga internal request dump:\n");
329*4882a593Smuzhiyun 	seq_printf(m, "request count = %d\n", request_manager->request_count);
330*4882a593Smuzhiyun 	seq_puts(m, "===============================================================\n");
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 	mutex_lock(&request_manager->lock);
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 	idr_for_each_entry(&request_manager->request_idr, request, id) {
335*4882a593Smuzhiyun 		seq_printf(m, "------------------ request: %d ------------------\n", request->id);
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 		spin_lock_irqsave(&request->lock, flags);
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 		task_count = request->task_count;
340*4882a593Smuzhiyun 		finished_task_count = request->finished_task_count;
341*4882a593Smuzhiyun 		failed_task_count = request->failed_task_count;
342*4882a593Smuzhiyun 		task_list = request->task_list;
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun 		spin_unlock_irqrestore(&request->lock, flags);
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 		if (task_list == NULL) {
347*4882a593Smuzhiyun 			seq_puts(m, "\t can not find task list from id\n");
348*4882a593Smuzhiyun 			continue;
349*4882a593Smuzhiyun 		}
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 		seq_printf(m, "\t set cmd num: %d, finish job: %d, failed job: %d, flags = 0x%x, ref = %d\n",
352*4882a593Smuzhiyun 			   task_count, finished_task_count, failed_task_count,
353*4882a593Smuzhiyun 			   request->flags, kref_read(&request->refcount));
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 		seq_puts(m, "\t cmd dump:\n\n");
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 		for (i = 0; i < request->task_count; i++)
358*4882a593Smuzhiyun 			rga_request_task_debug_info(m, &(task_list[i]));
359*4882a593Smuzhiyun 	}
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	mutex_unlock(&request_manager->lock);
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	return 0;
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun #ifdef CONFIG_NO_GKI
rga_dump_path_show(struct seq_file * m,void * data)367*4882a593Smuzhiyun static int rga_dump_path_show(struct seq_file *m, void *data)
368*4882a593Smuzhiyun {
369*4882a593Smuzhiyun 	seq_printf(m, "dump path: %s\n", g_dump_path);
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	return 0;
372*4882a593Smuzhiyun }
373*4882a593Smuzhiyun 
rga_dump_path_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)374*4882a593Smuzhiyun static ssize_t rga_dump_path_write(struct file *file, const char __user *ubuf,
375*4882a593Smuzhiyun 				    size_t len, loff_t *offp)
376*4882a593Smuzhiyun {
377*4882a593Smuzhiyun 	char buf[100];
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 	if (len > sizeof(buf) - 1)
380*4882a593Smuzhiyun 		return -EINVAL;
381*4882a593Smuzhiyun 	if (copy_from_user(buf, ubuf, len))
382*4882a593Smuzhiyun 		return -EFAULT;
383*4882a593Smuzhiyun 	buf[len - 1] = '\0';
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 	snprintf(g_dump_path, sizeof(buf), "%s", buf);
386*4882a593Smuzhiyun 	pr_info("dump path change to: %s\n", g_dump_path);
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	return len;
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun 
rga_dump_image_show(struct seq_file * m,void * data)391*4882a593Smuzhiyun static int rga_dump_image_show(struct seq_file *m, void *data)
392*4882a593Smuzhiyun {
393*4882a593Smuzhiyun 	seq_printf(m, "dump image count: %d\n", RGA_DEBUG_DUMP_IMAGE);
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	return 0;
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun 
rga_dump_image_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)398*4882a593Smuzhiyun static ssize_t rga_dump_image_write(struct file *file, const char __user *ubuf,
399*4882a593Smuzhiyun 				    size_t len, loff_t *offp)
400*4882a593Smuzhiyun {
401*4882a593Smuzhiyun 	int ret;
402*4882a593Smuzhiyun 	int dump_count = 0;
403*4882a593Smuzhiyun 	char buf[14];
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun 	if (len > sizeof(buf) - 1)
406*4882a593Smuzhiyun 		return -EINVAL;
407*4882a593Smuzhiyun 	if (copy_from_user(buf, ubuf, len))
408*4882a593Smuzhiyun 		return -EFAULT;
409*4882a593Smuzhiyun 	buf[len - 1] = '\0';
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun 	ret = kstrtoint(buf, 10, &dump_count);
412*4882a593Smuzhiyun 	if (ret) {
413*4882a593Smuzhiyun 		pr_err("Failed to parse str[%s]\n", buf);
414*4882a593Smuzhiyun 		return -EFAULT;
415*4882a593Smuzhiyun 	}
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	if (dump_count <= 0) {
418*4882a593Smuzhiyun 		pr_err("dump_image count is invalid [%d]!\n", dump_count);
419*4882a593Smuzhiyun 		return -EINVAL;
420*4882a593Smuzhiyun 	}
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	RGA_DEBUG_DUMP_IMAGE = dump_count;
423*4882a593Smuzhiyun 	pr_info("dump image %d\n", RGA_DEBUG_DUMP_IMAGE);
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 	return len;
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun #endif /* #ifdef CONFIG_NO_GKI */
428*4882a593Smuzhiyun 
rga_hardware_show(struct seq_file * m,void * data)429*4882a593Smuzhiyun static int rga_hardware_show(struct seq_file *m, void *data)
430*4882a593Smuzhiyun {
431*4882a593Smuzhiyun 	struct rga_scheduler_t *scheduler = NULL;
432*4882a593Smuzhiyun 	const struct rga_hw_data *hw_data = NULL;
433*4882a593Smuzhiyun 	int i;
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	seq_puts(m, "===================================\n");
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun 	for (i = 0; i < rga_drvdata->num_of_scheduler; i++) {
438*4882a593Smuzhiyun 		scheduler = rga_drvdata->scheduler[i];
439*4882a593Smuzhiyun 		hw_data = scheduler->data;
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun 		seq_printf(m, "%s, core %d: version: %s\n",
442*4882a593Smuzhiyun 			   dev_driver_string(scheduler->dev),
443*4882a593Smuzhiyun 			   scheduler->core, scheduler->version.str);
444*4882a593Smuzhiyun 		seq_printf(m, "input range: %dx%d ~ %dx%d\n",
445*4882a593Smuzhiyun 			   hw_data->input_range.min.width, hw_data->input_range.min.height,
446*4882a593Smuzhiyun 			   hw_data->input_range.max.width, hw_data->input_range.max.height);
447*4882a593Smuzhiyun 		seq_printf(m, "output range: %dx%d ~ %dx%d\n",
448*4882a593Smuzhiyun 			   hw_data->output_range.min.width, hw_data->output_range.min.height,
449*4882a593Smuzhiyun 			   hw_data->output_range.max.width, hw_data->output_range.max.height);
450*4882a593Smuzhiyun 		seq_printf(m, "scale limit: 1/%d ~ %d\n",
451*4882a593Smuzhiyun 			   (1 << hw_data->max_downscale_factor),
452*4882a593Smuzhiyun 			   (1 << hw_data->max_upscale_factor));
453*4882a593Smuzhiyun 		seq_printf(m, "byte_stride_align: %d\n", hw_data->byte_stride_align);
454*4882a593Smuzhiyun 		seq_printf(m, "max_byte_stride: %d\n", hw_data->max_byte_stride);
455*4882a593Smuzhiyun 		seq_printf(m, "csc: RGB2YUV 0x%x YUV2RGB 0x%x\n",
456*4882a593Smuzhiyun 			   hw_data->csc_r2y_mode, hw_data->csc_y2r_mode);
457*4882a593Smuzhiyun 		seq_printf(m, "feature: 0x%x\n", hw_data->feature);
458*4882a593Smuzhiyun 		seq_printf(m, "mmu: %s\n", rga_get_mmu_type_str(hw_data->mmu));
459*4882a593Smuzhiyun 		seq_puts(m, "-----------------------------------\n");
460*4882a593Smuzhiyun 	}
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 	return 0;
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun static struct rga_debugger_list rga_debugger_root_list[] = {
466*4882a593Smuzhiyun 	{"debug", rga_debug_show, rga_debug_write, NULL},
467*4882a593Smuzhiyun 	{"driver_version", rga_version_show, NULL, NULL},
468*4882a593Smuzhiyun 	{"load", rga_load_show, NULL, NULL},
469*4882a593Smuzhiyun 	{"scheduler_status", rga_scheduler_show, NULL, NULL},
470*4882a593Smuzhiyun 	{"mm_session", rga_mm_session_show, NULL, NULL},
471*4882a593Smuzhiyun 	{"request_manager", rga_request_manager_show, NULL, NULL},
472*4882a593Smuzhiyun #ifdef CONFIG_NO_GKI
473*4882a593Smuzhiyun 	{"dump_path", rga_dump_path_show, rga_dump_path_write, NULL},
474*4882a593Smuzhiyun 	{"dump_image", rga_dump_image_show, rga_dump_image_write, NULL},
475*4882a593Smuzhiyun #endif
476*4882a593Smuzhiyun 	{"hardware", rga_hardware_show, NULL, NULL},
477*4882a593Smuzhiyun };
478*4882a593Smuzhiyun 
rga_debugger_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)479*4882a593Smuzhiyun static ssize_t rga_debugger_write(struct file *file, const char __user *ubuf,
480*4882a593Smuzhiyun 				 size_t len, loff_t *offp)
481*4882a593Smuzhiyun {
482*4882a593Smuzhiyun 	struct seq_file *priv = file->private_data;
483*4882a593Smuzhiyun 	struct rga_debugger_node *node = priv->private;
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 	if (node->info_ent->write)
486*4882a593Smuzhiyun 		return node->info_ent->write(file, ubuf, len, offp);
487*4882a593Smuzhiyun 	else
488*4882a593Smuzhiyun 		return len;
489*4882a593Smuzhiyun }
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun #ifdef CONFIG_ROCKCHIP_RGA_DEBUG_FS
rga_debugfs_open(struct inode * inode,struct file * file)492*4882a593Smuzhiyun static int rga_debugfs_open(struct inode *inode, struct file *file)
493*4882a593Smuzhiyun {
494*4882a593Smuzhiyun 	struct rga_debugger_node *node = inode->i_private;
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 	return single_open(file, node->info_ent->show, node);
497*4882a593Smuzhiyun }
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun static const struct file_operations rga_debugfs_fops = {
500*4882a593Smuzhiyun 	.owner = THIS_MODULE,
501*4882a593Smuzhiyun 	.open = rga_debugfs_open,
502*4882a593Smuzhiyun 	.read = seq_read,
503*4882a593Smuzhiyun 	.llseek = seq_lseek,
504*4882a593Smuzhiyun 	.release = single_release,
505*4882a593Smuzhiyun 	.write = rga_debugger_write,
506*4882a593Smuzhiyun };
507*4882a593Smuzhiyun 
rga_debugfs_remove_files(struct rga_debugger * debugger)508*4882a593Smuzhiyun static int rga_debugfs_remove_files(struct rga_debugger *debugger)
509*4882a593Smuzhiyun {
510*4882a593Smuzhiyun 	struct rga_debugger_node *pos, *q;
511*4882a593Smuzhiyun 	struct list_head *entry_list;
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	mutex_lock(&debugger->debugfs_lock);
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 	/* Delete debugfs entry list */
516*4882a593Smuzhiyun 	entry_list = &debugger->debugfs_entry_list;
517*4882a593Smuzhiyun 	list_for_each_entry_safe(pos, q, entry_list, list) {
518*4882a593Smuzhiyun 		if (pos->dent == NULL)
519*4882a593Smuzhiyun 			continue;
520*4882a593Smuzhiyun 		list_del(&pos->list);
521*4882a593Smuzhiyun 		kfree(pos);
522*4882a593Smuzhiyun 		pos = NULL;
523*4882a593Smuzhiyun 	}
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun 	/* Delete all debugfs node in this directory */
526*4882a593Smuzhiyun 	debugfs_remove_recursive(debugger->debugfs_dir);
527*4882a593Smuzhiyun 	debugger->debugfs_dir = NULL;
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	mutex_unlock(&debugger->debugfs_lock);
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun 	return 0;
532*4882a593Smuzhiyun }
533*4882a593Smuzhiyun 
rga_debugfs_create_files(const struct rga_debugger_list * files,int count,struct dentry * root,struct rga_debugger * debugger)534*4882a593Smuzhiyun static int rga_debugfs_create_files(const struct rga_debugger_list *files,
535*4882a593Smuzhiyun 					int count, struct dentry *root,
536*4882a593Smuzhiyun 					struct rga_debugger *debugger)
537*4882a593Smuzhiyun {
538*4882a593Smuzhiyun 	int i;
539*4882a593Smuzhiyun 	struct dentry *ent;
540*4882a593Smuzhiyun 	struct rga_debugger_node *tmp;
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
543*4882a593Smuzhiyun 		tmp = kmalloc(sizeof(struct rga_debugger_node), GFP_KERNEL);
544*4882a593Smuzhiyun 		if (tmp == NULL) {
545*4882a593Smuzhiyun 			pr_err("Cannot alloc node path /sys/kernel/debug/%pd/%s\n",
546*4882a593Smuzhiyun 				 root, files[i].name);
547*4882a593Smuzhiyun 			goto MALLOC_FAIL;
548*4882a593Smuzhiyun 		}
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun 		tmp->info_ent = &files[i];
551*4882a593Smuzhiyun 		tmp->debugger = debugger;
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 		ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO,
554*4882a593Smuzhiyun 					 root, tmp, &rga_debugfs_fops);
555*4882a593Smuzhiyun 		if (!ent) {
556*4882a593Smuzhiyun 			pr_err("Cannot create /sys/kernel/debug/%pd/%s\n", root,
557*4882a593Smuzhiyun 				 files[i].name);
558*4882a593Smuzhiyun 			goto CREATE_FAIL;
559*4882a593Smuzhiyun 		}
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 		tmp->dent = ent;
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun 		mutex_lock(&debugger->debugfs_lock);
564*4882a593Smuzhiyun 		list_add_tail(&tmp->list, &debugger->debugfs_entry_list);
565*4882a593Smuzhiyun 		mutex_unlock(&debugger->debugfs_lock);
566*4882a593Smuzhiyun 	}
567*4882a593Smuzhiyun 
568*4882a593Smuzhiyun 	return 0;
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun CREATE_FAIL:
571*4882a593Smuzhiyun 	kfree(tmp);
572*4882a593Smuzhiyun MALLOC_FAIL:
573*4882a593Smuzhiyun 	rga_debugfs_remove_files(debugger);
574*4882a593Smuzhiyun 
575*4882a593Smuzhiyun 	return -1;
576*4882a593Smuzhiyun }
577*4882a593Smuzhiyun 
rga_debugfs_remove(void)578*4882a593Smuzhiyun int rga_debugfs_remove(void)
579*4882a593Smuzhiyun {
580*4882a593Smuzhiyun 	struct rga_debugger *debugger;
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun 	debugger = rga_drvdata->debugger;
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 	rga_debugfs_remove_files(debugger);
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	return 0;
587*4882a593Smuzhiyun }
588*4882a593Smuzhiyun 
rga_debugfs_init(void)589*4882a593Smuzhiyun int rga_debugfs_init(void)
590*4882a593Smuzhiyun {
591*4882a593Smuzhiyun 	int ret;
592*4882a593Smuzhiyun 	struct rga_debugger *debugger;
593*4882a593Smuzhiyun 
594*4882a593Smuzhiyun 	debugger = rga_drvdata->debugger;
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun 	debugger->debugfs_dir =
597*4882a593Smuzhiyun 		debugfs_create_dir(RGA_DEBUGGER_ROOT_NAME, NULL);
598*4882a593Smuzhiyun 	if (IS_ERR_OR_NULL(debugger->debugfs_dir)) {
599*4882a593Smuzhiyun 		pr_err("failed on mkdir /sys/kernel/debug/%s\n",
600*4882a593Smuzhiyun 			 RGA_DEBUGGER_ROOT_NAME);
601*4882a593Smuzhiyun 		debugger->debugfs_dir = NULL;
602*4882a593Smuzhiyun 		return -EIO;
603*4882a593Smuzhiyun 	}
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 	ret = rga_debugfs_create_files(rga_debugger_root_list, ARRAY_SIZE(rga_debugger_root_list),
606*4882a593Smuzhiyun 					 debugger->debugfs_dir, debugger);
607*4882a593Smuzhiyun 	if (ret) {
608*4882a593Smuzhiyun 		pr_err("Could not install rga_debugger_root_list debugfs\n");
609*4882a593Smuzhiyun 		goto CREATE_FAIL;
610*4882a593Smuzhiyun 	}
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun 	return 0;
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun CREATE_FAIL:
615*4882a593Smuzhiyun 	rga_debugfs_remove();
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun 	return ret;
618*4882a593Smuzhiyun }
619*4882a593Smuzhiyun #endif /* #ifdef CONFIG_ROCKCHIP_RGA_DEBUG_FS */
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun #ifdef CONFIG_ROCKCHIP_RGA_PROC_FS
rga_procfs_open(struct inode * inode,struct file * file)622*4882a593Smuzhiyun static int rga_procfs_open(struct inode *inode, struct file *file)
623*4882a593Smuzhiyun {
624*4882a593Smuzhiyun #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
625*4882a593Smuzhiyun 	struct rga_debugger_node *node = pde_data(inode);
626*4882a593Smuzhiyun #else
627*4882a593Smuzhiyun 	struct rga_debugger_node *node = PDE_DATA(inode);
628*4882a593Smuzhiyun #endif
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun 	return single_open(file, node->info_ent->show, node);
631*4882a593Smuzhiyun }
632*4882a593Smuzhiyun 
633*4882a593Smuzhiyun static const struct proc_ops rga_procfs_fops = {
634*4882a593Smuzhiyun 	.proc_open = rga_procfs_open,
635*4882a593Smuzhiyun 	.proc_read = seq_read,
636*4882a593Smuzhiyun 	.proc_lseek = seq_lseek,
637*4882a593Smuzhiyun 	.proc_release = single_release,
638*4882a593Smuzhiyun 	.proc_write = rga_debugger_write,
639*4882a593Smuzhiyun };
640*4882a593Smuzhiyun 
rga_procfs_remove_files(struct rga_debugger * debugger)641*4882a593Smuzhiyun static int rga_procfs_remove_files(struct rga_debugger *debugger)
642*4882a593Smuzhiyun {
643*4882a593Smuzhiyun 	struct rga_debugger_node *pos, *q;
644*4882a593Smuzhiyun 	struct list_head *entry_list;
645*4882a593Smuzhiyun 
646*4882a593Smuzhiyun 	mutex_lock(&debugger->procfs_lock);
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun 	/* Delete procfs entry list */
649*4882a593Smuzhiyun 	entry_list = &debugger->procfs_entry_list;
650*4882a593Smuzhiyun 	list_for_each_entry_safe(pos, q, entry_list, list) {
651*4882a593Smuzhiyun 		if (pos->pent == NULL)
652*4882a593Smuzhiyun 			continue;
653*4882a593Smuzhiyun 		list_del(&pos->list);
654*4882a593Smuzhiyun 		kfree(pos);
655*4882a593Smuzhiyun 		pos = NULL;
656*4882a593Smuzhiyun 	}
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun 	/* Delete all procfs node in this directory */
659*4882a593Smuzhiyun 	proc_remove(debugger->procfs_dir);
660*4882a593Smuzhiyun 	debugger->procfs_dir = NULL;
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun 	mutex_unlock(&debugger->procfs_lock);
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun 	return 0;
665*4882a593Smuzhiyun }
666*4882a593Smuzhiyun 
rga_procfs_create_files(const struct rga_debugger_list * files,int count,struct proc_dir_entry * root,struct rga_debugger * debugger)667*4882a593Smuzhiyun static int rga_procfs_create_files(const struct rga_debugger_list *files,
668*4882a593Smuzhiyun 				 int count, struct proc_dir_entry *root,
669*4882a593Smuzhiyun 				 struct rga_debugger *debugger)
670*4882a593Smuzhiyun {
671*4882a593Smuzhiyun 	int i;
672*4882a593Smuzhiyun 	struct proc_dir_entry *ent;
673*4882a593Smuzhiyun 	struct rga_debugger_node *tmp;
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
676*4882a593Smuzhiyun 		tmp = kmalloc(sizeof(struct rga_debugger_node), GFP_KERNEL);
677*4882a593Smuzhiyun 		if (tmp == NULL) {
678*4882a593Smuzhiyun 			pr_err("Cannot alloc node path for /proc/%s/%s\n",
679*4882a593Smuzhiyun 				 RGA_DEBUGGER_ROOT_NAME, files[i].name);
680*4882a593Smuzhiyun 			goto MALLOC_FAIL;
681*4882a593Smuzhiyun 		}
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun 		tmp->info_ent = &files[i];
684*4882a593Smuzhiyun 		tmp->debugger = debugger;
685*4882a593Smuzhiyun 
686*4882a593Smuzhiyun 		ent = proc_create_data(files[i].name, S_IFREG | S_IRUGO,
687*4882a593Smuzhiyun 					 root, &rga_procfs_fops, tmp);
688*4882a593Smuzhiyun 		if (!ent) {
689*4882a593Smuzhiyun 			pr_err("Cannot create /proc/%s/%s\n",
690*4882a593Smuzhiyun 				 RGA_DEBUGGER_ROOT_NAME, files[i].name);
691*4882a593Smuzhiyun 			goto CREATE_FAIL;
692*4882a593Smuzhiyun 		}
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun 		tmp->pent = ent;
695*4882a593Smuzhiyun 
696*4882a593Smuzhiyun 		mutex_lock(&debugger->procfs_lock);
697*4882a593Smuzhiyun 		list_add_tail(&tmp->list, &debugger->procfs_entry_list);
698*4882a593Smuzhiyun 		mutex_unlock(&debugger->procfs_lock);
699*4882a593Smuzhiyun 	}
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 	return 0;
702*4882a593Smuzhiyun 
703*4882a593Smuzhiyun CREATE_FAIL:
704*4882a593Smuzhiyun 	kfree(tmp);
705*4882a593Smuzhiyun MALLOC_FAIL:
706*4882a593Smuzhiyun 	rga_procfs_remove_files(debugger);
707*4882a593Smuzhiyun 	return -1;
708*4882a593Smuzhiyun }
709*4882a593Smuzhiyun 
rga_procfs_remove(void)710*4882a593Smuzhiyun int rga_procfs_remove(void)
711*4882a593Smuzhiyun {
712*4882a593Smuzhiyun 	struct rga_debugger *debugger;
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun 	debugger = rga_drvdata->debugger;
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun 	rga_procfs_remove_files(debugger);
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun 	return 0;
719*4882a593Smuzhiyun }
720*4882a593Smuzhiyun 
rga_procfs_init(void)721*4882a593Smuzhiyun int rga_procfs_init(void)
722*4882a593Smuzhiyun {
723*4882a593Smuzhiyun 	int ret;
724*4882a593Smuzhiyun 	struct rga_debugger *debugger;
725*4882a593Smuzhiyun 
726*4882a593Smuzhiyun 	debugger = rga_drvdata->debugger;
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 	debugger->procfs_dir = proc_mkdir(RGA_DEBUGGER_ROOT_NAME, NULL);
729*4882a593Smuzhiyun 	if (IS_ERR_OR_NULL(debugger->procfs_dir)) {
730*4882a593Smuzhiyun 		pr_err("failed on mkdir /proc/%s\n", RGA_DEBUGGER_ROOT_NAME);
731*4882a593Smuzhiyun 		debugger->procfs_dir = NULL;
732*4882a593Smuzhiyun 		return -EIO;
733*4882a593Smuzhiyun 	}
734*4882a593Smuzhiyun 
735*4882a593Smuzhiyun 	ret = rga_procfs_create_files(rga_debugger_root_list, ARRAY_SIZE(rga_debugger_root_list),
736*4882a593Smuzhiyun 					 debugger->procfs_dir, debugger);
737*4882a593Smuzhiyun 	if (ret) {
738*4882a593Smuzhiyun 		pr_err("Could not install rga_debugger_root_list procfs\n");
739*4882a593Smuzhiyun 		goto CREATE_FAIL;
740*4882a593Smuzhiyun 	}
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun 	return 0;
743*4882a593Smuzhiyun 
744*4882a593Smuzhiyun CREATE_FAIL:
745*4882a593Smuzhiyun 	rga_procfs_remove();
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun 	return ret;
748*4882a593Smuzhiyun }
749*4882a593Smuzhiyun #endif /* #ifdef CONFIG_ROCKCHIP_RGA_PROC_FS */
750*4882a593Smuzhiyun 
rga_request_task_debug_info(struct seq_file * m,struct rga_req * req)751*4882a593Smuzhiyun void rga_request_task_debug_info(struct seq_file *m, struct rga_req *req)
752*4882a593Smuzhiyun {
753*4882a593Smuzhiyun 	seq_printf(m, "\t\t rotate_mode = %d\n", req->rotate_mode);
754*4882a593Smuzhiyun 	seq_printf(m, "\t\t src: y = %lx uv = %lx v = %lx aw = %d ah = %d vw = %d vh = %d\n",
755*4882a593Smuzhiyun 		 (unsigned long)req->src.yrgb_addr, (unsigned long)req->src.uv_addr,
756*4882a593Smuzhiyun 		 (unsigned long)req->src.v_addr, req->src.act_w, req->src.act_h,
757*4882a593Smuzhiyun 		 req->src.vir_w, req->src.vir_h);
758*4882a593Smuzhiyun 	seq_printf(m, "\t\t src: xoff = %d, yoff = %d, format = 0x%x, rd_mode = %d\n",
759*4882a593Smuzhiyun 		req->src.x_offset, req->src.y_offset, req->src.format, req->src.rd_mode);
760*4882a593Smuzhiyun 
761*4882a593Smuzhiyun 	if (req->pat.yrgb_addr != 0 || req->pat.uv_addr != 0
762*4882a593Smuzhiyun 		|| req->pat.v_addr != 0) {
763*4882a593Smuzhiyun 		seq_printf(m, "\t\t pat: y=%lx uv=%lx v=%lx aw=%d ah=%d vw=%d vh=%d\n",
764*4882a593Smuzhiyun 			 (unsigned long)req->pat.yrgb_addr, (unsigned long)req->pat.uv_addr,
765*4882a593Smuzhiyun 			 (unsigned long)req->pat.v_addr, req->pat.act_w, req->pat.act_h,
766*4882a593Smuzhiyun 			 req->pat.vir_w, req->pat.vir_h);
767*4882a593Smuzhiyun 		seq_printf(m, "\t\t xoff = %d yoff = %d, format = 0x%x, rd_mode = %d\n",
768*4882a593Smuzhiyun 			req->pat.x_offset, req->pat.y_offset, req->pat.format, req->pat.rd_mode);
769*4882a593Smuzhiyun 	}
770*4882a593Smuzhiyun 
771*4882a593Smuzhiyun 	seq_printf(m, "\t\t dst: y=%lx uv=%lx v=%lx aw=%d ah=%d vw=%d vh=%d\n",
772*4882a593Smuzhiyun 		 (unsigned long)req->dst.yrgb_addr, (unsigned long)req->dst.uv_addr,
773*4882a593Smuzhiyun 		 (unsigned long)req->dst.v_addr, req->dst.act_w, req->dst.act_h,
774*4882a593Smuzhiyun 		 req->dst.vir_w, req->dst.vir_h);
775*4882a593Smuzhiyun 	seq_printf(m, "\t\t dst: xoff = %d, yoff = %d, format = 0x%x, rd_mode = %d\n",
776*4882a593Smuzhiyun 		req->dst.x_offset, req->dst.y_offset, req->dst.format, req->dst.rd_mode);
777*4882a593Smuzhiyun 
778*4882a593Smuzhiyun 	seq_printf(m, "\t\t mmu: mmu_flag=%x en=%x\n",
779*4882a593Smuzhiyun 		req->mmu_info.mmu_flag, req->mmu_info.mmu_en);
780*4882a593Smuzhiyun 	seq_printf(m, "\t\t alpha: rop_mode = %x\n", req->alpha_rop_mode);
781*4882a593Smuzhiyun 	seq_printf(m, "\t\t yuv2rgb mode is %x\n", req->yuv2rgb_mode);
782*4882a593Smuzhiyun 	seq_printf(m, "\t\t set core = %d, priority = %d, in_fence_fd = %d\n",
783*4882a593Smuzhiyun 		req->core, req->priority, req->in_fence_fd);
784*4882a593Smuzhiyun }
785*4882a593Smuzhiyun 
rga_cmd_print_debug_info(struct rga_req * req)786*4882a593Smuzhiyun void rga_cmd_print_debug_info(struct rga_req *req)
787*4882a593Smuzhiyun {
788*4882a593Smuzhiyun 	pr_info("render_mode = %d, bitblit_mode=%d, rotate_mode = %d\n",
789*4882a593Smuzhiyun 		req->render_mode, req->bsfilter_flag,
790*4882a593Smuzhiyun 		req->rotate_mode);
791*4882a593Smuzhiyun 
792*4882a593Smuzhiyun 	pr_info("src: y = %lx uv = %lx v = %lx aw = %d ah = %d vw = %d vh = %d\n",
793*4882a593Smuzhiyun 		 (unsigned long)req->src.yrgb_addr,
794*4882a593Smuzhiyun 		 (unsigned long)req->src.uv_addr,
795*4882a593Smuzhiyun 		 (unsigned long)req->src.v_addr,
796*4882a593Smuzhiyun 		 req->src.act_w, req->src.act_h,
797*4882a593Smuzhiyun 		 req->src.vir_w, req->src.vir_h);
798*4882a593Smuzhiyun 	pr_info("src: xoff = %d, yoff = %d, format = 0x%x, rd_mode = %d\n",
799*4882a593Smuzhiyun 		req->src.x_offset, req->src.y_offset,
800*4882a593Smuzhiyun 		 req->src.format, req->src.rd_mode);
801*4882a593Smuzhiyun 
802*4882a593Smuzhiyun 	if (req->pat.yrgb_addr != 0 || req->pat.uv_addr != 0
803*4882a593Smuzhiyun 		|| req->pat.v_addr != 0) {
804*4882a593Smuzhiyun 		pr_info("pat: y=%lx uv=%lx v=%lx aw=%d ah=%d vw=%d vh=%d\n",
805*4882a593Smuzhiyun 			 (unsigned long)req->pat.yrgb_addr,
806*4882a593Smuzhiyun 			 (unsigned long)req->pat.uv_addr,
807*4882a593Smuzhiyun 			 (unsigned long)req->pat.v_addr,
808*4882a593Smuzhiyun 			 req->pat.act_w, req->pat.act_h,
809*4882a593Smuzhiyun 			 req->pat.vir_w, req->pat.vir_h);
810*4882a593Smuzhiyun 		pr_info("pat: xoff = %d yoff = %d, format = 0x%x, rd_mode = %d\n",
811*4882a593Smuzhiyun 			req->pat.x_offset, req->pat.y_offset,
812*4882a593Smuzhiyun 			req->pat.format, req->pat.rd_mode);
813*4882a593Smuzhiyun 	}
814*4882a593Smuzhiyun 
815*4882a593Smuzhiyun 	pr_info("dst: y=%lx uv=%lx v=%lx aw=%d ah=%d vw=%d vh=%d\n",
816*4882a593Smuzhiyun 		 (unsigned long)req->dst.yrgb_addr,
817*4882a593Smuzhiyun 		 (unsigned long)req->dst.uv_addr,
818*4882a593Smuzhiyun 		 (unsigned long)req->dst.v_addr,
819*4882a593Smuzhiyun 		 req->dst.act_w, req->dst.act_h,
820*4882a593Smuzhiyun 		 req->dst.vir_w, req->dst.vir_h);
821*4882a593Smuzhiyun 	pr_info("dst: xoff = %d, yoff = %d, format = 0x%x, rd_mode = %d\n",
822*4882a593Smuzhiyun 		req->dst.x_offset, req->dst.y_offset,
823*4882a593Smuzhiyun 		req->dst.format, req->dst.rd_mode);
824*4882a593Smuzhiyun 
825*4882a593Smuzhiyun 	pr_info("mmu: mmu_flag=%x en=%x\n",
826*4882a593Smuzhiyun 		req->mmu_info.mmu_flag, req->mmu_info.mmu_en);
827*4882a593Smuzhiyun 	pr_info("alpha: rop_mode = %x\n", req->alpha_rop_mode);
828*4882a593Smuzhiyun 	pr_info("yuv2rgb mode is %x\n", req->yuv2rgb_mode);
829*4882a593Smuzhiyun 	pr_info("set core = %d, priority = %d, in_fence_fd = %d\n",
830*4882a593Smuzhiyun 		req->core, req->priority, req->in_fence_fd);
831*4882a593Smuzhiyun }
832*4882a593Smuzhiyun 
833*4882a593Smuzhiyun #ifdef CONFIG_NO_GKI
rga_dump_image_to_file(struct rga_internal_buffer * dump_buffer,const char * channel_name,int plane_id,int core)834*4882a593Smuzhiyun static int rga_dump_image_to_file(struct rga_internal_buffer *dump_buffer,
835*4882a593Smuzhiyun 				  const char *channel_name,
836*4882a593Smuzhiyun 				  int plane_id,
837*4882a593Smuzhiyun 				  int core)
838*4882a593Smuzhiyun {
839*4882a593Smuzhiyun 	char file_name[100];
840*4882a593Smuzhiyun 	struct file *file;
841*4882a593Smuzhiyun 	size_t size = 0;
842*4882a593Smuzhiyun 	loff_t pos = 0;
843*4882a593Smuzhiyun #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
844*4882a593Smuzhiyun 	int ret;
845*4882a593Smuzhiyun 	struct iosys_map map;
846*4882a593Smuzhiyun #endif
847*4882a593Smuzhiyun 	void *kvaddr = NULL;
848*4882a593Smuzhiyun 	void *kvaddr_origin = NULL;
849*4882a593Smuzhiyun 
850*4882a593Smuzhiyun 	switch (dump_buffer->type) {
851*4882a593Smuzhiyun 	case RGA_DMA_BUFFER:
852*4882a593Smuzhiyun 	case RGA_DMA_BUFFER_PTR:
853*4882a593Smuzhiyun 		if (IS_ERR_OR_NULL(dump_buffer->dma_buffer->dma_buf)) {
854*4882a593Smuzhiyun 			pr_err("Failed to dump dma_buf 0x%px\n",
855*4882a593Smuzhiyun 			       dump_buffer->dma_buffer->dma_buf);
856*4882a593Smuzhiyun 			return -EINVAL;
857*4882a593Smuzhiyun 		}
858*4882a593Smuzhiyun 
859*4882a593Smuzhiyun #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
860*4882a593Smuzhiyun 		ret = dma_buf_vmap(dump_buffer->dma_buffer->dma_buf, &map);
861*4882a593Smuzhiyun 		kvaddr = ret ? NULL : map.vaddr;
862*4882a593Smuzhiyun #else
863*4882a593Smuzhiyun 		kvaddr = dma_buf_vmap(dump_buffer->dma_buffer->dma_buf);
864*4882a593Smuzhiyun #endif
865*4882a593Smuzhiyun 		if (!kvaddr) {
866*4882a593Smuzhiyun 			pr_err("can't vmap the dma buffer!\n");
867*4882a593Smuzhiyun 			return -EINVAL;
868*4882a593Smuzhiyun 		}
869*4882a593Smuzhiyun 
870*4882a593Smuzhiyun 		kvaddr_origin = kvaddr;
871*4882a593Smuzhiyun 		kvaddr += dump_buffer->dma_buffer->offset;
872*4882a593Smuzhiyun 		break;
873*4882a593Smuzhiyun 	case RGA_VIRTUAL_ADDRESS:
874*4882a593Smuzhiyun 		kvaddr = vmap(dump_buffer->virt_addr->pages, dump_buffer->virt_addr->page_count,
875*4882a593Smuzhiyun 			      VM_MAP, pgprot_writecombine(PAGE_KERNEL));
876*4882a593Smuzhiyun 		if (!kvaddr) {
877*4882a593Smuzhiyun 			pr_err("dump_vaddr vmap error!, 0x%lx\n",
878*4882a593Smuzhiyun 			       (unsigned long)dump_buffer->virt_addr->addr);
879*4882a593Smuzhiyun 			return -EFAULT;
880*4882a593Smuzhiyun 		}
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun 		kvaddr_origin = kvaddr;
883*4882a593Smuzhiyun 		kvaddr += dump_buffer->virt_addr->offset;
884*4882a593Smuzhiyun 		break;
885*4882a593Smuzhiyun 	case RGA_PHYSICAL_ADDRESS:
886*4882a593Smuzhiyun 		kvaddr = phys_to_virt(dump_buffer->phys_addr);
887*4882a593Smuzhiyun 		break;
888*4882a593Smuzhiyun 	default:
889*4882a593Smuzhiyun 		pr_err("unsupported memory type[%x]\n", dump_buffer->type);
890*4882a593Smuzhiyun 		return -EINVAL;
891*4882a593Smuzhiyun 	}
892*4882a593Smuzhiyun 
893*4882a593Smuzhiyun 	size = dump_buffer->size;
894*4882a593Smuzhiyun 
895*4882a593Smuzhiyun 	if (kvaddr == NULL) {
896*4882a593Smuzhiyun 		pr_err("dump addr is NULL!\n");
897*4882a593Smuzhiyun 		return -EFAULT;
898*4882a593Smuzhiyun 	}
899*4882a593Smuzhiyun 
900*4882a593Smuzhiyun 	if (size <= 0) {
901*4882a593Smuzhiyun 		pr_err("dump buffer size[%lx] is invalid!\n", (unsigned long)size);
902*4882a593Smuzhiyun 		return -EFAULT;
903*4882a593Smuzhiyun 	}
904*4882a593Smuzhiyun 
905*4882a593Smuzhiyun 	if (dump_buffer->memory_parm.width == 0 &&
906*4882a593Smuzhiyun 	    dump_buffer->memory_parm.height == 0)
907*4882a593Smuzhiyun 		snprintf(file_name, 100, "%s/%d_core%d_%s_plane%d_%s_size%zu_%s.bin",
908*4882a593Smuzhiyun 			 g_dump_path,
909*4882a593Smuzhiyun 			 RGA_DEBUG_DUMP_IMAGE, core, channel_name, plane_id,
910*4882a593Smuzhiyun 			 rga_get_memory_type_str(dump_buffer->type),
911*4882a593Smuzhiyun 			 size,
912*4882a593Smuzhiyun 			 rga_get_format_name(dump_buffer->memory_parm.format));
913*4882a593Smuzhiyun 	else
914*4882a593Smuzhiyun 		snprintf(file_name, 100, "%s/%d_core%d_%s_plane%d_%s_w%d_h%d_%s.bin",
915*4882a593Smuzhiyun 			 g_dump_path,
916*4882a593Smuzhiyun 			 RGA_DEBUG_DUMP_IMAGE, core, channel_name, plane_id,
917*4882a593Smuzhiyun 			 rga_get_memory_type_str(dump_buffer->type),
918*4882a593Smuzhiyun 			 dump_buffer->memory_parm.width,
919*4882a593Smuzhiyun 			 dump_buffer->memory_parm.height,
920*4882a593Smuzhiyun 			 rga_get_format_name(dump_buffer->memory_parm.format));
921*4882a593Smuzhiyun 
922*4882a593Smuzhiyun 	file = filp_open(file_name, O_RDWR | O_CREAT | O_TRUNC, 0600);
923*4882a593Smuzhiyun 	if (!IS_ERR(file)) {
924*4882a593Smuzhiyun 		kernel_write(file, kvaddr, size, &pos);
925*4882a593Smuzhiyun 		pr_info("dump image to: %s\n", file_name);
926*4882a593Smuzhiyun 		fput(file);
927*4882a593Smuzhiyun 	} else {
928*4882a593Smuzhiyun 		pr_info("open %s failed\n", file_name);
929*4882a593Smuzhiyun 	}
930*4882a593Smuzhiyun 
931*4882a593Smuzhiyun 	switch (dump_buffer->type) {
932*4882a593Smuzhiyun 	case RGA_DMA_BUFFER:
933*4882a593Smuzhiyun 	case RGA_DMA_BUFFER_PTR:
934*4882a593Smuzhiyun #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
935*4882a593Smuzhiyun 		dma_buf_vunmap(dump_buffer->dma_buffer->dma_buf, &map);
936*4882a593Smuzhiyun #else
937*4882a593Smuzhiyun 		dma_buf_vunmap(dump_buffer->dma_buffer->dma_buf, kvaddr_origin);
938*4882a593Smuzhiyun #endif
939*4882a593Smuzhiyun 		break;
940*4882a593Smuzhiyun 	case RGA_VIRTUAL_ADDRESS:
941*4882a593Smuzhiyun 		vunmap(kvaddr_origin);
942*4882a593Smuzhiyun 		break;
943*4882a593Smuzhiyun 	}
944*4882a593Smuzhiyun 
945*4882a593Smuzhiyun 	return 0;
946*4882a593Smuzhiyun }
947*4882a593Smuzhiyun 
rga_dump_channel_image(struct rga_job_buffer * job_buffer,const char * channel_name,int core)948*4882a593Smuzhiyun static inline void rga_dump_channel_image(struct rga_job_buffer *job_buffer,
949*4882a593Smuzhiyun 					  const char *channel_name,
950*4882a593Smuzhiyun 					  int core)
951*4882a593Smuzhiyun {
952*4882a593Smuzhiyun 	if (job_buffer->y_addr)
953*4882a593Smuzhiyun 		rga_dump_image_to_file(job_buffer->y_addr, channel_name, 0, core);
954*4882a593Smuzhiyun 	if (job_buffer->uv_addr)
955*4882a593Smuzhiyun 		rga_dump_image_to_file(job_buffer->uv_addr, channel_name, 1, core);
956*4882a593Smuzhiyun 	if (job_buffer->v_addr)
957*4882a593Smuzhiyun 		rga_dump_image_to_file(job_buffer->v_addr, channel_name, 2, core);
958*4882a593Smuzhiyun }
959*4882a593Smuzhiyun 
rga_dump_job_image(struct rga_job * dump_job)960*4882a593Smuzhiyun void rga_dump_job_image(struct rga_job *dump_job)
961*4882a593Smuzhiyun {
962*4882a593Smuzhiyun 	rga_dump_channel_image(&dump_job->src_buffer, "src", dump_job->core);
963*4882a593Smuzhiyun 	rga_dump_channel_image(&dump_job->src1_buffer, "src1", dump_job->core);
964*4882a593Smuzhiyun 	rga_dump_channel_image(&dump_job->dst_buffer, "dst", dump_job->core);
965*4882a593Smuzhiyun 	rga_dump_channel_image(&dump_job->els_buffer, "els", dump_job->core);
966*4882a593Smuzhiyun 
967*4882a593Smuzhiyun 	if (RGA_DEBUG_DUMP_IMAGE > 0)
968*4882a593Smuzhiyun 		RGA_DEBUG_DUMP_IMAGE--;
969*4882a593Smuzhiyun }
970*4882a593Smuzhiyun #endif /* #ifdef CONFIG_NO_GKI */
971