From: Sean Paul <seanpaul@xxxxxxxxxxxx> Add tracing which tracks important connector_state events through the atomic core. Signed-off-by: Sean Paul <seanpaul@xxxxxxxxxxxx> --- drivers/gpu/drm/drm_atomic.c | 12 ++++- drivers/gpu/drm/drm_trace.h | 101 +++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) 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 */ -- Sean Paul, Software Engineer, Google / Chromium OS _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel