aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_atomic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_atomic.c')
-rw-r--r--drivers/gpu/drm/drm_atomic.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 1d6ab371cd52..f5ea7db4a48a 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -30,6 +30,7 @@
30#include <drm/drm_atomic.h> 30#include <drm/drm_atomic.h>
31#include <drm/drm_mode.h> 31#include <drm/drm_mode.h>
32#include <drm/drm_plane_helper.h> 32#include <drm/drm_plane_helper.h>
33#include <drm/drm_print.h>
33 34
34#include "drm_crtc_internal.h" 35#include "drm_crtc_internal.h"
35 36
@@ -605,6 +606,28 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
605 return 0; 606 return 0;
606} 607}
607 608
609static void drm_atomic_crtc_print_state(struct drm_printer *p,
610 const struct drm_crtc_state *state)
611{
612 struct drm_crtc *crtc = state->crtc;
613
614 drm_printf(p, "crtc[%u]: %s\n", crtc->base.id, crtc->name);
615 drm_printf(p, "\tenable=%d\n", state->enable);
616 drm_printf(p, "\tactive=%d\n", state->active);
617 drm_printf(p, "\tplanes_changed=%d\n", state->planes_changed);
618 drm_printf(p, "\tmode_changed=%d\n", state->mode_changed);
619 drm_printf(p, "\tactive_changed=%d\n", state->active_changed);
620 drm_printf(p, "\tconnectors_changed=%d\n", state->connectors_changed);
621 drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed);
622 drm_printf(p, "\tplane_mask=%x\n", state->plane_mask);
623 drm_printf(p, "\tconnector_mask=%x\n", state->connector_mask);
624 drm_printf(p, "\tencoder_mask=%x\n", state->encoder_mask);
625 drm_printf(p, "\tmode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&state->mode));
626
627 if (crtc->funcs->atomic_print_state)
628 crtc->funcs->atomic_print_state(p, state);
629}
630
608/** 631/**
609 * drm_atomic_get_plane_state - get plane state 632 * drm_atomic_get_plane_state - get plane state
610 * @state: global atomic state object 633 * @state: global atomic state object
@@ -881,6 +904,38 @@ static int drm_atomic_plane_check(struct drm_plane *plane,
881 return 0; 904 return 0;
882} 905}
883 906
907static void drm_atomic_plane_print_state(struct drm_printer *p,
908 const struct drm_plane_state *state)
909{
910 struct drm_plane *plane = state->plane;
911 struct drm_rect src = drm_plane_state_src(state);
912 struct drm_rect dest = drm_plane_state_dest(state);
913
914 drm_printf(p, "plane[%u]: %s\n", plane->base.id, plane->name);
915 drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
916 drm_printf(p, "\tfb=%u\n", state->fb ? state->fb->base.id : 0);
917 if (state->fb) {
918 struct drm_framebuffer *fb = state->fb;
919 int i, n = drm_format_num_planes(fb->pixel_format);
920
921 drm_printf(p, "\t\tformat=%s\n",
922 drm_get_format_name(fb->pixel_format));
923 drm_printf(p, "\t\tsize=%dx%d\n", fb->width, fb->height);
924 drm_printf(p, "\t\tlayers:\n");
925 for (i = 0; i < n; i++) {
926 drm_printf(p, "\t\t\tpitch[%d]=%u\n", i, fb->pitches[i]);
927 drm_printf(p, "\t\t\toffset[%d]=%u\n", i, fb->offsets[i]);
928 drm_printf(p, "\t\t\tmodifier[%d]=0x%llx\n", i, fb->modifier[i]);
929 }
930 }
931 drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest));
932 drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src));
933 drm_printf(p, "\trotation=%x\n", state->rotation);
934
935 if (plane->funcs->atomic_print_state)
936 plane->funcs->atomic_print_state(p, state);
937}
938
884/** 939/**
885 * drm_atomic_get_connector_state - get connector state 940 * drm_atomic_get_connector_state - get connector state
886 * @state: global atomic state object 941 * @state: global atomic state object
@@ -996,6 +1051,18 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
996} 1051}
997EXPORT_SYMBOL(drm_atomic_connector_set_property); 1052EXPORT_SYMBOL(drm_atomic_connector_set_property);
998 1053
1054static void drm_atomic_connector_print_state(struct drm_printer *p,
1055 const struct drm_connector_state *state)
1056{
1057 struct drm_connector *connector = state->connector;
1058
1059 drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name);
1060 drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
1061
1062 if (connector->funcs->atomic_print_state)
1063 connector->funcs->atomic_print_state(p, state);
1064}
1065
999/** 1066/**
1000 * drm_atomic_connector_get_property - get property value from connector state 1067 * drm_atomic_connector_get_property - get property value from connector state
1001 * @connector: the drm connector to set a property on 1068 * @connector: the drm connector to set a property on
@@ -1150,6 +1217,36 @@ drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
1150EXPORT_SYMBOL(drm_atomic_set_fb_for_plane); 1217EXPORT_SYMBOL(drm_atomic_set_fb_for_plane);
1151 1218
1152/** 1219/**
1220 * drm_atomic_set_fence_for_plane - set fence for plane
1221 * @plane_state: atomic state object for the plane
1222 * @fence: dma_fence to use for the plane
1223 *
1224 * Helper to setup the plane_state fence in case it is not set yet.
1225 * By using this drivers doesn't need to worry if the user choose
1226 * implicit or explicit fencing.
1227 *
1228 * This function will not set the fence to the state if it was set
1229 * via explicit fencing interfaces on the atomic ioctl. It will
1230 * all drope the reference to the fence as we not storing it
1231 * anywhere.
1232 *
1233 * Otherwise, if plane_state->fence is not set this function we
1234 * just set it with the received implict fence.
1235 */
1236void
1237drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state,
1238 struct dma_fence *fence)
1239{
1240 if (plane_state->fence) {
1241 dma_fence_put(fence);
1242 return;
1243 }
1244
1245 plane_state->fence = fence;
1246}
1247EXPORT_SYMBOL(drm_atomic_set_fence_for_plane);
1248
1249/**
1153 * drm_atomic_set_crtc_for_connector - set crtc for connector 1250 * drm_atomic_set_crtc_for_connector - set crtc for connector
1154 * @conn_state: atomic state object for the connector 1251 * @conn_state: atomic state object for the connector
1155 * @crtc: crtc to use for the connector 1252 * @crtc: crtc to use for the connector
@@ -1460,6 +1557,92 @@ int drm_atomic_nonblocking_commit(struct drm_atomic_state *state)
1460} 1557}
1461EXPORT_SYMBOL(drm_atomic_nonblocking_commit); 1558EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
1462 1559
1560static void drm_atomic_print_state(const struct drm_atomic_state *state)
1561{
1562 struct drm_printer p = drm_info_printer(state->dev->dev);
1563 struct drm_plane *plane;
1564 struct drm_plane_state *plane_state;
1565 struct drm_crtc *crtc;
1566 struct drm_crtc_state *crtc_state;
1567 struct drm_connector *connector;
1568 struct drm_connector_state *connector_state;
1569 int i;
1570
1571 DRM_DEBUG_ATOMIC("checking %p\n", state);
1572
1573 for_each_plane_in_state(state, plane, plane_state, i)
1574 drm_atomic_plane_print_state(&p, plane_state);
1575
1576 for_each_crtc_in_state(state, crtc, crtc_state, i)
1577 drm_atomic_crtc_print_state(&p, crtc_state);
1578
1579 for_each_connector_in_state(state, connector, connector_state, i)
1580 drm_atomic_connector_print_state(&p, connector_state);
1581}
1582
1583/**
1584 * drm_state_dump - dump entire device atomic state
1585 * @dev: the drm device
1586 * @p: where to print the state to
1587 *
1588 * Just for debugging. Drivers might want an option to dump state
1589 * to dmesg in case of error irq's. (Hint, you probably want to
1590 * ratelimit this!)
1591 *
1592 * The caller must drm_modeset_lock_all(), or if this is called
1593 * from error irq handler, it should not be enabled by default.
1594 * (Ie. if you are debugging errors you might not care that this
1595 * is racey. But calling this without all modeset locks held is
1596 * not inherently safe.)
1597 */
1598void drm_state_dump(struct drm_device *dev, struct drm_printer *p)
1599{
1600 struct drm_mode_config *config = &dev->mode_config;
1601 struct drm_plane *plane;
1602 struct drm_crtc *crtc;
1603 struct drm_connector *connector;
1604
1605 if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
1606 return;
1607
1608 list_for_each_entry(plane, &config->plane_list, head)
1609 drm_atomic_plane_print_state(p, plane->state);
1610
1611 list_for_each_entry(crtc, &config->crtc_list, head)
1612 drm_atomic_crtc_print_state(p, crtc->state);
1613
1614 list_for_each_entry(connector, &config->connector_list, head)
1615 drm_atomic_connector_print_state(p, connector->state);
1616}
1617EXPORT_SYMBOL(drm_state_dump);
1618
1619#ifdef CONFIG_DEBUG_FS
1620static int drm_state_info(struct seq_file *m, void *data)
1621{
1622 struct drm_info_node *node = (struct drm_info_node *) m->private;
1623 struct drm_device *dev = node->minor->dev;
1624 struct drm_printer p = drm_seq_file_printer(m);
1625
1626 drm_modeset_lock_all(dev);
1627 drm_state_dump(dev, &p);
1628 drm_modeset_unlock_all(dev);
1629
1630 return 0;
1631}
1632
1633/* any use in debugfs files to dump individual planes/crtc/etc? */
1634static const struct drm_info_list drm_atomic_debugfs_list[] = {
1635 {"state", drm_state_info, 0},
1636};
1637
1638int drm_atomic_debugfs_init(struct drm_minor *minor)
1639{
1640 return drm_debugfs_create_files(drm_atomic_debugfs_list,
1641 ARRAY_SIZE(drm_atomic_debugfs_list),
1642 minor->debugfs_root, minor);
1643}
1644#endif
1645
1463/* 1646/*
1464 * The big monstor ioctl 1647 * The big monstor ioctl
1465 */ 1648 */
@@ -1749,6 +1932,9 @@ retry:
1749 } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) { 1932 } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
1750 ret = drm_atomic_nonblocking_commit(state); 1933 ret = drm_atomic_nonblocking_commit(state);
1751 } else { 1934 } else {
1935 if (unlikely(drm_debug & DRM_UT_STATE))
1936 drm_atomic_print_state(state);
1937
1752 ret = drm_atomic_commit(state); 1938 ret = drm_atomic_commit(state);
1753 } 1939 }
1754 1940