diff options
author | Rob Clark <robdclark@gmail.com> | 2016-11-05 11:08:10 -0400 |
---|---|---|
committer | Sean Paul <seanpaul@chromium.org> | 2016-11-08 16:38:03 -0500 |
commit | 6559c901cb4840e46893d587d8af435aac9c4c3f (patch) | |
tree | 2e8878c166d83f7c68183acc699b5855a864563e | |
parent | fceffb325b30f6a9f0bdee22e65d0b8bb35883af (diff) |
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
-rw-r--r-- | drivers/gpu/drm/drm_atomic.c | 63 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_debugfs.c | 9 | ||||
-rw-r--r-- | include/drm/drm_atomic.h | 7 |
3 files changed, 79 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index bd62c959b475..b096c1673969 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c | |||
@@ -1577,6 +1577,69 @@ static void drm_atomic_print_state(const struct drm_atomic_state *state) | |||
1577 | drm_atomic_connector_print_state(&p, connector_state); | 1577 | drm_atomic_connector_print_state(&p, connector_state); |
1578 | } | 1578 | } |
1579 | 1579 | ||
1580 | /** | ||
1581 | * drm_state_dump - dump entire device atomic state | ||
1582 | * @dev: the drm device | ||
1583 | * @p: where to print the state to | ||
1584 | * | ||
1585 | * Just for debugging. Drivers might want an option to dump state | ||
1586 | * to dmesg in case of error irq's. (Hint, you probably want to | ||
1587 | * ratelimit this!) | ||
1588 | * | ||
1589 | * The caller must drm_modeset_lock_all(), or if this is called | ||
1590 | * from error irq handler, it should not be enabled by default. | ||
1591 | * (Ie. if you are debugging errors you might not care that this | ||
1592 | * is racey. But calling this without all modeset locks held is | ||
1593 | * not inherently safe.) | ||
1594 | */ | ||
1595 | void drm_state_dump(struct drm_device *dev, struct drm_printer *p) | ||
1596 | { | ||
1597 | struct drm_mode_config *config = &dev->mode_config; | ||
1598 | struct drm_plane *plane; | ||
1599 | struct drm_crtc *crtc; | ||
1600 | struct drm_connector *connector; | ||
1601 | |||
1602 | if (!drm_core_check_feature(dev, DRIVER_ATOMIC)) | ||
1603 | return; | ||
1604 | |||
1605 | list_for_each_entry(plane, &config->plane_list, head) | ||
1606 | drm_atomic_plane_print_state(p, plane->state); | ||
1607 | |||
1608 | list_for_each_entry(crtc, &config->crtc_list, head) | ||
1609 | drm_atomic_crtc_print_state(p, crtc->state); | ||
1610 | |||
1611 | list_for_each_entry(connector, &config->connector_list, head) | ||
1612 | drm_atomic_connector_print_state(p, connector->state); | ||
1613 | } | ||
1614 | EXPORT_SYMBOL(drm_state_dump); | ||
1615 | |||
1616 | #ifdef CONFIG_DEBUG_FS | ||
1617 | static int drm_state_info(struct seq_file *m, void *data) | ||
1618 | { | ||
1619 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
1620 | struct drm_device *dev = node->minor->dev; | ||
1621 | struct drm_printer p = drm_seq_file_printer(m); | ||
1622 | |||
1623 | drm_modeset_lock_all(dev); | ||
1624 | drm_state_dump(dev, &p); | ||
1625 | drm_modeset_unlock_all(dev); | ||
1626 | |||
1627 | return 0; | ||
1628 | } | ||
1629 | |||
1630 | /* any use in debugfs files to dump individual planes/crtc/etc? */ | ||
1631 | static const struct drm_info_list drm_atomic_debugfs_list[] = { | ||
1632 | {"state", drm_state_info, 0}, | ||
1633 | }; | ||
1634 | |||
1635 | int drm_atomic_debugfs_init(struct drm_minor *minor) | ||
1636 | { | ||
1637 | return drm_debugfs_create_files(drm_atomic_debugfs_list, | ||
1638 | ARRAY_SIZE(drm_atomic_debugfs_list), | ||
1639 | minor->debugfs_root, minor); | ||
1640 | } | ||
1641 | #endif | ||
1642 | |||
1580 | /* | 1643 | /* |
1581 | * The big monstor ioctl | 1644 | * The big monstor ioctl |
1582 | */ | 1645 | */ |
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 800055c39cdb..206a4fe7ea26 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/export.h> | 36 | #include <linux/export.h> |
37 | #include <drm/drmP.h> | 37 | #include <drm/drmP.h> |
38 | #include <drm/drm_edid.h> | 38 | #include <drm/drm_edid.h> |
39 | #include <drm/drm_atomic.h> | ||
39 | #include "drm_internal.h" | 40 | #include "drm_internal.h" |
40 | 41 | ||
41 | #if defined(CONFIG_DEBUG_FS) | 42 | #if defined(CONFIG_DEBUG_FS) |
@@ -163,6 +164,14 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id, | |||
163 | return ret; | 164 | return ret; |
164 | } | 165 | } |
165 | 166 | ||
167 | if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { | ||
168 | ret = drm_atomic_debugfs_init(minor); | ||
169 | if (ret) { | ||
170 | DRM_ERROR("Failed to create atomic debugfs files\n"); | ||
171 | return ret; | ||
172 | } | ||
173 | } | ||
174 | |||
166 | if (dev->driver->debugfs_init) { | 175 | if (dev->driver->debugfs_init) { |
167 | ret = dev->driver->debugfs_init(minor); | 176 | ret = dev->driver->debugfs_init(minor); |
168 | if (ret) { | 177 | if (ret) { |
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 2d1e9c944b54..331bb100b718 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h | |||
@@ -366,6 +366,13 @@ int __must_check drm_atomic_check_only(struct drm_atomic_state *state); | |||
366 | int __must_check drm_atomic_commit(struct drm_atomic_state *state); | 366 | int __must_check drm_atomic_commit(struct drm_atomic_state *state); |
367 | int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state); | 367 | int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state); |
368 | 368 | ||
369 | void drm_state_dump(struct drm_device *dev, struct drm_printer *p); | ||
370 | |||
371 | #ifdef CONFIG_DEBUG_FS | ||
372 | struct drm_minor; | ||
373 | int drm_atomic_debugfs_init(struct drm_minor *minor); | ||
374 | #endif | ||
375 | |||
369 | #define for_each_connector_in_state(__state, connector, connector_state, __i) \ | 376 | #define for_each_connector_in_state(__state, connector, connector_state, __i) \ |
370 | for ((__i) = 0; \ | 377 | for ((__i) = 0; \ |
371 | (__i) < (__state)->num_connector && \ | 378 | (__i) < (__state)->num_connector && \ |