]> Git Repo - linux.git/blob - drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux...
[linux.git] / drivers / gpu / drm / i915 / gt / uc / intel_guc_log_debugfs.c
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2020 Intel Corporation
4  */
5
6 #include <linux/fs.h>
7 #include <drm/drm_print.h>
8
9 #include "gt/intel_gt_debugfs.h"
10 #include "intel_guc.h"
11 #include "intel_guc_log.h"
12 #include "intel_guc_log_debugfs.h"
13 #include "intel_uc.h"
14
15 static u32 obj_to_guc_log_dump_size(struct drm_i915_gem_object *obj)
16 {
17         u32 size;
18
19         if (!obj)
20                 return PAGE_SIZE;
21
22         /* "0x%08x 0x%08x 0x%08x 0x%08x\n" => 16 bytes -> 44 chars => x2.75 */
23         size = ((obj->base.size * 11) + 3) / 4;
24
25         /* Add padding for final blank line, any extra header info, etc. */
26         size = PAGE_ALIGN(size + PAGE_SIZE);
27
28         return size;
29 }
30
31 static u32 guc_log_dump_size(struct intel_guc_log *log)
32 {
33         struct intel_guc *guc = log_to_guc(log);
34
35         if (!intel_guc_is_supported(guc))
36                 return PAGE_SIZE;
37
38         if (!log->vma)
39                 return PAGE_SIZE;
40
41         return obj_to_guc_log_dump_size(log->vma->obj);
42 }
43
44 static int guc_log_dump_show(struct seq_file *m, void *data)
45 {
46         struct drm_printer p = drm_seq_file_printer(m);
47         int ret;
48
49         ret = intel_guc_log_dump(m->private, &p, false);
50
51         if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) && seq_has_overflowed(m))
52                 pr_warn_once("preallocated size:%zx for %s exceeded\n",
53                              m->size, __func__);
54
55         return ret;
56 }
57 DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE_WITH_SIZE(guc_log_dump, guc_log_dump_size);
58
59 static u32 guc_load_err_dump_size(struct intel_guc_log *log)
60 {
61         struct intel_guc *guc = log_to_guc(log);
62         struct intel_uc *uc = container_of(guc, struct intel_uc, guc);
63
64         if (!intel_guc_is_supported(guc))
65                 return PAGE_SIZE;
66
67         return obj_to_guc_log_dump_size(uc->load_err_log);
68 }
69
70 static int guc_load_err_log_dump_show(struct seq_file *m, void *data)
71 {
72         struct drm_printer p = drm_seq_file_printer(m);
73
74         if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) && seq_has_overflowed(m))
75                 pr_warn_once("preallocated size:%zx for %s exceeded\n",
76                              m->size, __func__);
77
78         return intel_guc_log_dump(m->private, &p, true);
79 }
80 DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE_WITH_SIZE(guc_load_err_log_dump, guc_load_err_dump_size);
81
82 static int guc_log_level_get(void *data, u64 *val)
83 {
84         struct intel_guc_log *log = data;
85
86         if (!log->vma)
87                 return -ENODEV;
88
89         *val = intel_guc_log_get_level(log);
90
91         return 0;
92 }
93
94 static int guc_log_level_set(void *data, u64 val)
95 {
96         struct intel_guc_log *log = data;
97
98         if (!log->vma)
99                 return -ENODEV;
100
101         return intel_guc_log_set_level(log, val);
102 }
103
104 DEFINE_SIMPLE_ATTRIBUTE(guc_log_level_fops,
105                         guc_log_level_get, guc_log_level_set,
106                         "%lld\n");
107
108 static int guc_log_relay_open(struct inode *inode, struct file *file)
109 {
110         struct intel_guc_log *log = inode->i_private;
111
112         if (!intel_guc_is_ready(log_to_guc(log)))
113                 return -ENODEV;
114
115         file->private_data = log;
116
117         return intel_guc_log_relay_open(log);
118 }
119
120 static ssize_t
121 guc_log_relay_write(struct file *filp,
122                     const char __user *ubuf,
123                     size_t cnt,
124                     loff_t *ppos)
125 {
126         struct intel_guc_log *log = filp->private_data;
127         int val;
128         int ret;
129
130         ret = kstrtoint_from_user(ubuf, cnt, 0, &val);
131         if (ret < 0)
132                 return ret;
133
134         /*
135          * Enable and start the guc log relay on value of 1.
136          * Flush log relay for any other value.
137          */
138         if (val == 1)
139                 ret = intel_guc_log_relay_start(log);
140         else
141                 intel_guc_log_relay_flush(log);
142
143         return ret ?: cnt;
144 }
145
146 static int guc_log_relay_release(struct inode *inode, struct file *file)
147 {
148         struct intel_guc_log *log = inode->i_private;
149
150         intel_guc_log_relay_close(log);
151         return 0;
152 }
153
154 static const struct file_operations guc_log_relay_fops = {
155         .owner = THIS_MODULE,
156         .open = guc_log_relay_open,
157         .write = guc_log_relay_write,
158         .release = guc_log_relay_release,
159 };
160
161 void intel_guc_log_debugfs_register(struct intel_guc_log *log,
162                                     struct dentry *root)
163 {
164         static const struct intel_gt_debugfs_file files[] = {
165                 { "guc_log_dump", &guc_log_dump_fops, NULL },
166                 { "guc_load_err_log_dump", &guc_load_err_log_dump_fops, NULL },
167                 { "guc_log_level", &guc_log_level_fops, NULL },
168                 { "guc_log_relay", &guc_log_relay_fops, NULL },
169         };
170
171         if (!intel_guc_is_supported(log_to_guc(log)))
172                 return;
173
174         intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), log);
175 }
This page took 0.039698 seconds and 4 git commands to generate.