| .. | .. |
|---|
| 26 | 26 | #define DEBUG /* for pr_debug() */ |
|---|
| 27 | 27 | |
|---|
| 28 | 28 | #include <stdarg.h> |
|---|
| 29 | + |
|---|
| 30 | +#include <linux/io.h> |
|---|
| 31 | +#include <linux/moduleparam.h> |
|---|
| 29 | 32 | #include <linux/seq_file.h> |
|---|
| 30 | | -#include <drm/drmP.h> |
|---|
| 33 | +#include <linux/slab.h> |
|---|
| 34 | + |
|---|
| 35 | +#include <drm/drm.h> |
|---|
| 36 | +#include <drm/drm_drv.h> |
|---|
| 31 | 37 | #include <drm/drm_print.h> |
|---|
| 38 | + |
|---|
| 39 | +/* |
|---|
| 40 | + * __drm_debug: Enable debug output. |
|---|
| 41 | + * Bitmask of DRM_UT_x. See include/drm/drm_print.h for details. |
|---|
| 42 | + */ |
|---|
| 43 | +unsigned int __drm_debug; |
|---|
| 44 | +EXPORT_SYMBOL(__drm_debug); |
|---|
| 45 | + |
|---|
| 46 | +MODULE_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)"); |
|---|
| 55 | +module_param_named(debug, __drm_debug, int, 0600); |
|---|
| 32 | 56 | |
|---|
| 33 | 57 | void __drm_puts_coredump(struct drm_printer *p, const char *str) |
|---|
| 34 | 58 | { |
|---|
| .. | .. |
|---|
| 142 | 166 | } |
|---|
| 143 | 167 | EXPORT_SYMBOL(__drm_printfn_debug); |
|---|
| 144 | 168 | |
|---|
| 169 | +void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf) |
|---|
| 170 | +{ |
|---|
| 171 | + pr_err("*ERROR* %s %pV", p->prefix, vaf); |
|---|
| 172 | +} |
|---|
| 173 | +EXPORT_SYMBOL(__drm_printfn_err); |
|---|
| 174 | + |
|---|
| 145 | 175 | /** |
|---|
| 146 | 176 | * drm_puts - print a const string to a &drm_printer stream |
|---|
| 147 | 177 | * @p: the &drm printer |
|---|
| .. | .. |
|---|
| 174 | 204 | } |
|---|
| 175 | 205 | EXPORT_SYMBOL(drm_printf); |
|---|
| 176 | 206 | |
|---|
| 207 | +/** |
|---|
| 208 | + * drm_print_bits - print bits to a &drm_printer stream |
|---|
| 209 | + * |
|---|
| 210 | + * Print bits (in flag fields for example) in human readable form. |
|---|
| 211 | + * |
|---|
| 212 | + * @p: the &drm_printer |
|---|
| 213 | + * @value: field value. |
|---|
| 214 | + * @bits: Array with bit names. |
|---|
| 215 | + * @nbits: Size of bit names array. |
|---|
| 216 | + */ |
|---|
| 217 | +void 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 | +} |
|---|
| 236 | +EXPORT_SYMBOL(drm_print_bits); |
|---|
| 237 | + |
|---|
| 177 | 238 | void drm_dev_printk(const struct device *dev, const char *level, |
|---|
| 178 | 239 | const char *format, ...) |
|---|
| 179 | 240 | { |
|---|
| .. | .. |
|---|
| 195 | 256 | } |
|---|
| 196 | 257 | EXPORT_SYMBOL(drm_dev_printk); |
|---|
| 197 | 258 | |
|---|
| 198 | | -void drm_dev_dbg(const struct device *dev, unsigned int category, |
|---|
| 259 | +void drm_dev_dbg(const struct device *dev, enum drm_debug_category category, |
|---|
| 199 | 260 | const char *format, ...) |
|---|
| 200 | 261 | { |
|---|
| 201 | 262 | struct va_format vaf; |
|---|
| 202 | 263 | va_list args; |
|---|
| 203 | 264 | |
|---|
| 204 | | - if (!(drm_debug & category)) |
|---|
| 265 | + if (!drm_debug_enabled(category)) |
|---|
| 205 | 266 | return; |
|---|
| 206 | 267 | |
|---|
| 207 | 268 | va_start(args, format); |
|---|
| .. | .. |
|---|
| 219 | 280 | } |
|---|
| 220 | 281 | EXPORT_SYMBOL(drm_dev_dbg); |
|---|
| 221 | 282 | |
|---|
| 222 | | -void drm_dbg(unsigned int category, const char *format, ...) |
|---|
| 283 | +void __drm_dbg(enum drm_debug_category category, const char *format, ...) |
|---|
| 223 | 284 | { |
|---|
| 224 | 285 | struct va_format vaf; |
|---|
| 225 | 286 | va_list args; |
|---|
| 226 | 287 | |
|---|
| 227 | | - if (!(drm_debug & category)) |
|---|
| 288 | + if (!drm_debug_enabled(category)) |
|---|
| 228 | 289 | return; |
|---|
| 229 | 290 | |
|---|
| 230 | 291 | va_start(args, format); |
|---|
| .. | .. |
|---|
| 236 | 297 | |
|---|
| 237 | 298 | va_end(args); |
|---|
| 238 | 299 | } |
|---|
| 239 | | -EXPORT_SYMBOL(drm_dbg); |
|---|
| 300 | +EXPORT_SYMBOL(__drm_dbg); |
|---|
| 240 | 301 | |
|---|
| 241 | | -void drm_err(const char *format, ...) |
|---|
| 302 | +void __drm_err(const char *format, ...) |
|---|
| 242 | 303 | { |
|---|
| 243 | 304 | struct va_format vaf; |
|---|
| 244 | 305 | va_list args; |
|---|
| .. | .. |
|---|
| 252 | 313 | |
|---|
| 253 | 314 | va_end(args); |
|---|
| 254 | 315 | } |
|---|
| 255 | | -EXPORT_SYMBOL(drm_err); |
|---|
| 316 | +EXPORT_SYMBOL(__drm_err); |
|---|
| 317 | + |
|---|
| 318 | +/** |
|---|
| 319 | + * drm_print_regset32 - print the contents of registers to a |
|---|
| 320 | + * &drm_printer stream. |
|---|
| 321 | + * |
|---|
| 322 | + * @p: the &drm printer |
|---|
| 323 | + * @regset: the list of registers to print. |
|---|
| 324 | + * |
|---|
| 325 | + * Often in driver debug, it's useful to be able to either capture the |
|---|
| 326 | + * contents of registers in the steady state using debugfs or at |
|---|
| 327 | + * specific points during operation. This lets the driver have a |
|---|
| 328 | + * single list of registers for both. |
|---|
| 329 | + */ |
|---|
| 330 | +void 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 | +} |
|---|
| 344 | +EXPORT_SYMBOL(drm_print_regset32); |
|---|