[5/6] drm: trace: Add connector state tracing
diff mbox series

Message ID 20191107210316.143216-6-sean@poorly.run
State New
Headers show
Series
  • drm: trace: Introduce drm_trace() and instrument drm_atomic.c
Related show

Commit Message

Sean Paul Nov. 7, 2019, 9:03 p.m. UTC
From: Sean Paul <seanpaul@chromium.org>

Add tracing which tracks important connector_state events through the atomic
core.

Signed-off-by: Sean Paul <seanpaul@chromium.org>
---
 drivers/gpu/drm/drm_atomic.c |  12 ++++-
 drivers/gpu/drm/drm_trace.h  | 101 +++++++++++++++++++++++++++++++++++
 2 files changed, 112 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 955650729115d..5dcaf145f22ff 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -422,12 +422,15 @@  static int drm_atomic_connector_check(struct drm_connector *connector,
 	if (connector->max_bpc_property)
 		state->max_bpc = min(state->max_bpc, state->max_requested_bpc);
 
-	if ((connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) || !writeback_job)
+	if ((connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) || !writeback_job) {
+		drm_trace(connector, check_passed, state);
 		return 0;
+	}
 
 	if (writeback_job->fb && !state->crtc) {
 		DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] framebuffer without CRTC\n",
 				 connector->base.id, connector->name);
+		drm_trace_err(connector, check_fail_writeback_no_crtc, state);
 		return -EINVAL;
 	}
 
@@ -439,6 +442,8 @@  static int drm_atomic_connector_check(struct drm_connector *connector,
 		DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] has framebuffer, but [CRTC:%d] is off\n",
 				 connector->base.id, connector->name,
 				 state->crtc->base.id);
+		drm_trace_err(connector, check_fail_writeback_not_active,
+			      state);
 		return -EINVAL;
 	}
 
@@ -446,6 +451,8 @@  static int drm_atomic_connector_check(struct drm_connector *connector,
 		if (writeback_job->out_fence) {
 			DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] requesting out-fence without framebuffer\n",
 					 connector->base.id, connector->name);
+			drm_trace_err(connector,
+				      check_fail_writeback_fence_no_fb, state);
 			return -EINVAL;
 		}
 
@@ -453,6 +460,7 @@  static int drm_atomic_connector_check(struct drm_connector *connector,
 		state->writeback_job = NULL;
 	}
 
+	drm_trace(connector, check_passed, state);
 	return 0;
 }
 
@@ -996,6 +1004,7 @@  drm_atomic_get_connector_state(struct drm_atomic_state *state,
 	DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d:%s] %p state to %p\n",
 			 connector->base.id, connector->name,
 			 connector_state, state);
+	drm_trace(connector, add, connector_state);
 
 	if (connector_state->crtc) {
 		struct drm_crtc_state *crtc_state;
@@ -1186,6 +1195,7 @@  int drm_atomic_check_only(struct drm_atomic_state *state)
 		if (ret) {
 			DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] atomic core check failed\n",
 					 conn->base.id, conn->name);
+			drm_trace_err(connector, check_failed, conn_state);
 			return ret;
 		}
 	}
diff --git a/drivers/gpu/drm/drm_trace.h b/drivers/gpu/drm/drm_trace.h
index 91880f650a7b3..c610e8d8c71ce 100644
--- a/drivers/gpu/drm/drm_trace.h
+++ b/drivers/gpu/drm/drm_trace.h
@@ -3,7 +3,9 @@ 
 #define _DRM_TRACE_H_
 
 #include <drm/drm_atomic.h>
+#include <drm/drm_connector.h>
 #include <drm/drm_crtc.h>
+#include <drm/drm_encoder.h>
 
 #include <linux/kref.h>
 #include <linux/stringify.h>
@@ -75,6 +77,12 @@  enum drm_trace_event_class {
 	 * the atomic core and helpers.
 	 */
 	drm_trace_class_crtc		= BIT(3),
+
+	/**
+	 * @drm_trace_class_connector: This class is used to track connector
+	 * state through the atomic core and helpers.
+	 */
+	drm_trace_class_connector	= BIT(4),
 };
 
 /**
@@ -343,6 +351,99 @@  DEFINE_EVENT(class_drm_crtc, drm_crtc_add_affected_planes,
 	TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state),
 	TP_ARGS(event_class, state)
 );
+
+DECLARE_EVENT_CLASS(class_drm_connector,
+	TP_PROTO(unsigned int event_class,
+		 const struct drm_connector_state *state),
+	TP_ARGS(event_class, state),
+	TP_STRUCT__entry(
+		__field(unsigned int, event_class)
+		__field(uint32_t, conn_id)
+		__field(const struct drm_connector_state *, conn_state)
+		__field(const struct drm_atomic_state *, state)
+		__field(const struct drm_crtc_commit *, commit)
+		__field(uint32_t, crtc_id)
+		__field(uint32_t, best_encoder_id)
+		__field(enum drm_link_status, link_status)
+		__field(bool, self_refresh_aware)
+		__field(enum hdmi_picture_aspect, picture_aspect_ratio)
+		__field(unsigned int, content_type)
+		__field(unsigned int, hdcp_content_type)
+		__field(unsigned int, content_protection)
+		__field(unsigned int, scaling_mode)
+		__field(u32, colorspace)
+		__field(const struct drm_writeback_job *, writeback_job)
+		__field(u8, max_requested_bpc)
+		__field(u8, max_bpc)
+	),
+	TP_fast_assign(
+		__entry->event_class = event_class;
+		__entry->conn_id = state->connector->base.id;
+		__entry->conn_state = state;
+		__entry->state = state->state;
+		__entry->commit = state->commit;
+		__entry->crtc_id = state->crtc ? state->crtc->base.id : 0;
+		__entry->best_encoder_id = state->best_encoder ?
+					   state->best_encoder->base.id : 0;
+		__entry->link_status = state->link_status;
+		__entry->self_refresh_aware = state->self_refresh_aware;
+		__entry->picture_aspect_ratio= state->picture_aspect_ratio;
+		__entry->content_type = state->content_type;
+		__entry->hdcp_content_type = state->hdcp_content_type;
+		__entry->content_protection = state->content_protection;
+		__entry->scaling_mode = state->scaling_mode;
+		__entry->colorspace = state->colorspace;
+		__entry->writeback_job = state->writeback_job;
+		__entry->max_requested_bpc = state->max_requested_bpc;
+		__entry->max_bpc = state->max_bpc;
+	),
+	TP_printk("conn_id=%u conn_state=%pK state=%pK commit=%pK crtc_id=%u "
+		  "best_encoder_id=%u link_status=%d self_refresh_aware=%d "
+		  "picture_aspect_ratio=%d content_type=%u "
+		  "hdcp_content_type=%u content_protection=%u scaling_mode=%u "
+		  "colorspace=%u writeback_job=%pK max_requested_bpc=%u "
+		  "max_bpc=%u",
+		  __entry->conn_id, __entry->conn_state, __entry->state,
+		  __entry->commit, __entry->crtc_id, __entry->best_encoder_id,
+		  __entry->link_status, __entry->self_refresh_aware,
+		  __entry->picture_aspect_ratio, __entry->content_type,
+		  __entry->hdcp_content_type, __entry->content_protection,
+		  __entry->scaling_mode, __entry->colorspace,
+		  __entry->writeback_job, __entry->max_requested_bpc,
+		  __entry->max_bpc)
+);
+DEFINE_EVENT(class_drm_connector, drm_connector_add,
+	TP_PROTO(unsigned int event_class,
+		 const struct drm_connector_state *state),
+	TP_ARGS(event_class, state)
+);
+DEFINE_EVENT(class_drm_connector, drm_connector_check_passed,
+	TP_PROTO(unsigned int event_class,
+		 const struct drm_connector_state *state),
+	TP_ARGS(event_class, state)
+);
+DEFINE_EVENT(class_drm_connector, drm_connector_check_failed,
+	TP_PROTO(unsigned int event_class,
+		 const struct drm_connector_state *state),
+	TP_ARGS(event_class, state)
+);
+DEFINE_EVENT(class_drm_connector, drm_connector_check_fail_writeback_no_crtc,
+	TP_PROTO(unsigned int event_class,
+		 const struct drm_connector_state *state),
+	TP_ARGS(event_class, state)
+);
+DEFINE_EVENT(class_drm_connector, drm_connector_check_fail_writeback_not_active,
+	TP_PROTO(unsigned int event_class,
+		 const struct drm_connector_state *state),
+	TP_ARGS(event_class, state)
+);
+DEFINE_EVENT(class_drm_connector,
+	     drm_connector_check_fail_writeback_fence_no_fb,
+	TP_PROTO(unsigned int event_class,
+		 const struct drm_connector_state *state),
+	TP_ARGS(event_class, state)
+);
+
 #endif /* _DRM_TRACE_H_ */
 
 /* This part must be outside protection */