1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2010 Google, Inc.
4 * Author: Erik Gilling <konkers@android.com>
6 * Copyright (C) 2011-2013 NVIDIA Corporation
9 #include <linux/debugfs.h>
10 #include <linux/pm_runtime.h>
11 #include <linux/seq_file.h>
12 #include <linux/uaccess.h>
20 static DEFINE_MUTEX(debug_lock
);
22 unsigned int host1x_debug_trace_cmdbuf
;
24 static pid_t host1x_debug_force_timeout_pid
;
25 static u32 host1x_debug_force_timeout_val
;
26 static u32 host1x_debug_force_timeout_channel
;
28 void host1x_debug_output(struct output
*o
, const char *fmt
, ...)
34 len
= vsnprintf(o
->buf
, sizeof(o
->buf
), fmt
, args
);
37 o
->fn(o
->ctx
, o
->buf
, len
, false);
40 void host1x_debug_cont(struct output
*o
, const char *fmt
, ...)
46 len
= vsnprintf(o
->buf
, sizeof(o
->buf
), fmt
, args
);
49 o
->fn(o
->ctx
, o
->buf
, len
, true);
52 static int show_channel(struct host1x_channel
*ch
, void *data
, bool show_fifo
)
54 struct host1x
*m
= dev_get_drvdata(ch
->dev
->parent
);
55 struct output
*o
= data
;
58 err
= pm_runtime_resume_and_get(m
->dev
);
62 mutex_lock(&ch
->cdma
.lock
);
63 mutex_lock(&debug_lock
);
66 host1x_hw_show_channel_fifo(m
, ch
, o
);
68 host1x_hw_show_channel_cdma(m
, ch
, o
);
70 mutex_unlock(&debug_lock
);
71 mutex_unlock(&ch
->cdma
.lock
);
73 pm_runtime_put(m
->dev
);
78 static void show_syncpts(struct host1x
*m
, struct output
*o
, bool show_all
)
80 unsigned long irqflags
;
81 struct list_head
*pos
;
85 host1x_debug_output(o
, "---- syncpts ----\n");
87 err
= pm_runtime_resume_and_get(m
->dev
);
91 for (i
= 0; i
< host1x_syncpt_nb_pts(m
); i
++) {
92 u32 max
= host1x_syncpt_read_max(m
->syncpt
+ i
);
93 u32 min
= host1x_syncpt_load(m
->syncpt
+ i
);
94 unsigned int waiters
= 0;
96 spin_lock_irqsave(&m
->syncpt
[i
].fences
.lock
, irqflags
);
97 list_for_each(pos
, &m
->syncpt
[i
].fences
.list
)
99 spin_unlock_irqrestore(&m
->syncpt
[i
].fences
.lock
, irqflags
);
101 if (!kref_read(&m
->syncpt
[i
].ref
))
104 if (!show_all
&& !min
&& !max
&& !waiters
)
107 host1x_debug_output(o
,
108 "id %u (%s) min %d max %d (%d waiters)\n",
109 i
, m
->syncpt
[i
].name
, min
, max
, waiters
);
112 for (i
= 0; i
< host1x_syncpt_nb_bases(m
); i
++) {
115 base_val
= host1x_syncpt_load_wait_base(m
->syncpt
+ i
);
117 host1x_debug_output(o
, "waitbase id %u val %d\n", i
,
121 pm_runtime_put(m
->dev
);
123 host1x_debug_output(o
, "\n");
126 static void show_all(struct host1x
*m
, struct output
*o
, bool show_fifo
)
130 host1x_hw_show_mlocks(m
, o
);
131 show_syncpts(m
, o
, true);
132 host1x_debug_output(o
, "---- channels ----\n");
134 for (i
= 0; i
< m
->info
->nb_channels
; ++i
) {
135 struct host1x_channel
*ch
= host1x_channel_get_index(m
, i
);
138 show_channel(ch
, o
, show_fifo
);
139 host1x_channel_put(ch
);
144 static int host1x_debug_all_show(struct seq_file
*s
, void *unused
)
147 .fn
= write_to_seqfile
,
151 show_all(s
->private, &o
, true);
155 DEFINE_SHOW_ATTRIBUTE(host1x_debug_all
);
157 static int host1x_debug_show(struct seq_file
*s
, void *unused
)
160 .fn
= write_to_seqfile
,
164 show_all(s
->private, &o
, false);
168 DEFINE_SHOW_ATTRIBUTE(host1x_debug
);
170 static void host1x_debugfs_init(struct host1x
*host1x
)
172 struct dentry
*de
= debugfs_create_dir("tegra-host1x", NULL
);
174 /* Store the created entry */
175 host1x
->debugfs
= de
;
177 debugfs_create_file("status", S_IRUGO
, de
, host1x
, &host1x_debug_fops
);
178 debugfs_create_file("status_all", S_IRUGO
, de
, host1x
,
179 &host1x_debug_all_fops
);
181 debugfs_create_u32("trace_cmdbuf", S_IRUGO
|S_IWUSR
, de
,
182 &host1x_debug_trace_cmdbuf
);
184 host1x_hw_debug_init(host1x
, de
);
186 debugfs_create_u32("force_timeout_pid", S_IRUGO
|S_IWUSR
, de
,
187 &host1x_debug_force_timeout_pid
);
188 debugfs_create_u32("force_timeout_val", S_IRUGO
|S_IWUSR
, de
,
189 &host1x_debug_force_timeout_val
);
190 debugfs_create_u32("force_timeout_channel", S_IRUGO
|S_IWUSR
, de
,
191 &host1x_debug_force_timeout_channel
);
194 static void host1x_debugfs_exit(struct host1x
*host1x
)
196 debugfs_remove_recursive(host1x
->debugfs
);
199 void host1x_debug_init(struct host1x
*host1x
)
201 if (IS_ENABLED(CONFIG_DEBUG_FS
))
202 host1x_debugfs_init(host1x
);
205 void host1x_debug_deinit(struct host1x
*host1x
)
207 if (IS_ENABLED(CONFIG_DEBUG_FS
))
208 host1x_debugfs_exit(host1x
);
211 void host1x_debug_dump(struct host1x
*host1x
)
214 .fn
= write_to_printk
217 show_all(host1x
, &o
, true);
220 void host1x_debug_dump_syncpts(struct host1x
*host1x
)
223 .fn
= write_to_printk
226 show_syncpts(host1x
, &o
, false);