drm/atomic: add new drm_debug bit to dump atomic state
authorRob Clark <robdclark@gmail.com>
Sat, 5 Nov 2016 15:08:09 +0000 (11:08 -0400)
committerSean Paul <seanpaul@chromium.org>
Tue, 8 Nov 2016 21:38:03 +0000 (16:38 -0500)
The contents of drm_{plane,crtc,connector}_state is dumped before
commit.  If a driver extends any of the state structs, it can implement
the corresponding funcs->atomic_print_state() to add it's own driver
specific state.

Signed-off-by: Rob Clark <robdclark@gmail.com>
[seanpaul resolved conflict in drm_plane.h]
Signed-off-by: Sean Paul <seanpaul@chromium.org>
drivers/gpu/drm/drm_atomic.c
include/drm/drmP.h
include/drm/drm_connector.h
include/drm/drm_crtc.h
include/drm/drm_plane.h

index 5e73954551085608bd01e2a3df8e4a84bd153cfb..bd62c959b475daa057c53eba0620a8c8470b0d30 100644 (file)
@@ -30,6 +30,7 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_mode.h>
 #include <drm/drm_plane_helper.h>
+#include <drm/drm_print.h>
 
 #include "drm_crtc_internal.h"
 
@@ -602,6 +603,28 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
        return 0;
 }
 
+static void drm_atomic_crtc_print_state(struct drm_printer *p,
+               const struct drm_crtc_state *state)
+{
+       struct drm_crtc *crtc = state->crtc;
+
+       drm_printf(p, "crtc[%u]: %s\n", crtc->base.id, crtc->name);
+       drm_printf(p, "\tenable=%d\n", state->enable);
+       drm_printf(p, "\tactive=%d\n", state->active);
+       drm_printf(p, "\tplanes_changed=%d\n", state->planes_changed);
+       drm_printf(p, "\tmode_changed=%d\n", state->mode_changed);
+       drm_printf(p, "\tactive_changed=%d\n", state->active_changed);
+       drm_printf(p, "\tconnectors_changed=%d\n", state->connectors_changed);
+       drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed);
+       drm_printf(p, "\tplane_mask=%x\n", state->plane_mask);
+       drm_printf(p, "\tconnector_mask=%x\n", state->connector_mask);
+       drm_printf(p, "\tencoder_mask=%x\n", state->encoder_mask);
+       drm_printf(p, "\tmode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&state->mode));
+
+       if (crtc->funcs->atomic_print_state)
+               crtc->funcs->atomic_print_state(p, state);
+}
+
 /**
  * drm_atomic_get_plane_state - get plane state
  * @state: global atomic state object
@@ -878,6 +901,38 @@ static int drm_atomic_plane_check(struct drm_plane *plane,
        return 0;
 }
 
+static void drm_atomic_plane_print_state(struct drm_printer *p,
+               const struct drm_plane_state *state)
+{
+       struct drm_plane *plane = state->plane;
+       struct drm_rect src  = drm_plane_state_src(state);
+       struct drm_rect dest = drm_plane_state_dest(state);
+
+       drm_printf(p, "plane[%u]: %s\n", plane->base.id, plane->name);
+       drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
+       drm_printf(p, "\tfb=%u\n", state->fb ? state->fb->base.id : 0);
+       if (state->fb) {
+               struct drm_framebuffer *fb = state->fb;
+               int i, n = drm_format_num_planes(fb->pixel_format);
+
+               drm_printf(p, "\t\tformat=%s\n",
+                               drm_get_format_name(fb->pixel_format));
+               drm_printf(p, "\t\tsize=%dx%d\n", fb->width, fb->height);
+               drm_printf(p, "\t\tlayers:\n");
+               for (i = 0; i < n; i++) {
+                       drm_printf(p, "\t\t\tpitch[%d]=%u\n", i, fb->pitches[i]);
+                       drm_printf(p, "\t\t\toffset[%d]=%u\n", i, fb->offsets[i]);
+                       drm_printf(p, "\t\t\tmodifier[%d]=0x%llx\n", i, fb->modifier[i]);
+               }
+       }
+       drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest));
+       drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src));
+       drm_printf(p, "\trotation=%x\n", state->rotation);
+
+       if (plane->funcs->atomic_print_state)
+               plane->funcs->atomic_print_state(p, state);
+}
+
 /**
  * drm_atomic_get_connector_state - get connector state
  * @state: global atomic state object
@@ -993,6 +1048,18 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_atomic_connector_set_property);
 
+static void drm_atomic_connector_print_state(struct drm_printer *p,
+               const struct drm_connector_state *state)
+{
+       struct drm_connector *connector = state->connector;
+
+       drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name);
+       drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
+
+       if (connector->funcs->atomic_print_state)
+               connector->funcs->atomic_print_state(p, state);
+}
+
 /**
  * drm_atomic_connector_get_property - get property value from connector state
  * @connector: the drm connector to set a property on
@@ -1487,6 +1554,29 @@ int drm_atomic_nonblocking_commit(struct drm_atomic_state *state)
 }
 EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
 
+static void drm_atomic_print_state(const struct drm_atomic_state *state)
+{
+       struct drm_printer p = drm_info_printer(state->dev->dev);
+       struct drm_plane *plane;
+       struct drm_plane_state *plane_state;
+       struct drm_crtc *crtc;
+       struct drm_crtc_state *crtc_state;
+       struct drm_connector *connector;
+       struct drm_connector_state *connector_state;
+       int i;
+
+       DRM_DEBUG_ATOMIC("checking %p\n", state);
+
+       for_each_plane_in_state(state, plane, plane_state, i)
+               drm_atomic_plane_print_state(&p, plane_state);
+
+       for_each_crtc_in_state(state, crtc, crtc_state, i)
+               drm_atomic_crtc_print_state(&p, crtc_state);
+
+       for_each_connector_in_state(state, connector, connector_state, i)
+               drm_atomic_connector_print_state(&p, connector_state);
+}
+
 /*
  * The big monstor ioctl
  */
@@ -1776,6 +1866,9 @@ retry:
        } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
                ret = drm_atomic_nonblocking_commit(state);
        } else {
+               if (unlikely(drm_debug & DRM_UT_STATE))
+                       drm_atomic_print_state(state);
+
                ret = drm_atomic_commit(state);
        }
 
index e92c904fe8cbd96a6e03a3ef42fe6527e9c59044..4e58137c1882b804bdb0fb7fd09faa5c0f3c8ae6 100644 (file)
@@ -135,6 +135,7 @@ struct dma_buf_attachment;
 #define DRM_UT_PRIME           0x08
 #define DRM_UT_ATOMIC          0x10
 #define DRM_UT_VBL             0x20
+#define DRM_UT_STATE           0x40
 
 extern __printf(6, 7)
 void drm_dev_printk(const struct device *dev, const char *level,
index ac9d7d8e0e43a807e9fc9a0b66de5f26b49d3348..3e9727264b65f036a029e7ddf12ed1d3c37025ef 100644 (file)
@@ -37,6 +37,7 @@ struct drm_crtc;
 struct drm_encoder;
 struct drm_property;
 struct drm_property_blob;
+struct drm_printer;
 struct edid;
 
 enum drm_connector_force {
@@ -481,6 +482,18 @@ struct drm_connector_funcs {
                                   const struct drm_connector_state *state,
                                   struct drm_property *property,
                                   uint64_t *val);
+
+       /**
+        * @atomic_print_state:
+        *
+        * If driver subclasses struct &drm_connector_state, it should implement
+        * this optional hook for printing additional driver specific state.
+        *
+        * Do not call this directly, use drm_atomic_connector_print_state()
+        * instead.
+        */
+       void (*atomic_print_state)(struct drm_printer *p,
+                                  const struct drm_connector_state *state);
 };
 
 /* mode specified on the command line */
index fa1aa214c8ead600fcffa6f8a384da71e5bee5a8..8cca2a895981a1e0d23198a82b05d120e95d98df 100644 (file)
@@ -53,6 +53,7 @@ struct drm_device;
 struct drm_mode_set;
 struct drm_file;
 struct drm_clip_rect;
+struct drm_printer;
 struct device_node;
 struct dma_fence;
 struct edid;
@@ -594,6 +595,18 @@ struct drm_crtc_funcs {
         */
        int (*set_crc_source)(struct drm_crtc *crtc, const char *source,
                              size_t *values_cnt);
+
+       /**
+        * @atomic_print_state:
+        *
+        * If driver subclasses struct &drm_crtc_state, it should implement
+        * this optional hook for printing additional driver specific state.
+        *
+        * Do not call this directly, use drm_atomic_crtc_print_state()
+        * instead.
+        */
+       void (*atomic_print_state)(struct drm_printer *p,
+                                  const struct drm_crtc_state *state);
 };
 
 /**
index a421cb5536202114c31a84a43d40e9f269600333..63d4e5051936a08e28da2c9cf41772bcd4ad4c31 100644 (file)
@@ -28,6 +28,7 @@
 #include <drm/drm_mode_object.h>
 
 struct drm_crtc;
+struct drm_printer;
 
 /**
  * struct drm_plane_state - mutable plane state
@@ -370,6 +371,18 @@ struct drm_plane_funcs {
         * before data structures are torndown.
         */
        void (*early_unregister)(struct drm_plane *plane);
+
+       /**
+        * @atomic_print_state:
+        *
+        * If driver subclasses struct &drm_plane_state, it should implement
+        * this optional hook for printing additional driver specific state.
+        *
+        * Do not call this directly, use drm_atomic_plane_print_state()
+        * instead.
+        */
+       void (*atomic_print_state)(struct drm_printer *p,
+                                  const struct drm_plane_state *state);
 };
 
 /**