Merge drm/drm-next into drm-intel-next-queued
[sfrench/cifs-2.6.git] / drivers / gpu / drm / drm_atomic_state_helper.c
index 59ffb6b9c74537d00cf70a753c605b30e83ddc5b..46dc264a248bf6d273b03c4b8db2a69b17539419 100644 (file)
  * Daniel Vetter <daniel.vetter@ffwll.ch>
  */
 
+#include <drm/drm_atomic.h>
 #include <drm/drm_atomic_state_helper.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_plane.h>
 #include <drm/drm_connector.h>
-#include <drm/drm_atomic.h>
+#include <drm/drm_crtc.h>
 #include <drm/drm_device.h>
+#include <drm/drm_plane.h>
+#include <drm/drm_print.h>
 #include <drm/drm_writeback.h>
 
 #include <linux/slab.h>
  * for these functions.
  */
 
+/**
+ * __drm_atomic_helper_crtc_reset - reset state on CRTC
+ * @crtc: drm CRTC
+ * @crtc_state: CRTC state to assign
+ *
+ * Initializes the newly allocated @crtc_state and assigns it to
+ * the &drm_crtc->state pointer of @crtc, usually required when
+ * initializing the drivers or when called from the &drm_crtc_funcs.reset
+ * hook.
+ *
+ * This is useful for drivers that subclass the CRTC state.
+ */
+void
+__drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
+                              struct drm_crtc_state *crtc_state)
+{
+       if (crtc_state)
+               crtc_state->crtc = crtc;
+
+       crtc->state = crtc_state;
+}
+EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset);
+
 /**
  * drm_atomic_helper_crtc_reset - default &drm_crtc_funcs.reset hook for CRTCs
  * @crtc: drm CRTC
  */
 void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
 {
-       if (crtc->state)
-               __drm_atomic_helper_crtc_destroy_state(crtc->state);
-
-       kfree(crtc->state);
-       crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL);
+       struct drm_crtc_state *crtc_state =
+               kzalloc(sizeof(*crtc->state), GFP_KERNEL);
 
        if (crtc->state)
-               crtc->state->crtc = crtc;
+               crtc->funcs->atomic_destroy_state(crtc, crtc->state);
+
+       __drm_atomic_helper_crtc_reset(crtc, crtc_state);
 }
 EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
 
@@ -106,6 +129,10 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
        state->commit = NULL;
        state->event = NULL;
        state->pageflip_flags = 0;
+
+       /* Self refresh should be canceled when a new update is available */
+       state->active = drm_atomic_crtc_effectively_active(state);
+       state->self_refresh_active = false;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
 
@@ -314,7 +341,7 @@ EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
  * @conn_state: connector state to assign
  *
  * Initializes the newly allocated @conn_state and assigns it to
- * the &drm_conector->state pointer of @connector, usually required when
+ * the &drm_connector->state pointer of @connector, usually required when
  * initializing the drivers or when called from the &drm_connector_funcs.reset
  * hook.
  *
@@ -352,6 +379,24 @@ void drm_atomic_helper_connector_reset(struct drm_connector *connector)
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
 
+/**
+ * drm_atomic_helper_connector_tv_reset - Resets TV connector properties
+ * @connector: DRM connector
+ *
+ * Resets the TV-related properties attached to a connector.
+ */
+void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
+{
+       struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
+       struct drm_connector_state *state = connector->state;
+
+       state->tv.margins.left = cmdline->tv_margins.left;
+       state->tv.margins.right = cmdline->tv_margins.right;
+       state->tv.margins.top = cmdline->tv_margins.top;
+       state->tv.margins.bottom = cmdline->tv_margins.bottom;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
+
 /**
  * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
  * @connector: connector object
@@ -369,6 +414,9 @@ __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
                drm_connector_get(connector);
        state->commit = NULL;
 
+       if (state->hdr_output_metadata)
+               drm_property_blob_get(state->hdr_output_metadata);
+
        /* Don't copy over a writeback job, they are used only once */
        state->writeback_job = NULL;
 }
@@ -416,6 +464,8 @@ __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
 
        if (state->writeback_job)
                drm_writeback_cleanup_job(state->writeback_job);
+
+       drm_property_blob_put(state->hdr_output_metadata);
 }
 EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);