Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2020-2023 Intel Corporation
4 */
5
6#include <drm/drm_debugfs.h>
7#include <drm/drm_file.h>
8#include <drm/drm_print.h>
9
10#include <uapi/drm/ivpu_accel.h>
11
12#include "ivpu_debugfs.h"
13#include "ivpu_drv.h"
14#include "ivpu_fw.h"
15#include "ivpu_fw_log.h"
16#include "ivpu_gem.h"
17#include "ivpu_jsm_msg.h"
18#include "ivpu_pm.h"
19
20static inline struct ivpu_device *seq_to_ivpu(struct seq_file *s)
21{
22 struct drm_debugfs_entry *entry = s->private;
23
24 return to_ivpu_device(entry->dev);
25}
26
27static int bo_list_show(struct seq_file *s, void *v)
28{
29 struct drm_printer p = drm_seq_file_printer(s);
30 struct ivpu_device *vdev = seq_to_ivpu(s);
31
32 ivpu_bo_list(&vdev->drm, &p);
33
34 return 0;
35}
36
37static int fw_name_show(struct seq_file *s, void *v)
38{
39 struct ivpu_device *vdev = seq_to_ivpu(s);
40
41 seq_printf(s, "%s\n", vdev->fw->name);
42 return 0;
43}
44
45static int fw_trace_capability_show(struct seq_file *s, void *v)
46{
47 struct ivpu_device *vdev = seq_to_ivpu(s);
48 u64 trace_hw_component_mask;
49 u32 trace_destination_mask;
50 int ret;
51
52 ret = ivpu_jsm_trace_get_capability(vdev, &trace_destination_mask,
53 &trace_hw_component_mask);
54 if (!ret) {
55 seq_printf(s,
56 "trace_destination_mask: %#18x\n"
57 "trace_hw_component_mask: %#18llx\n",
58 trace_destination_mask, trace_hw_component_mask);
59 }
60 return 0;
61}
62
63static int fw_trace_config_show(struct seq_file *s, void *v)
64{
65 struct ivpu_device *vdev = seq_to_ivpu(s);
66 /**
67 * WA: VPU_JSM_MSG_TRACE_GET_CONFIG command is not working yet,
68 * so we use values from vdev->fw instead of calling ivpu_jsm_trace_get_config()
69 */
70 u32 trace_level = vdev->fw->trace_level;
71 u32 trace_destination_mask = vdev->fw->trace_destination_mask;
72 u64 trace_hw_component_mask = vdev->fw->trace_hw_component_mask;
73
74 seq_printf(s,
75 "trace_level: %#18x\n"
76 "trace_destination_mask: %#18x\n"
77 "trace_hw_component_mask: %#18llx\n",
78 trace_level, trace_destination_mask, trace_hw_component_mask);
79
80 return 0;
81}
82
83static int last_bootmode_show(struct seq_file *s, void *v)
84{
85 struct ivpu_device *vdev = seq_to_ivpu(s);
86
87 seq_printf(s, "%s\n", (vdev->pm->is_warmboot) ? "warmboot" : "coldboot");
88
89 return 0;
90}
91
92static int reset_counter_show(struct seq_file *s, void *v)
93{
94 struct ivpu_device *vdev = seq_to_ivpu(s);
95
96 seq_printf(s, "%d\n", atomic_read(&vdev->pm->reset_counter));
97 return 0;
98}
99
100static int reset_pending_show(struct seq_file *s, void *v)
101{
102 struct ivpu_device *vdev = seq_to_ivpu(s);
103
104 seq_printf(s, "%d\n", atomic_read(&vdev->pm->in_reset));
105 return 0;
106}
107
108static const struct drm_debugfs_info vdev_debugfs_list[] = {
109 {"bo_list", bo_list_show, 0},
110 {"fw_name", fw_name_show, 0},
111 {"fw_trace_capability", fw_trace_capability_show, 0},
112 {"fw_trace_config", fw_trace_config_show, 0},
113 {"last_bootmode", last_bootmode_show, 0},
114 {"reset_counter", reset_counter_show, 0},
115 {"reset_pending", reset_pending_show, 0},
116};
117
118static int fw_log_show(struct seq_file *s, void *v)
119{
120 struct ivpu_device *vdev = s->private;
121 struct drm_printer p = drm_seq_file_printer(s);
122
123 ivpu_fw_log_print(vdev, true, &p);
124 return 0;
125}
126
127static int fw_log_fops_open(struct inode *inode, struct file *file)
128{
129 return single_open(file, fw_log_show, inode->i_private);
130}
131
132static ssize_t
133fw_log_fops_write(struct file *file, const char __user *user_buf, size_t size, loff_t *pos)
134{
135 struct seq_file *s = file->private_data;
136 struct ivpu_device *vdev = s->private;
137
138 if (!size)
139 return -EINVAL;
140
141 ivpu_fw_log_clear(vdev);
142 return size;
143}
144
145static const struct file_operations fw_log_fops = {
146 .owner = THIS_MODULE,
147 .open = fw_log_fops_open,
148 .write = fw_log_fops_write,
149 .read = seq_read,
150 .llseek = seq_lseek,
151 .release = single_release,
152};
153
154static ssize_t
155fw_trace_destination_mask_fops_write(struct file *file, const char __user *user_buf,
156 size_t size, loff_t *pos)
157{
158 struct ivpu_device *vdev = file->private_data;
159 struct ivpu_fw_info *fw = vdev->fw;
160 u32 trace_destination_mask;
161 int ret;
162
163 ret = kstrtou32_from_user(user_buf, size, 0, &trace_destination_mask);
164 if (ret < 0)
165 return ret;
166
167 fw->trace_destination_mask = trace_destination_mask;
168
169 ivpu_jsm_trace_set_config(vdev, fw->trace_level, trace_destination_mask,
170 fw->trace_hw_component_mask);
171
172 return size;
173}
174
175static const struct file_operations fw_trace_destination_mask_fops = {
176 .owner = THIS_MODULE,
177 .open = simple_open,
178 .write = fw_trace_destination_mask_fops_write,
179};
180
181static ssize_t
182fw_trace_hw_comp_mask_fops_write(struct file *file, const char __user *user_buf,
183 size_t size, loff_t *pos)
184{
185 struct ivpu_device *vdev = file->private_data;
186 struct ivpu_fw_info *fw = vdev->fw;
187 u64 trace_hw_component_mask;
188 int ret;
189
190 ret = kstrtou64_from_user(user_buf, size, 0, &trace_hw_component_mask);
191 if (ret < 0)
192 return ret;
193
194 fw->trace_hw_component_mask = trace_hw_component_mask;
195
196 ivpu_jsm_trace_set_config(vdev, fw->trace_level, fw->trace_destination_mask,
197 trace_hw_component_mask);
198
199 return size;
200}
201
202static const struct file_operations fw_trace_hw_comp_mask_fops = {
203 .owner = THIS_MODULE,
204 .open = simple_open,
205 .write = fw_trace_hw_comp_mask_fops_write,
206};
207
208static ssize_t
209fw_trace_level_fops_write(struct file *file, const char __user *user_buf, size_t size, loff_t *pos)
210{
211 struct ivpu_device *vdev = file->private_data;
212 struct ivpu_fw_info *fw = vdev->fw;
213 u32 trace_level;
214 int ret;
215
216 ret = kstrtou32_from_user(user_buf, size, 0, &trace_level);
217 if (ret < 0)
218 return ret;
219
220 fw->trace_level = trace_level;
221
222 ivpu_jsm_trace_set_config(vdev, trace_level, fw->trace_destination_mask,
223 fw->trace_hw_component_mask);
224
225 return size;
226}
227
228static const struct file_operations fw_trace_level_fops = {
229 .owner = THIS_MODULE,
230 .open = simple_open,
231 .write = fw_trace_level_fops_write,
232};
233
234static ssize_t
235ivpu_reset_engine_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos)
236{
237 struct ivpu_device *vdev = file->private_data;
238
239 if (!size)
240 return -EINVAL;
241
242 if (ivpu_jsm_reset_engine(vdev, DRM_IVPU_ENGINE_COMPUTE))
243 return -ENODEV;
244 if (ivpu_jsm_reset_engine(vdev, DRM_IVPU_ENGINE_COPY))
245 return -ENODEV;
246
247 return size;
248}
249
250static ssize_t
251ivpu_force_recovery_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos)
252{
253 struct ivpu_device *vdev = file->private_data;
254
255 if (!size)
256 return -EINVAL;
257
258 ivpu_pm_schedule_recovery(vdev);
259 return size;
260}
261
262static const struct file_operations ivpu_force_recovery_fops = {
263 .owner = THIS_MODULE,
264 .open = simple_open,
265 .write = ivpu_force_recovery_fn,
266};
267
268static const struct file_operations ivpu_reset_engine_fops = {
269 .owner = THIS_MODULE,
270 .open = simple_open,
271 .write = ivpu_reset_engine_fn,
272};
273
274void ivpu_debugfs_init(struct ivpu_device *vdev)
275{
276 struct dentry *debugfs_root = vdev->drm.debugfs_root;
277
278 drm_debugfs_add_files(&vdev->drm, vdev_debugfs_list, ARRAY_SIZE(vdev_debugfs_list));
279
280 debugfs_create_file("force_recovery", 0200, debugfs_root, vdev,
281 &ivpu_force_recovery_fops);
282
283 debugfs_create_file("fw_log", 0644, debugfs_root, vdev,
284 &fw_log_fops);
285 debugfs_create_file("fw_trace_destination_mask", 0200, debugfs_root, vdev,
286 &fw_trace_destination_mask_fops);
287 debugfs_create_file("fw_trace_hw_comp_mask", 0200, debugfs_root, vdev,
288 &fw_trace_hw_comp_mask_fops);
289 debugfs_create_file("fw_trace_level", 0200, debugfs_root, vdev,
290 &fw_trace_level_fops);
291
292 debugfs_create_file("reset_engine", 0200, debugfs_root, vdev,
293 &ivpu_reset_engine_fops);
294}