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