forked from mirrors/linux
		
	drm/atomic: add debugfs file to dump out atomic state
Useful to dump current state from debugfs, if turning on the drm.debug bit is too much overhead. The drm_state_dump() can also be used by drivers, for example to implement a module param that dumps state on error irqs. Signed-off-by: Rob Clark <robdclark@gmail.com> Reviewed-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Sean Paul <seanpaul@chromium.org> Link: http://patchwork.freedesktop.org/patch/msgid/1478358492-30738-6-git-send-email-robdclark@gmail.com
This commit is contained in:
		
							parent
							
								
									fceffb325b
								
							
						
					
					
						commit
						6559c901cb
					
				
					 3 changed files with 79 additions and 0 deletions
				
			
		| 
						 | 
					@ -1577,6 +1577,69 @@ static void drm_atomic_print_state(const struct drm_atomic_state *state)
 | 
				
			||||||
		drm_atomic_connector_print_state(&p, connector_state);
 | 
							drm_atomic_connector_print_state(&p, connector_state);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * drm_state_dump - dump entire device atomic state
 | 
				
			||||||
 | 
					 * @dev: the drm device
 | 
				
			||||||
 | 
					 * @p: where to print the state to
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Just for debugging.  Drivers might want an option to dump state
 | 
				
			||||||
 | 
					 * to dmesg in case of error irq's.  (Hint, you probably want to
 | 
				
			||||||
 | 
					 * ratelimit this!)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The caller must drm_modeset_lock_all(), or if this is called
 | 
				
			||||||
 | 
					 * from error irq handler, it should not be enabled by default.
 | 
				
			||||||
 | 
					 * (Ie. if you are debugging errors you might not care that this
 | 
				
			||||||
 | 
					 * is racey.  But calling this without all modeset locks held is
 | 
				
			||||||
 | 
					 * not inherently safe.)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void drm_state_dump(struct drm_device *dev, struct drm_printer *p)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct drm_mode_config *config = &dev->mode_config;
 | 
				
			||||||
 | 
						struct drm_plane *plane;
 | 
				
			||||||
 | 
						struct drm_crtc *crtc;
 | 
				
			||||||
 | 
						struct drm_connector *connector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_entry(plane, &config->plane_list, head)
 | 
				
			||||||
 | 
							drm_atomic_plane_print_state(p, plane->state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_entry(crtc, &config->crtc_list, head)
 | 
				
			||||||
 | 
							drm_atomic_crtc_print_state(p, crtc->state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_entry(connector, &config->connector_list, head)
 | 
				
			||||||
 | 
							drm_atomic_connector_print_state(p, connector->state);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(drm_state_dump);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_DEBUG_FS
 | 
				
			||||||
 | 
					static int drm_state_info(struct seq_file *m, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct drm_info_node *node = (struct drm_info_node *) m->private;
 | 
				
			||||||
 | 
						struct drm_device *dev = node->minor->dev;
 | 
				
			||||||
 | 
						struct drm_printer p = drm_seq_file_printer(m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drm_modeset_lock_all(dev);
 | 
				
			||||||
 | 
						drm_state_dump(dev, &p);
 | 
				
			||||||
 | 
						drm_modeset_unlock_all(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* any use in debugfs files to dump individual planes/crtc/etc? */
 | 
				
			||||||
 | 
					static const struct drm_info_list drm_atomic_debugfs_list[] = {
 | 
				
			||||||
 | 
						{"state", drm_state_info, 0},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int drm_atomic_debugfs_init(struct drm_minor *minor)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return drm_debugfs_create_files(drm_atomic_debugfs_list,
 | 
				
			||||||
 | 
								ARRAY_SIZE(drm_atomic_debugfs_list),
 | 
				
			||||||
 | 
								minor->debugfs_root, minor);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * The big monstor ioctl
 | 
					 * The big monstor ioctl
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,6 +36,7 @@
 | 
				
			||||||
#include <linux/export.h>
 | 
					#include <linux/export.h>
 | 
				
			||||||
#include <drm/drmP.h>
 | 
					#include <drm/drmP.h>
 | 
				
			||||||
#include <drm/drm_edid.h>
 | 
					#include <drm/drm_edid.h>
 | 
				
			||||||
 | 
					#include <drm/drm_atomic.h>
 | 
				
			||||||
#include "drm_internal.h"
 | 
					#include "drm_internal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(CONFIG_DEBUG_FS)
 | 
					#if defined(CONFIG_DEBUG_FS)
 | 
				
			||||||
| 
						 | 
					@ -163,6 +164,14 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
 | 
				
			||||||
 | 
							ret = drm_atomic_debugfs_init(minor);
 | 
				
			||||||
 | 
							if (ret) {
 | 
				
			||||||
 | 
								DRM_ERROR("Failed to create atomic debugfs files\n");
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dev->driver->debugfs_init) {
 | 
						if (dev->driver->debugfs_init) {
 | 
				
			||||||
		ret = dev->driver->debugfs_init(minor);
 | 
							ret = dev->driver->debugfs_init(minor);
 | 
				
			||||||
		if (ret) {
 | 
							if (ret) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -366,6 +366,13 @@ int __must_check drm_atomic_check_only(struct drm_atomic_state *state);
 | 
				
			||||||
int __must_check drm_atomic_commit(struct drm_atomic_state *state);
 | 
					int __must_check drm_atomic_commit(struct drm_atomic_state *state);
 | 
				
			||||||
int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
 | 
					int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_DEBUG_FS
 | 
				
			||||||
 | 
					struct drm_minor;
 | 
				
			||||||
 | 
					int drm_atomic_debugfs_init(struct drm_minor *minor);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define for_each_connector_in_state(__state, connector, connector_state, __i) \
 | 
					#define for_each_connector_in_state(__state, connector, connector_state, __i) \
 | 
				
			||||||
	for ((__i) = 0;							\
 | 
						for ((__i) = 0;							\
 | 
				
			||||||
	     (__i) < (__state)->num_connector &&				\
 | 
						     (__i) < (__state)->num_connector &&				\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue