18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (C) 2016 Red Hat 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 58c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 68c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation 78c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 88c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 98c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 128c2ecf20Sopenharmony_ci * all copies or substantial portions of the Software. 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 158c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 168c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 178c2ecf20Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 188c2ecf20Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 198c2ecf20Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 208c2ecf20Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * Authors: 238c2ecf20Sopenharmony_ci * Rob Clark <robdclark@gmail.com> 248c2ecf20Sopenharmony_ci */ 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#ifndef DRM_PRINT_H_ 278c2ecf20Sopenharmony_ci#define DRM_PRINT_H_ 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#include <linux/compiler.h> 308c2ecf20Sopenharmony_ci#include <linux/printk.h> 318c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 328c2ecf20Sopenharmony_ci#include <linux/device.h> 338c2ecf20Sopenharmony_ci#include <linux/debugfs.h> 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#include <drm/drm.h> 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* Do *not* use outside of drm_print.[ch]! */ 388c2ecf20Sopenharmony_ciextern unsigned int __drm_debug; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/** 418c2ecf20Sopenharmony_ci * DOC: print 428c2ecf20Sopenharmony_ci * 438c2ecf20Sopenharmony_ci * A simple wrapper for dev_printk(), seq_printf(), etc. Allows same 448c2ecf20Sopenharmony_ci * debug code to be used for both debugfs and printk logging. 458c2ecf20Sopenharmony_ci * 468c2ecf20Sopenharmony_ci * For example:: 478c2ecf20Sopenharmony_ci * 488c2ecf20Sopenharmony_ci * void log_some_info(struct drm_printer *p) 498c2ecf20Sopenharmony_ci * { 508c2ecf20Sopenharmony_ci * drm_printf(p, "foo=%d\n", foo); 518c2ecf20Sopenharmony_ci * drm_printf(p, "bar=%d\n", bar); 528c2ecf20Sopenharmony_ci * } 538c2ecf20Sopenharmony_ci * 548c2ecf20Sopenharmony_ci * #ifdef CONFIG_DEBUG_FS 558c2ecf20Sopenharmony_ci * void debugfs_show(struct seq_file *f) 568c2ecf20Sopenharmony_ci * { 578c2ecf20Sopenharmony_ci * struct drm_printer p = drm_seq_file_printer(f); 588c2ecf20Sopenharmony_ci * log_some_info(&p); 598c2ecf20Sopenharmony_ci * } 608c2ecf20Sopenharmony_ci * #endif 618c2ecf20Sopenharmony_ci * 628c2ecf20Sopenharmony_ci * void some_other_function(...) 638c2ecf20Sopenharmony_ci * { 648c2ecf20Sopenharmony_ci * struct drm_printer p = drm_info_printer(drm->dev); 658c2ecf20Sopenharmony_ci * log_some_info(&p); 668c2ecf20Sopenharmony_ci * } 678c2ecf20Sopenharmony_ci */ 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci/** 708c2ecf20Sopenharmony_ci * struct drm_printer - drm output "stream" 718c2ecf20Sopenharmony_ci * 728c2ecf20Sopenharmony_ci * Do not use struct members directly. Use drm_printer_seq_file(), 738c2ecf20Sopenharmony_ci * drm_printer_info(), etc to initialize. And drm_printf() for output. 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_cistruct drm_printer { 768c2ecf20Sopenharmony_ci /* private: */ 778c2ecf20Sopenharmony_ci void (*printfn)(struct drm_printer *p, struct va_format *vaf); 788c2ecf20Sopenharmony_ci void (*puts)(struct drm_printer *p, const char *str); 798c2ecf20Sopenharmony_ci void *arg; 808c2ecf20Sopenharmony_ci const char *prefix; 818c2ecf20Sopenharmony_ci}; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_civoid __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf); 848c2ecf20Sopenharmony_civoid __drm_puts_coredump(struct drm_printer *p, const char *str); 858c2ecf20Sopenharmony_civoid __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf); 868c2ecf20Sopenharmony_civoid __drm_puts_seq_file(struct drm_printer *p, const char *str); 878c2ecf20Sopenharmony_civoid __drm_printfn_info(struct drm_printer *p, struct va_format *vaf); 888c2ecf20Sopenharmony_civoid __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf); 898c2ecf20Sopenharmony_civoid __drm_printfn_err(struct drm_printer *p, struct va_format *vaf); 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci__printf(2, 3) 928c2ecf20Sopenharmony_civoid drm_printf(struct drm_printer *p, const char *f, ...); 938c2ecf20Sopenharmony_civoid drm_puts(struct drm_printer *p, const char *str); 948c2ecf20Sopenharmony_civoid drm_print_regset32(struct drm_printer *p, struct debugfs_regset32 *regset); 958c2ecf20Sopenharmony_civoid drm_print_bits(struct drm_printer *p, unsigned long value, 968c2ecf20Sopenharmony_ci const char * const bits[], unsigned int nbits); 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci__printf(2, 0) 998c2ecf20Sopenharmony_ci/** 1008c2ecf20Sopenharmony_ci * drm_vprintf - print to a &drm_printer stream 1018c2ecf20Sopenharmony_ci * @p: the &drm_printer 1028c2ecf20Sopenharmony_ci * @fmt: format string 1038c2ecf20Sopenharmony_ci * @va: the va_list 1048c2ecf20Sopenharmony_ci */ 1058c2ecf20Sopenharmony_cistatic inline void 1068c2ecf20Sopenharmony_cidrm_vprintf(struct drm_printer *p, const char *fmt, va_list *va) 1078c2ecf20Sopenharmony_ci{ 1088c2ecf20Sopenharmony_ci struct va_format vaf = { .fmt = fmt, .va = va }; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci p->printfn(p, &vaf); 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci/** 1148c2ecf20Sopenharmony_ci * drm_printf_indent - Print to a &drm_printer stream with indentation 1158c2ecf20Sopenharmony_ci * @printer: DRM printer 1168c2ecf20Sopenharmony_ci * @indent: Tab indentation level (max 5) 1178c2ecf20Sopenharmony_ci * @fmt: Format string 1188c2ecf20Sopenharmony_ci */ 1198c2ecf20Sopenharmony_ci#define drm_printf_indent(printer, indent, fmt, ...) \ 1208c2ecf20Sopenharmony_ci drm_printf((printer), "%.*s" fmt, (indent), "\t\t\t\t\tX", ##__VA_ARGS__) 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci/** 1238c2ecf20Sopenharmony_ci * struct drm_print_iterator - local struct used with drm_printer_coredump 1248c2ecf20Sopenharmony_ci * @data: Pointer to the devcoredump output buffer 1258c2ecf20Sopenharmony_ci * @start: The offset within the buffer to start writing 1268c2ecf20Sopenharmony_ci * @remain: The number of bytes to write for this iteration 1278c2ecf20Sopenharmony_ci */ 1288c2ecf20Sopenharmony_cistruct drm_print_iterator { 1298c2ecf20Sopenharmony_ci void *data; 1308c2ecf20Sopenharmony_ci ssize_t start; 1318c2ecf20Sopenharmony_ci ssize_t remain; 1328c2ecf20Sopenharmony_ci /* private: */ 1338c2ecf20Sopenharmony_ci ssize_t offset; 1348c2ecf20Sopenharmony_ci}; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci/** 1378c2ecf20Sopenharmony_ci * drm_coredump_printer - construct a &drm_printer that can output to a buffer 1388c2ecf20Sopenharmony_ci * from the read function for devcoredump 1398c2ecf20Sopenharmony_ci * @iter: A pointer to a struct drm_print_iterator for the read instance 1408c2ecf20Sopenharmony_ci * 1418c2ecf20Sopenharmony_ci * This wrapper extends drm_printf() to work with a dev_coredumpm() callback 1428c2ecf20Sopenharmony_ci * function. The passed in drm_print_iterator struct contains the buffer 1438c2ecf20Sopenharmony_ci * pointer, size and offset as passed in from devcoredump. 1448c2ecf20Sopenharmony_ci * 1458c2ecf20Sopenharmony_ci * For example:: 1468c2ecf20Sopenharmony_ci * 1478c2ecf20Sopenharmony_ci * void coredump_read(char *buffer, loff_t offset, size_t count, 1488c2ecf20Sopenharmony_ci * void *data, size_t datalen) 1498c2ecf20Sopenharmony_ci * { 1508c2ecf20Sopenharmony_ci * struct drm_print_iterator iter; 1518c2ecf20Sopenharmony_ci * struct drm_printer p; 1528c2ecf20Sopenharmony_ci * 1538c2ecf20Sopenharmony_ci * iter.data = buffer; 1548c2ecf20Sopenharmony_ci * iter.start = offset; 1558c2ecf20Sopenharmony_ci * iter.remain = count; 1568c2ecf20Sopenharmony_ci * 1578c2ecf20Sopenharmony_ci * p = drm_coredump_printer(&iter); 1588c2ecf20Sopenharmony_ci * 1598c2ecf20Sopenharmony_ci * drm_printf(p, "foo=%d\n", foo); 1608c2ecf20Sopenharmony_ci * } 1618c2ecf20Sopenharmony_ci * 1628c2ecf20Sopenharmony_ci * void makecoredump(...) 1638c2ecf20Sopenharmony_ci * { 1648c2ecf20Sopenharmony_ci * ... 1658c2ecf20Sopenharmony_ci * dev_coredumpm(dev, THIS_MODULE, data, 0, GFP_KERNEL, 1668c2ecf20Sopenharmony_ci * coredump_read, ...) 1678c2ecf20Sopenharmony_ci * } 1688c2ecf20Sopenharmony_ci * 1698c2ecf20Sopenharmony_ci * RETURNS: 1708c2ecf20Sopenharmony_ci * The &drm_printer object 1718c2ecf20Sopenharmony_ci */ 1728c2ecf20Sopenharmony_cistatic inline struct drm_printer 1738c2ecf20Sopenharmony_cidrm_coredump_printer(struct drm_print_iterator *iter) 1748c2ecf20Sopenharmony_ci{ 1758c2ecf20Sopenharmony_ci struct drm_printer p = { 1768c2ecf20Sopenharmony_ci .printfn = __drm_printfn_coredump, 1778c2ecf20Sopenharmony_ci .puts = __drm_puts_coredump, 1788c2ecf20Sopenharmony_ci .arg = iter, 1798c2ecf20Sopenharmony_ci }; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci /* Set the internal offset of the iterator to zero */ 1828c2ecf20Sopenharmony_ci iter->offset = 0; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci return p; 1858c2ecf20Sopenharmony_ci} 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci/** 1888c2ecf20Sopenharmony_ci * drm_seq_file_printer - construct a &drm_printer that outputs to &seq_file 1898c2ecf20Sopenharmony_ci * @f: the &struct seq_file to output to 1908c2ecf20Sopenharmony_ci * 1918c2ecf20Sopenharmony_ci * RETURNS: 1928c2ecf20Sopenharmony_ci * The &drm_printer object 1938c2ecf20Sopenharmony_ci */ 1948c2ecf20Sopenharmony_cistatic inline struct drm_printer drm_seq_file_printer(struct seq_file *f) 1958c2ecf20Sopenharmony_ci{ 1968c2ecf20Sopenharmony_ci struct drm_printer p = { 1978c2ecf20Sopenharmony_ci .printfn = __drm_printfn_seq_file, 1988c2ecf20Sopenharmony_ci .puts = __drm_puts_seq_file, 1998c2ecf20Sopenharmony_ci .arg = f, 2008c2ecf20Sopenharmony_ci }; 2018c2ecf20Sopenharmony_ci return p; 2028c2ecf20Sopenharmony_ci} 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci/** 2058c2ecf20Sopenharmony_ci * drm_info_printer - construct a &drm_printer that outputs to dev_printk() 2068c2ecf20Sopenharmony_ci * @dev: the &struct device pointer 2078c2ecf20Sopenharmony_ci * 2088c2ecf20Sopenharmony_ci * RETURNS: 2098c2ecf20Sopenharmony_ci * The &drm_printer object 2108c2ecf20Sopenharmony_ci */ 2118c2ecf20Sopenharmony_cistatic inline struct drm_printer drm_info_printer(struct device *dev) 2128c2ecf20Sopenharmony_ci{ 2138c2ecf20Sopenharmony_ci struct drm_printer p = { 2148c2ecf20Sopenharmony_ci .printfn = __drm_printfn_info, 2158c2ecf20Sopenharmony_ci .arg = dev, 2168c2ecf20Sopenharmony_ci }; 2178c2ecf20Sopenharmony_ci return p; 2188c2ecf20Sopenharmony_ci} 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci/** 2218c2ecf20Sopenharmony_ci * drm_debug_printer - construct a &drm_printer that outputs to pr_debug() 2228c2ecf20Sopenharmony_ci * @prefix: debug output prefix 2238c2ecf20Sopenharmony_ci * 2248c2ecf20Sopenharmony_ci * RETURNS: 2258c2ecf20Sopenharmony_ci * The &drm_printer object 2268c2ecf20Sopenharmony_ci */ 2278c2ecf20Sopenharmony_cistatic inline struct drm_printer drm_debug_printer(const char *prefix) 2288c2ecf20Sopenharmony_ci{ 2298c2ecf20Sopenharmony_ci struct drm_printer p = { 2308c2ecf20Sopenharmony_ci .printfn = __drm_printfn_debug, 2318c2ecf20Sopenharmony_ci .prefix = prefix 2328c2ecf20Sopenharmony_ci }; 2338c2ecf20Sopenharmony_ci return p; 2348c2ecf20Sopenharmony_ci} 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci/** 2378c2ecf20Sopenharmony_ci * drm_err_printer - construct a &drm_printer that outputs to pr_err() 2388c2ecf20Sopenharmony_ci * @prefix: debug output prefix 2398c2ecf20Sopenharmony_ci * 2408c2ecf20Sopenharmony_ci * RETURNS: 2418c2ecf20Sopenharmony_ci * The &drm_printer object 2428c2ecf20Sopenharmony_ci */ 2438c2ecf20Sopenharmony_cistatic inline struct drm_printer drm_err_printer(const char *prefix) 2448c2ecf20Sopenharmony_ci{ 2458c2ecf20Sopenharmony_ci struct drm_printer p = { 2468c2ecf20Sopenharmony_ci .printfn = __drm_printfn_err, 2478c2ecf20Sopenharmony_ci .prefix = prefix 2488c2ecf20Sopenharmony_ci }; 2498c2ecf20Sopenharmony_ci return p; 2508c2ecf20Sopenharmony_ci} 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci/** 2538c2ecf20Sopenharmony_ci * enum drm_debug_category - The DRM debug categories 2548c2ecf20Sopenharmony_ci * 2558c2ecf20Sopenharmony_ci * Each of the DRM debug logging macros use a specific category, and the logging 2568c2ecf20Sopenharmony_ci * is filtered by the drm.debug module parameter. This enum specifies the values 2578c2ecf20Sopenharmony_ci * for the interface. 2588c2ecf20Sopenharmony_ci * 2598c2ecf20Sopenharmony_ci * Each DRM_DEBUG_<CATEGORY> macro logs to DRM_UT_<CATEGORY> category, except 2608c2ecf20Sopenharmony_ci * DRM_DEBUG() logs to DRM_UT_CORE. 2618c2ecf20Sopenharmony_ci * 2628c2ecf20Sopenharmony_ci * Enabling verbose debug messages is done through the drm.debug parameter, each 2638c2ecf20Sopenharmony_ci * category being enabled by a bit: 2648c2ecf20Sopenharmony_ci * 2658c2ecf20Sopenharmony_ci * - drm.debug=0x1 will enable CORE messages 2668c2ecf20Sopenharmony_ci * - drm.debug=0x2 will enable DRIVER messages 2678c2ecf20Sopenharmony_ci * - drm.debug=0x3 will enable CORE and DRIVER messages 2688c2ecf20Sopenharmony_ci * - ... 2698c2ecf20Sopenharmony_ci * - drm.debug=0x1ff will enable all messages 2708c2ecf20Sopenharmony_ci * 2718c2ecf20Sopenharmony_ci * An interesting feature is that it's possible to enable verbose logging at 2728c2ecf20Sopenharmony_ci * run-time by echoing the debug value in its sysfs node:: 2738c2ecf20Sopenharmony_ci * 2748c2ecf20Sopenharmony_ci * # echo 0xf > /sys/module/drm/parameters/debug 2758c2ecf20Sopenharmony_ci * 2768c2ecf20Sopenharmony_ci */ 2778c2ecf20Sopenharmony_cienum drm_debug_category { 2788c2ecf20Sopenharmony_ci /** 2798c2ecf20Sopenharmony_ci * @DRM_UT_CORE: Used in the generic drm code: drm_ioctl.c, drm_mm.c, 2808c2ecf20Sopenharmony_ci * drm_memory.c, ... 2818c2ecf20Sopenharmony_ci */ 2828c2ecf20Sopenharmony_ci DRM_UT_CORE = 0x01, 2838c2ecf20Sopenharmony_ci /** 2848c2ecf20Sopenharmony_ci * @DRM_UT_DRIVER: Used in the vendor specific part of the driver: i915, 2858c2ecf20Sopenharmony_ci * radeon, ... macro. 2868c2ecf20Sopenharmony_ci */ 2878c2ecf20Sopenharmony_ci DRM_UT_DRIVER = 0x02, 2888c2ecf20Sopenharmony_ci /** 2898c2ecf20Sopenharmony_ci * @DRM_UT_KMS: Used in the modesetting code. 2908c2ecf20Sopenharmony_ci */ 2918c2ecf20Sopenharmony_ci DRM_UT_KMS = 0x04, 2928c2ecf20Sopenharmony_ci /** 2938c2ecf20Sopenharmony_ci * @DRM_UT_PRIME: Used in the prime code. 2948c2ecf20Sopenharmony_ci */ 2958c2ecf20Sopenharmony_ci DRM_UT_PRIME = 0x08, 2968c2ecf20Sopenharmony_ci /** 2978c2ecf20Sopenharmony_ci * @DRM_UT_ATOMIC: Used in the atomic code. 2988c2ecf20Sopenharmony_ci */ 2998c2ecf20Sopenharmony_ci DRM_UT_ATOMIC = 0x10, 3008c2ecf20Sopenharmony_ci /** 3018c2ecf20Sopenharmony_ci * @DRM_UT_VBL: Used for verbose debug message in the vblank code. 3028c2ecf20Sopenharmony_ci */ 3038c2ecf20Sopenharmony_ci DRM_UT_VBL = 0x20, 3048c2ecf20Sopenharmony_ci /** 3058c2ecf20Sopenharmony_ci * @DRM_UT_STATE: Used for verbose atomic state debugging. 3068c2ecf20Sopenharmony_ci */ 3078c2ecf20Sopenharmony_ci DRM_UT_STATE = 0x40, 3088c2ecf20Sopenharmony_ci /** 3098c2ecf20Sopenharmony_ci * @DRM_UT_LEASE: Used in the lease code. 3108c2ecf20Sopenharmony_ci */ 3118c2ecf20Sopenharmony_ci DRM_UT_LEASE = 0x80, 3128c2ecf20Sopenharmony_ci /** 3138c2ecf20Sopenharmony_ci * @DRM_UT_DP: Used in the DP code. 3148c2ecf20Sopenharmony_ci */ 3158c2ecf20Sopenharmony_ci DRM_UT_DP = 0x100, 3168c2ecf20Sopenharmony_ci /** 3178c2ecf20Sopenharmony_ci * @DRM_UT_DRMRES: Used in the drm managed resources code. 3188c2ecf20Sopenharmony_ci */ 3198c2ecf20Sopenharmony_ci DRM_UT_DRMRES = 0x200, 3208c2ecf20Sopenharmony_ci}; 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_cistatic inline bool drm_debug_enabled(enum drm_debug_category category) 3238c2ecf20Sopenharmony_ci{ 3248c2ecf20Sopenharmony_ci return unlikely(__drm_debug & category); 3258c2ecf20Sopenharmony_ci} 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ci/* 3288c2ecf20Sopenharmony_ci * struct device based logging 3298c2ecf20Sopenharmony_ci * 3308c2ecf20Sopenharmony_ci * Prefer drm_device based logging over device or prink based logging. 3318c2ecf20Sopenharmony_ci */ 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci__printf(3, 4) 3348c2ecf20Sopenharmony_civoid drm_dev_printk(const struct device *dev, const char *level, 3358c2ecf20Sopenharmony_ci const char *format, ...); 3368c2ecf20Sopenharmony_ci__printf(3, 4) 3378c2ecf20Sopenharmony_civoid drm_dev_dbg(const struct device *dev, enum drm_debug_category category, 3388c2ecf20Sopenharmony_ci const char *format, ...); 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci/** 3418c2ecf20Sopenharmony_ci * DRM_DEV_ERROR() - Error output. 3428c2ecf20Sopenharmony_ci * 3438c2ecf20Sopenharmony_ci * @dev: device pointer 3448c2ecf20Sopenharmony_ci * @fmt: printf() like format string. 3458c2ecf20Sopenharmony_ci */ 3468c2ecf20Sopenharmony_ci#define DRM_DEV_ERROR(dev, fmt, ...) \ 3478c2ecf20Sopenharmony_ci drm_dev_printk(dev, KERN_ERR, "*ERROR* " fmt, ##__VA_ARGS__) 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_ci/** 3508c2ecf20Sopenharmony_ci * DRM_DEV_ERROR_RATELIMITED() - Rate limited error output. 3518c2ecf20Sopenharmony_ci * 3528c2ecf20Sopenharmony_ci * @dev: device pointer 3538c2ecf20Sopenharmony_ci * @fmt: printf() like format string. 3548c2ecf20Sopenharmony_ci * 3558c2ecf20Sopenharmony_ci * Like DRM_ERROR() but won't flood the log. 3568c2ecf20Sopenharmony_ci */ 3578c2ecf20Sopenharmony_ci#define DRM_DEV_ERROR_RATELIMITED(dev, fmt, ...) \ 3588c2ecf20Sopenharmony_ci({ \ 3598c2ecf20Sopenharmony_ci static DEFINE_RATELIMIT_STATE(_rs, \ 3608c2ecf20Sopenharmony_ci DEFAULT_RATELIMIT_INTERVAL, \ 3618c2ecf20Sopenharmony_ci DEFAULT_RATELIMIT_BURST); \ 3628c2ecf20Sopenharmony_ci \ 3638c2ecf20Sopenharmony_ci if (__ratelimit(&_rs)) \ 3648c2ecf20Sopenharmony_ci DRM_DEV_ERROR(dev, fmt, ##__VA_ARGS__); \ 3658c2ecf20Sopenharmony_ci}) 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci#define DRM_DEV_INFO(dev, fmt, ...) \ 3688c2ecf20Sopenharmony_ci drm_dev_printk(dev, KERN_INFO, fmt, ##__VA_ARGS__) 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci#define DRM_DEV_INFO_ONCE(dev, fmt, ...) \ 3718c2ecf20Sopenharmony_ci({ \ 3728c2ecf20Sopenharmony_ci static bool __print_once __read_mostly; \ 3738c2ecf20Sopenharmony_ci if (!__print_once) { \ 3748c2ecf20Sopenharmony_ci __print_once = true; \ 3758c2ecf20Sopenharmony_ci DRM_DEV_INFO(dev, fmt, ##__VA_ARGS__); \ 3768c2ecf20Sopenharmony_ci } \ 3778c2ecf20Sopenharmony_ci}) 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci/** 3808c2ecf20Sopenharmony_ci * DRM_DEV_DEBUG() - Debug output for generic drm code 3818c2ecf20Sopenharmony_ci * 3828c2ecf20Sopenharmony_ci * @dev: device pointer 3838c2ecf20Sopenharmony_ci * @fmt: printf() like format string. 3848c2ecf20Sopenharmony_ci */ 3858c2ecf20Sopenharmony_ci#define DRM_DEV_DEBUG(dev, fmt, ...) \ 3868c2ecf20Sopenharmony_ci drm_dev_dbg(dev, DRM_UT_CORE, fmt, ##__VA_ARGS__) 3878c2ecf20Sopenharmony_ci/** 3888c2ecf20Sopenharmony_ci * DRM_DEV_DEBUG_DRIVER() - Debug output for vendor specific part of the driver 3898c2ecf20Sopenharmony_ci * 3908c2ecf20Sopenharmony_ci * @dev: device pointer 3918c2ecf20Sopenharmony_ci * @fmt: printf() like format string. 3928c2ecf20Sopenharmony_ci */ 3938c2ecf20Sopenharmony_ci#define DRM_DEV_DEBUG_DRIVER(dev, fmt, ...) \ 3948c2ecf20Sopenharmony_ci drm_dev_dbg(dev, DRM_UT_DRIVER, fmt, ##__VA_ARGS__) 3958c2ecf20Sopenharmony_ci/** 3968c2ecf20Sopenharmony_ci * DRM_DEV_DEBUG_KMS() - Debug output for modesetting code 3978c2ecf20Sopenharmony_ci * 3988c2ecf20Sopenharmony_ci * @dev: device pointer 3998c2ecf20Sopenharmony_ci * @fmt: printf() like format string. 4008c2ecf20Sopenharmony_ci */ 4018c2ecf20Sopenharmony_ci#define DRM_DEV_DEBUG_KMS(dev, fmt, ...) \ 4028c2ecf20Sopenharmony_ci drm_dev_dbg(dev, DRM_UT_KMS, fmt, ##__VA_ARGS__) 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci/* 4058c2ecf20Sopenharmony_ci * struct drm_device based logging 4068c2ecf20Sopenharmony_ci * 4078c2ecf20Sopenharmony_ci * Prefer drm_device based logging over device or prink based logging. 4088c2ecf20Sopenharmony_ci */ 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci/* Helper for struct drm_device based logging. */ 4118c2ecf20Sopenharmony_ci#define __drm_printk(drm, level, type, fmt, ...) \ 4128c2ecf20Sopenharmony_ci dev_##level##type((drm)->dev, "[drm] " fmt, ##__VA_ARGS__) 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci#define drm_info(drm, fmt, ...) \ 4168c2ecf20Sopenharmony_ci __drm_printk((drm), info,, fmt, ##__VA_ARGS__) 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci#define drm_notice(drm, fmt, ...) \ 4198c2ecf20Sopenharmony_ci __drm_printk((drm), notice,, fmt, ##__VA_ARGS__) 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci#define drm_warn(drm, fmt, ...) \ 4228c2ecf20Sopenharmony_ci __drm_printk((drm), warn,, fmt, ##__VA_ARGS__) 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci#define drm_err(drm, fmt, ...) \ 4258c2ecf20Sopenharmony_ci __drm_printk((drm), err,, "*ERROR* " fmt, ##__VA_ARGS__) 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci#define drm_info_once(drm, fmt, ...) \ 4298c2ecf20Sopenharmony_ci __drm_printk((drm), info, _once, fmt, ##__VA_ARGS__) 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci#define drm_notice_once(drm, fmt, ...) \ 4328c2ecf20Sopenharmony_ci __drm_printk((drm), notice, _once, fmt, ##__VA_ARGS__) 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci#define drm_warn_once(drm, fmt, ...) \ 4358c2ecf20Sopenharmony_ci __drm_printk((drm), warn, _once, fmt, ##__VA_ARGS__) 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_ci#define drm_err_once(drm, fmt, ...) \ 4388c2ecf20Sopenharmony_ci __drm_printk((drm), err, _once, "*ERROR* " fmt, ##__VA_ARGS__) 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci#define drm_err_ratelimited(drm, fmt, ...) \ 4428c2ecf20Sopenharmony_ci __drm_printk((drm), err, _ratelimited, "*ERROR* " fmt, ##__VA_ARGS__) 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_ci#define drm_dbg_core(drm, fmt, ...) \ 4468c2ecf20Sopenharmony_ci drm_dev_dbg((drm)->dev, DRM_UT_CORE, fmt, ##__VA_ARGS__) 4478c2ecf20Sopenharmony_ci#define drm_dbg(drm, fmt, ...) \ 4488c2ecf20Sopenharmony_ci drm_dev_dbg((drm)->dev, DRM_UT_DRIVER, fmt, ##__VA_ARGS__) 4498c2ecf20Sopenharmony_ci#define drm_dbg_kms(drm, fmt, ...) \ 4508c2ecf20Sopenharmony_ci drm_dev_dbg((drm)->dev, DRM_UT_KMS, fmt, ##__VA_ARGS__) 4518c2ecf20Sopenharmony_ci#define drm_dbg_prime(drm, fmt, ...) \ 4528c2ecf20Sopenharmony_ci drm_dev_dbg((drm)->dev, DRM_UT_PRIME, fmt, ##__VA_ARGS__) 4538c2ecf20Sopenharmony_ci#define drm_dbg_atomic(drm, fmt, ...) \ 4548c2ecf20Sopenharmony_ci drm_dev_dbg((drm)->dev, DRM_UT_ATOMIC, fmt, ##__VA_ARGS__) 4558c2ecf20Sopenharmony_ci#define drm_dbg_vbl(drm, fmt, ...) \ 4568c2ecf20Sopenharmony_ci drm_dev_dbg((drm)->dev, DRM_UT_VBL, fmt, ##__VA_ARGS__) 4578c2ecf20Sopenharmony_ci#define drm_dbg_state(drm, fmt, ...) \ 4588c2ecf20Sopenharmony_ci drm_dev_dbg((drm)->dev, DRM_UT_STATE, fmt, ##__VA_ARGS__) 4598c2ecf20Sopenharmony_ci#define drm_dbg_lease(drm, fmt, ...) \ 4608c2ecf20Sopenharmony_ci drm_dev_dbg((drm)->dev, DRM_UT_LEASE, fmt, ##__VA_ARGS__) 4618c2ecf20Sopenharmony_ci#define drm_dbg_dp(drm, fmt, ...) \ 4628c2ecf20Sopenharmony_ci drm_dev_dbg((drm)->dev, DRM_UT_DP, fmt, ##__VA_ARGS__) 4638c2ecf20Sopenharmony_ci#define drm_dbg_drmres(drm, fmt, ...) \ 4648c2ecf20Sopenharmony_ci drm_dev_dbg((drm)->dev, DRM_UT_DRMRES, fmt, ##__VA_ARGS__) 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_ci/* 4688c2ecf20Sopenharmony_ci * printk based logging 4698c2ecf20Sopenharmony_ci * 4708c2ecf20Sopenharmony_ci * Prefer drm_device based logging over device or prink based logging. 4718c2ecf20Sopenharmony_ci */ 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ci__printf(2, 3) 4748c2ecf20Sopenharmony_civoid __drm_dbg(enum drm_debug_category category, const char *format, ...); 4758c2ecf20Sopenharmony_ci__printf(1, 2) 4768c2ecf20Sopenharmony_civoid __drm_err(const char *format, ...); 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci/* Macros to make printk easier */ 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_ci#define _DRM_PRINTK(once, level, fmt, ...) \ 4818c2ecf20Sopenharmony_ci printk##once(KERN_##level "[" DRM_NAME "] " fmt, ##__VA_ARGS__) 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci#define DRM_INFO(fmt, ...) \ 4848c2ecf20Sopenharmony_ci _DRM_PRINTK(, INFO, fmt, ##__VA_ARGS__) 4858c2ecf20Sopenharmony_ci#define DRM_NOTE(fmt, ...) \ 4868c2ecf20Sopenharmony_ci _DRM_PRINTK(, NOTICE, fmt, ##__VA_ARGS__) 4878c2ecf20Sopenharmony_ci#define DRM_WARN(fmt, ...) \ 4888c2ecf20Sopenharmony_ci _DRM_PRINTK(, WARNING, fmt, ##__VA_ARGS__) 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ci#define DRM_INFO_ONCE(fmt, ...) \ 4918c2ecf20Sopenharmony_ci _DRM_PRINTK(_once, INFO, fmt, ##__VA_ARGS__) 4928c2ecf20Sopenharmony_ci#define DRM_NOTE_ONCE(fmt, ...) \ 4938c2ecf20Sopenharmony_ci _DRM_PRINTK(_once, NOTICE, fmt, ##__VA_ARGS__) 4948c2ecf20Sopenharmony_ci#define DRM_WARN_ONCE(fmt, ...) \ 4958c2ecf20Sopenharmony_ci _DRM_PRINTK(_once, WARNING, fmt, ##__VA_ARGS__) 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci#define DRM_ERROR(fmt, ...) \ 4988c2ecf20Sopenharmony_ci __drm_err(fmt, ##__VA_ARGS__) 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_ci#define DRM_ERROR_RATELIMITED(fmt, ...) \ 5018c2ecf20Sopenharmony_ci DRM_DEV_ERROR_RATELIMITED(NULL, fmt, ##__VA_ARGS__) 5028c2ecf20Sopenharmony_ci 5038c2ecf20Sopenharmony_ci#define DRM_DEBUG(fmt, ...) \ 5048c2ecf20Sopenharmony_ci __drm_dbg(DRM_UT_CORE, fmt, ##__VA_ARGS__) 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci#define DRM_DEBUG_DRIVER(fmt, ...) \ 5078c2ecf20Sopenharmony_ci __drm_dbg(DRM_UT_DRIVER, fmt, ##__VA_ARGS__) 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci#define DRM_DEBUG_KMS(fmt, ...) \ 5108c2ecf20Sopenharmony_ci __drm_dbg(DRM_UT_KMS, fmt, ##__VA_ARGS__) 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_ci#define DRM_DEBUG_PRIME(fmt, ...) \ 5138c2ecf20Sopenharmony_ci __drm_dbg(DRM_UT_PRIME, fmt, ##__VA_ARGS__) 5148c2ecf20Sopenharmony_ci 5158c2ecf20Sopenharmony_ci#define DRM_DEBUG_ATOMIC(fmt, ...) \ 5168c2ecf20Sopenharmony_ci __drm_dbg(DRM_UT_ATOMIC, fmt, ##__VA_ARGS__) 5178c2ecf20Sopenharmony_ci 5188c2ecf20Sopenharmony_ci#define DRM_DEBUG_VBL(fmt, ...) \ 5198c2ecf20Sopenharmony_ci __drm_dbg(DRM_UT_VBL, fmt, ##__VA_ARGS__) 5208c2ecf20Sopenharmony_ci 5218c2ecf20Sopenharmony_ci#define DRM_DEBUG_LEASE(fmt, ...) \ 5228c2ecf20Sopenharmony_ci __drm_dbg(DRM_UT_LEASE, fmt, ##__VA_ARGS__) 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci#define DRM_DEBUG_DP(fmt, ...) \ 5258c2ecf20Sopenharmony_ci __drm_dbg(DRM_UT_DP, fmt, ## __VA_ARGS__) 5268c2ecf20Sopenharmony_ci 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci#define DRM_DEBUG_KMS_RATELIMITED(fmt, ...) \ 5298c2ecf20Sopenharmony_ci({ \ 5308c2ecf20Sopenharmony_ci static DEFINE_RATELIMIT_STATE(_rs, \ 5318c2ecf20Sopenharmony_ci DEFAULT_RATELIMIT_INTERVAL, \ 5328c2ecf20Sopenharmony_ci DEFAULT_RATELIMIT_BURST); \ 5338c2ecf20Sopenharmony_ci if (__ratelimit(&_rs)) \ 5348c2ecf20Sopenharmony_ci drm_dev_dbg(NULL, DRM_UT_KMS, fmt, ##__VA_ARGS__); \ 5358c2ecf20Sopenharmony_ci}) 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci/* 5388c2ecf20Sopenharmony_ci * struct drm_device based WARNs 5398c2ecf20Sopenharmony_ci * 5408c2ecf20Sopenharmony_ci * drm_WARN*() acts like WARN*(), but with the key difference of 5418c2ecf20Sopenharmony_ci * using device specific information so that we know from which device 5428c2ecf20Sopenharmony_ci * warning is originating from. 5438c2ecf20Sopenharmony_ci * 5448c2ecf20Sopenharmony_ci * Prefer drm_device based drm_WARN* over regular WARN* 5458c2ecf20Sopenharmony_ci */ 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_ci/* Helper for struct drm_device based WARNs */ 5488c2ecf20Sopenharmony_ci#define drm_WARN(drm, condition, format, arg...) \ 5498c2ecf20Sopenharmony_ci WARN(condition, "%s %s: " format, \ 5508c2ecf20Sopenharmony_ci dev_driver_string((drm)->dev), \ 5518c2ecf20Sopenharmony_ci dev_name((drm)->dev), ## arg) 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_ci#define drm_WARN_ONCE(drm, condition, format, arg...) \ 5548c2ecf20Sopenharmony_ci WARN_ONCE(condition, "%s %s: " format, \ 5558c2ecf20Sopenharmony_ci dev_driver_string((drm)->dev), \ 5568c2ecf20Sopenharmony_ci dev_name((drm)->dev), ## arg) 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci#define drm_WARN_ON(drm, x) \ 5598c2ecf20Sopenharmony_ci drm_WARN((drm), (x), "%s", \ 5608c2ecf20Sopenharmony_ci "drm_WARN_ON(" __stringify(x) ")") 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci#define drm_WARN_ON_ONCE(drm, x) \ 5638c2ecf20Sopenharmony_ci drm_WARN_ONCE((drm), (x), "%s", \ 5648c2ecf20Sopenharmony_ci "drm_WARN_ON_ONCE(" __stringify(x) ")") 5658c2ecf20Sopenharmony_ci 5668c2ecf20Sopenharmony_ci#endif /* DRM_PRINT_H_ */ 567