1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#define DEBUG
27
28#include <stdarg.h>
29
30#include <linux/io.h>
31#include <linux/moduleparam.h>
32#include <linux/seq_file.h>
33#include <linux/slab.h>
34
35#include <drm/drm.h>
36#include <drm/drm_drv.h>
37#include <drm/drm_print.h>
38
39
40
41
42
43unsigned int __drm_debug;
44EXPORT_SYMBOL(__drm_debug);
45
46MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug category.\n"
47"\t\tBit 0 (0x01) will enable CORE messages (drm core code)\n"
48"\t\tBit 1 (0x02) will enable DRIVER messages (drm controller code)\n"
49"\t\tBit 2 (0x04) will enable KMS messages (modesetting code)\n"
50"\t\tBit 3 (0x08) will enable PRIME messages (prime code)\n"
51"\t\tBit 4 (0x10) will enable ATOMIC messages (atomic code)\n"
52"\t\tBit 5 (0x20) will enable VBL messages (vblank code)\n"
53"\t\tBit 7 (0x80) will enable LEASE messages (leasing code)\n"
54"\t\tBit 8 (0x100) will enable DP messages (displayport code)");
55module_param_named(debug, __drm_debug, int, 0600);
56
57void __drm_puts_coredump(struct drm_printer *p, const char *str)
58{
59 struct drm_print_iterator *iterator = p->arg;
60 ssize_t len;
61
62 if (!iterator->remain)
63 return;
64
65 if (iterator->offset < iterator->start) {
66 ssize_t copy;
67
68 len = strlen(str);
69
70 if (iterator->offset + len <= iterator->start) {
71 iterator->offset += len;
72 return;
73 }
74
75 copy = len - (iterator->start - iterator->offset);
76
77 if (copy > iterator->remain)
78 copy = iterator->remain;
79
80
81 memcpy(iterator->data,
82 str + (iterator->start - iterator->offset), copy);
83
84 iterator->offset = iterator->start + copy;
85 iterator->remain -= copy;
86 } else {
87 ssize_t pos = iterator->offset - iterator->start;
88
89 len = min_t(ssize_t, strlen(str), iterator->remain);
90
91 memcpy(iterator->data + pos, str, len);
92
93 iterator->offset += len;
94 iterator->remain -= len;
95 }
96}
97EXPORT_SYMBOL(__drm_puts_coredump);
98
99void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)
100{
101 struct drm_print_iterator *iterator = p->arg;
102 size_t len;
103 char *buf;
104
105 if (!iterator->remain)
106 return;
107
108
109 len = snprintf(NULL, 0, "%pV", vaf);
110
111
112 if (iterator->offset + len <= iterator->start) {
113 iterator->offset += len;
114 return;
115 }
116
117
118 if ((iterator->offset >= iterator->start) && (len < iterator->remain)) {
119 ssize_t pos = iterator->offset - iterator->start;
120
121 snprintf(((char *) iterator->data) + pos,
122 iterator->remain, "%pV", vaf);
123
124 iterator->offset += len;
125 iterator->remain -= len;
126
127 return;
128 }
129
130
131
132
133
134 buf = kmalloc(len + 1, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
135 if (!buf)
136 return;
137
138 snprintf(buf, len + 1, "%pV", vaf);
139 __drm_puts_coredump(p, (const char *) buf);
140
141 kfree(buf);
142}
143EXPORT_SYMBOL(__drm_printfn_coredump);
144
145void __drm_puts_seq_file(struct drm_printer *p, const char *str)
146{
147 seq_puts(p->arg, str);
148}
149EXPORT_SYMBOL(__drm_puts_seq_file);
150
151void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf)
152{
153 seq_printf(p->arg, "%pV", vaf);
154}
155EXPORT_SYMBOL(__drm_printfn_seq_file);
156
157void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf)
158{
159 dev_info(p->arg, "[" DRM_NAME "] %pV", vaf);
160}
161EXPORT_SYMBOL(__drm_printfn_info);
162
163void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf)
164{
165 pr_debug("%s %pV", p->prefix, vaf);
166}
167EXPORT_SYMBOL(__drm_printfn_debug);
168
169void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf)
170{
171 pr_err("*ERROR* %s %pV", p->prefix, vaf);
172}
173EXPORT_SYMBOL(__drm_printfn_err);
174
175
176
177
178
179
180
181
182
183void drm_puts(struct drm_printer *p, const char *str)
184{
185 if (p->puts)
186 p->puts(p, str);
187 else
188 drm_printf(p, "%s", str);
189}
190EXPORT_SYMBOL(drm_puts);
191
192
193
194
195
196
197void drm_printf(struct drm_printer *p, const char *f, ...)
198{
199 va_list args;
200
201 va_start(args, f);
202 drm_vprintf(p, f, &args);
203 va_end(args);
204}
205EXPORT_SYMBOL(drm_printf);
206
207
208
209
210
211
212
213
214
215
216
217void drm_print_bits(struct drm_printer *p, unsigned long value,
218 const char * const bits[], unsigned int nbits)
219{
220 bool first = true;
221 unsigned int i;
222
223 if (WARN_ON_ONCE(nbits > BITS_PER_TYPE(value)))
224 nbits = BITS_PER_TYPE(value);
225
226 for_each_set_bit(i, &value, nbits) {
227 if (WARN_ON_ONCE(!bits[i]))
228 continue;
229 drm_printf(p, "%s%s", first ? "" : ",",
230 bits[i]);
231 first = false;
232 }
233 if (first)
234 drm_printf(p, "(none)");
235}
236EXPORT_SYMBOL(drm_print_bits);
237
238void drm_dev_printk(const struct device *dev, const char *level,
239 const char *format, ...)
240{
241 struct va_format vaf;
242 va_list args;
243
244 va_start(args, format);
245 vaf.fmt = format;
246 vaf.va = &args;
247
248 if (dev)
249 dev_printk(level, dev, "[" DRM_NAME ":%ps] %pV",
250 __builtin_return_address(0), &vaf);
251 else
252 printk("%s" "[" DRM_NAME ":%ps] %pV",
253 level, __builtin_return_address(0), &vaf);
254
255 va_end(args);
256}
257EXPORT_SYMBOL(drm_dev_printk);
258
259void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
260 const char *format, ...)
261{
262 struct va_format vaf;
263 va_list args;
264
265 if (!drm_debug_enabled(category))
266 return;
267
268 va_start(args, format);
269 vaf.fmt = format;
270 vaf.va = &args;
271
272 if (dev)
273 dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV",
274 __builtin_return_address(0), &vaf);
275 else
276 printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
277 __builtin_return_address(0), &vaf);
278
279 va_end(args);
280}
281EXPORT_SYMBOL(drm_dev_dbg);
282
283void __drm_dbg(enum drm_debug_category category, const char *format, ...)
284{
285 struct va_format vaf;
286 va_list args;
287
288 if (!drm_debug_enabled(category))
289 return;
290
291 va_start(args, format);
292 vaf.fmt = format;
293 vaf.va = &args;
294
295 printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
296 __builtin_return_address(0), &vaf);
297
298 va_end(args);
299}
300EXPORT_SYMBOL(__drm_dbg);
301
302void __drm_err(const char *format, ...)
303{
304 struct va_format vaf;
305 va_list args;
306
307 va_start(args, format);
308 vaf.fmt = format;
309 vaf.va = &args;
310
311 printk(KERN_ERR "[" DRM_NAME ":%ps] *ERROR* %pV",
312 __builtin_return_address(0), &vaf);
313
314 va_end(args);
315}
316EXPORT_SYMBOL(__drm_err);
317
318
319
320
321
322
323
324
325
326
327
328
329
330void drm_print_regset32(struct drm_printer *p, struct debugfs_regset32 *regset)
331{
332 int namelen = 0;
333 int i;
334
335 for (i = 0; i < regset->nregs; i++)
336 namelen = max(namelen, (int)strlen(regset->regs[i].name));
337
338 for (i = 0; i < regset->nregs; i++) {
339 drm_printf(p, "%*s = 0x%08x\n",
340 namelen, regset->regs[i].name,
341 readl(regset->base + regset->regs[i].offset));
342 }
343}
344EXPORT_SYMBOL(drm_print_regset32);
345