@@ -319,6 +319,7 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state,
DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
crtc->base.id, crtc->name, crtc_state, state);
+ drm_trace(crtc, add, crtc_state);
return crtc_state;
}
@@ -340,6 +341,8 @@ static int drm_atomic_crtc_check(const struct drm_crtc_state *old_crtc_state,
if (new_crtc_state->active && !new_crtc_state->enable) {
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active without enabled\n",
crtc->base.id, crtc->name);
+ drm_trace_err(crtc, check_fail_active_not_enabled,
+ new_crtc_state);
return -EINVAL;
}
@@ -350,6 +353,7 @@ static int drm_atomic_crtc_check(const struct drm_crtc_state *old_crtc_state,
WARN_ON(new_crtc_state->enable && !new_crtc_state->mode_blob)) {
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled without mode blob\n",
crtc->base.id, crtc->name);
+ drm_trace_err(crtc, check_fail_enable_no_mode, new_crtc_state);
return -EINVAL;
}
@@ -357,6 +361,7 @@ static int drm_atomic_crtc_check(const struct drm_crtc_state *old_crtc_state,
WARN_ON(!new_crtc_state->enable && new_crtc_state->mode_blob)) {
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] disabled with mode blob\n",
crtc->base.id, crtc->name);
+ drm_trace_err(crtc, check_fail_mode_no_enable, new_crtc_state);
return -EINVAL;
}
@@ -374,9 +379,12 @@ static int drm_atomic_crtc_check(const struct drm_crtc_state *old_crtc_state,
!new_crtc_state->active && !old_crtc_state->active) {
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requesting event but off\n",
crtc->base.id, crtc->name);
+ drm_trace_err(crtc, check_fail_event_not_active,
+ new_crtc_state);
return -EINVAL;
}
+ drm_trace(crtc, check_passed, new_crtc_state);
return 0;
}
@@ -1057,6 +1065,8 @@ drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d:%s] to %p\n",
crtc->base.id, crtc->name, state);
+ drm_trace(crtc, add_affected_connectors, crtc_state);
+
/*
* Changed connectors are already in @state, so only need to look
@@ -1111,6 +1121,7 @@ drm_atomic_add_affected_planes(struct drm_atomic_state *state,
DRM_DEBUG_ATOMIC("Adding all current planes for [CRTC:%d:%s] to %p\n",
crtc->base.id, crtc->name, state);
+ drm_trace(crtc, add_affected_planes, old_crtc_state);
drm_for_each_plane_mask(plane, state->dev, old_crtc_state->plane_mask) {
struct drm_plane_state *plane_state =
@@ -1165,6 +1176,7 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
if (ret) {
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic core check failed\n",
crtc->base.id, crtc->name);
+ drm_trace_err(crtc, check_failed, new_crtc_state);
return ret;
}
}
@@ -1194,6 +1206,8 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requires full modeset\n",
crtc->base.id, crtc->name);
+ drm_trace_err(crtc, check_fail_modeset_required,
+ new_crtc_state);
return -EINVAL;
}
}
@@ -3,6 +3,7 @@
#define _DRM_TRACE_H_
#include <drm/drm_atomic.h>
+#include <drm/drm_crtc.h>
#include <linux/kref.h>
#include <linux/stringify.h>
@@ -68,6 +69,12 @@ enum drm_trace_event_class {
* atomic state from alloc to free and everywhere in between.
*/
drm_trace_class_atomic = BIT(2),
+
+ /**
+ * @drm_trace_class_crtc: This class is used to track crtc state through
+ * the atomic core and helpers.
+ */
+ drm_trace_class_crtc = BIT(3),
};
/**
@@ -234,6 +241,108 @@ DEFINE_EVENT(class_drm_atomic, drm_atomic_check_failed,
TP_ARGS(event_class, state)
);
+DECLARE_EVENT_CLASS(class_drm_crtc,
+ TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state),
+ TP_ARGS(event_class, state),
+ TP_STRUCT__entry(
+ __field(unsigned int, event_class)
+ __field(const struct drm_atomic_state *, state)
+ __field(const struct drm_crtc_state *, crtc_state)
+ __field(const struct drm_crtc_commit *, commit)
+ __field(uint32_t, crtc_id)
+ __field(bool, enable)
+ __field(bool, active)
+ __field(bool, planes_changed)
+ __field(bool, mode_changed)
+ __field(bool, active_changed)
+ __field(bool, connectors_changed)
+ __field(bool, zpos_changed)
+ __field(bool, color_mgmt_changed)
+ __field(bool, no_vblank)
+ __field(bool, async_flip)
+ __field(bool, vrr_enabled)
+ __field(bool, self_refresh_active)
+ __field(u32, plane_mask)
+ __field(u32, connector_mask)
+ __field(u32, encoder_mask)
+ ),
+ TP_fast_assign(
+ __entry->event_class = event_class;
+ __entry->state = state->state;
+ __entry->crtc_state = state;
+ __entry->crtc_id = state->crtc->base.id;
+ __entry->commit = state->commit;
+ __entry->enable = state->enable;
+ __entry->active = state->active;
+ __entry->planes_changed = state->planes_changed;
+ __entry->mode_changed = state->mode_changed;
+ __entry->active_changed = state->active_changed;
+ __entry->connectors_changed = state->connectors_changed;
+ __entry->zpos_changed = state->zpos_changed;
+ __entry->color_mgmt_changed = state->color_mgmt_changed;
+ __entry->no_vblank = state->no_vblank;
+ __entry->async_flip = state->async_flip;
+ __entry->vrr_enabled = state->vrr_enabled;
+ __entry->self_refresh_active = state->self_refresh_active;
+ __entry->plane_mask = state->plane_mask;
+ __entry->connector_mask = state->connector_mask;
+ __entry->encoder_mask = state->encoder_mask;
+ ),
+ TP_printk("crtc_id=%u crtc_state=%pK state=%pK commit=%pK changed("
+ "planes=%d mode=%d active=%d conn=%d zpos=%d color_mgmt=%d) "
+ "state(enable=%d active=%d async_flip=%d vrr_enabled=%d "
+ "self_refresh_active=%d no_vblank=%d) mask(plane=%x conn=%x "
+ "enc=%x)",
+ __entry->crtc_id, __entry->crtc_state, __entry->state,
+ __entry->commit, __entry->planes_changed,
+ __entry->mode_changed, __entry->active_changed,
+ __entry->connectors_changed, __entry->zpos_changed,
+ __entry->color_mgmt_changed, __entry->enable, __entry->active,
+ __entry->async_flip, __entry->vrr_enabled,
+ __entry->self_refresh_active, __entry->no_vblank,
+ __entry->plane_mask, __entry->connector_mask,
+ __entry->encoder_mask)
+);
+DEFINE_EVENT(class_drm_crtc, drm_crtc_add,
+ TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state),
+ TP_ARGS(event_class, state)
+);
+DEFINE_EVENT(class_drm_crtc, drm_crtc_check_passed,
+ TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state),
+ TP_ARGS(event_class, state)
+);
+DEFINE_EVENT(class_drm_crtc, drm_crtc_check_failed,
+ TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state),
+ TP_ARGS(event_class, state)
+);
+DEFINE_EVENT(class_drm_crtc, drm_crtc_check_fail_active_not_enabled,
+ TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state),
+ TP_ARGS(event_class, state)
+);
+DEFINE_EVENT(class_drm_crtc, drm_crtc_check_fail_enable_no_mode,
+ TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state),
+ TP_ARGS(event_class, state)
+);
+DEFINE_EVENT(class_drm_crtc, drm_crtc_check_fail_mode_no_enable,
+ TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state),
+ TP_ARGS(event_class, state)
+);
+DEFINE_EVENT(class_drm_crtc, drm_crtc_check_fail_event_not_active,
+ TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state),
+ TP_ARGS(event_class, state)
+);
+DEFINE_EVENT(class_drm_crtc, drm_crtc_check_fail_modeset_required,
+ TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state),
+ TP_ARGS(event_class, state)
+);
+DEFINE_EVENT(class_drm_crtc, drm_crtc_add_affected_connectors,
+ TP_PROTO(unsigned int event_class, const struct drm_crtc_state *state),
+ TP_ARGS(event_class, state)
+);
+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)
+);
#endif /* _DRM_TRACE_H_ */
/* This part must be outside protection */