drm/atomic: Add current-mode blob to CRTC state

Add a blob property tracking the current mode to the CRTC state, and
ensure it is properly updated and referenced.

v2: Continue using crtc_state->mode inside getcrtc, instead of reading
    out the mode blob. Use IS_ERR and PTR_ERR from create_blob. Move
    set_mode_prop_for_crtc to later patch where it actually gets used.
    Enforce !!state->enable == !!state->mode_blob inside
    drm_atomic_crtc_check.

Signed-off-by: Daniel Stone <daniels@collabora.com>
Tested-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index e69d484..a900858 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2044,6 +2044,8 @@
  */
 void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
 {
+	if (crtc->state && crtc->state->mode_blob)
+		drm_property_unreference_blob(crtc->state->mode_blob);
 	kfree(crtc->state);
 	crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL);
 
@@ -2065,6 +2067,8 @@
 {
 	memcpy(state, crtc->state, sizeof(*state));
 
+	if (state->mode_blob)
+		drm_property_reference_blob(state->mode_blob);
 	state->mode_changed = false;
 	state->active_changed = false;
 	state->planes_changed = false;
@@ -2107,11 +2111,8 @@
 void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
 					    struct drm_crtc_state *state)
 {
-	/*
-	 * This is currently a placeholder so that drivers that subclass the
-	 * state will automatically do the right thing if code is ever added
-	 * to this function.
-	 */
+	if (state->mode_blob)
+		drm_property_unreference_blob(state->mode_blob);
 }
 EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);