drm/vmwgfx: CRTC atomic state
authorSinclair Yeh <syeh@vmware.com>
Thu, 23 Mar 2017 18:33:39 +0000 (11:33 -0700)
committerSinclair Yeh <syeh@vmware.com>
Fri, 31 Mar 2017 16:13:08 +0000 (09:13 -0700)
Create and Add CRTC state.  We currently do not track any properties
or custom states so we can technically use the DRM helpers.  Creating
this code just to make potential future additions easier.

Most of the new code will be compiled but not enabled until
plane/connector state handling code is also in place.

This is the first of a series to enable atomic mode set for vmwgfx.

The atomic enabling effort was done in collaboration with Thomas
Hellstrom and the VMware Graphics Team.

Signed-off-by: Sinclair Yeh <syeh@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c

index c9f5ddabfb72fcda85b73bff23185d0fd49888a6..18bd8dc46507b2ef1dff3ee88fc0088673ae0c67 100644 (file)
@@ -26,6 +26,8 @@
  **************************************************************************/
 
 #include "vmwgfx_kms.h"
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
 
 
 /* Might need a hrtimer here? */
@@ -388,6 +390,84 @@ void vmw_du_primary_plane_destroy(struct drm_plane *plane)
 }
 
 
+/**
+ * vmw_du_crtc_duplicate_state - duplicate crtc state
+ * @crtc: DRM crtc
+ *
+ * Allocates and returns a copy of the crtc state (both common and
+ * vmw-specific) for the specified crtc.
+ *
+ * Returns: The newly allocated crtc state, or NULL on failure.
+ */
+struct drm_crtc_state *
+vmw_du_crtc_duplicate_state(struct drm_crtc *crtc)
+{
+       struct drm_crtc_state *state;
+       struct vmw_crtc_state *vcs;
+
+       if (WARN_ON(!crtc->state))
+               return NULL;
+
+       vcs = kmemdup(crtc->state, sizeof(*vcs), GFP_KERNEL);
+
+       if (!vcs)
+               return NULL;
+
+       state = &vcs->base;
+
+       __drm_atomic_helper_crtc_duplicate_state(crtc, state);
+
+       return state;
+}
+
+
+/**
+ * vmw_du_crtc_reset - creates a blank vmw crtc state
+ * @crtc: DRM crtc
+ *
+ * Resets the atomic state for @crtc by freeing the state pointer (which
+ * might be NULL, e.g. at driver load time) and allocating a new empty state
+ * object.
+ */
+void vmw_du_crtc_reset(struct drm_crtc *crtc)
+{
+       struct vmw_crtc_state *vcs;
+
+
+       if (crtc->state) {
+               __drm_atomic_helper_crtc_destroy_state(crtc->state);
+
+               kfree(vmw_crtc_state_to_vcs(crtc->state));
+       }
+
+       vcs = kzalloc(sizeof(*vcs), GFP_KERNEL);
+
+       if (!vcs) {
+               DRM_ERROR("Cannot allocate vmw_crtc_state\n");
+               return;
+       }
+
+       crtc->state = &vcs->base;
+       crtc->state->crtc = crtc;
+}
+
+
+/**
+ * vmw_du_crtc_destroy_state - destroy crtc state
+ * @crtc: DRM crtc
+ * @state: state object to destroy
+ *
+ * Destroys the crtc state (both common and vmw-specific) for the
+ * specified plane.
+ */
+void
+vmw_du_crtc_destroy_state(struct drm_crtc *crtc,
+                         struct drm_crtc_state *state)
+{
+       drm_atomic_helper_crtc_destroy_state(crtc, state);
+}
+
+
 /*
  * Generic framebuffer code
  */
@@ -1600,6 +1680,7 @@ int vmw_du_connector_set_property(struct drm_connector *connector,
 }
 
 
+
 int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
                                struct drm_file *file_priv)
 {
index e400bfb26167eb431b4ebe24bc636b7c3795c754..370f75c95f5635c7123d6f912b268c22c3425150 100644 (file)
@@ -139,6 +139,19 @@ static const uint32_t vmw_cursor_plane_formats[] = {
        DRM_FORMAT_ARGB8888,
 };
 
+
+#define vmw_crtc_state_to_vcs(x) container_of(x, struct vmw_crtc_state, base)
+
+
+/**
+ * Derived class for crtc state object
+ *
+ * @base DRM crtc object
+ */
+struct vmw_crtc_state {
+       struct drm_crtc_state base;
+};
+
 /**
  * Base class display unit.
  *
@@ -205,6 +218,9 @@ int vmw_du_crtc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
                            uint32_t handle, uint32_t width, uint32_t height,
                            int32_t hot_x, int32_t hot_y);
 int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
+int vmw_du_connector_set_property(struct drm_connector *connector,
+                                 struct drm_property *property,
+                                 uint64_t val);
 int vmw_du_connector_dpms(struct drm_connector *connector, int mode);
 void vmw_du_connector_save(struct drm_connector *connector);
 void vmw_du_connector_restore(struct drm_connector *connector);
@@ -212,9 +228,6 @@ enum drm_connector_status
 vmw_du_connector_detect(struct drm_connector *connector, bool force);
 int vmw_du_connector_fill_modes(struct drm_connector *connector,
                                uint32_t max_width, uint32_t max_height);
-int vmw_du_connector_set_property(struct drm_connector *connector,
-                                 struct drm_property *property,
-                                 uint64_t val);
 int vmw_kms_helper_dirty(struct vmw_private *dev_priv,
                         struct vmw_framebuffer *framebuffer,
                         const struct drm_clip_rect *clips,
@@ -285,6 +298,10 @@ int vmw_du_cursor_plane_update(struct drm_plane *plane,
                               uint32_t src_x, uint32_t src_y,
                               uint32_t src_w, uint32_t src_h);
 
+void vmw_du_crtc_reset(struct drm_crtc *crtc);
+struct drm_crtc_state *vmw_du_crtc_duplicate_state(struct drm_crtc *crtc);
+void vmw_du_crtc_destroy_state(struct drm_crtc *crtc,
+                               struct drm_crtc_state *state);
 
 /*
  * Legacy display unit functions - vmwgfx_ldu.c
index 3efcbe5144724322d46c892a46c1ed38de584e60..3ee33f0234e4eb6582824db93bd0040b0d1641fc 100644 (file)
@@ -280,6 +280,9 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set)
 static const struct drm_crtc_funcs vmw_legacy_crtc_funcs = {
        .gamma_set = vmw_du_crtc_gamma_set,
        .destroy = vmw_ldu_crtc_destroy,
+       .reset = vmw_du_crtc_reset,
+       .atomic_duplicate_state = vmw_du_crtc_duplicate_state,
+       .atomic_destroy_state = vmw_du_crtc_destroy_state,
        .set_config = vmw_ldu_crtc_set_config,
 };
 
@@ -355,6 +358,11 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
        ldu->base.pref_width = dev_priv->initial_width;
        ldu->base.pref_height = dev_priv->initial_height;
        ldu->base.pref_mode = NULL;
+
+       /*
+        * Remove this after enabling atomic because property values can
+        * only exist in a state object
+        */
        ldu->base.is_implicit = true;
 
        /* Initialize primary plane */
@@ -405,6 +413,8 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
                goto err_free_encoder;
        }
 
+       /* FIXME: Turn on after plane/connector states are implemented. */
+       /* vmw_du_crtc_reset(crtc); */
        ret = drm_crtc_init_with_planes(dev, crtc, &ldu->base.primary,
                                        &ldu->base.cursor,
                                        &vmw_legacy_crtc_funcs, NULL);
index 8ffccb87cf3aad732a2d81b609280b246c1d4b50..033e17b966b1d07b9b1305e00e96d7d6a3da8f50 100644 (file)
@@ -461,6 +461,9 @@ out_no_fence:
 static const struct drm_crtc_funcs vmw_screen_object_crtc_funcs = {
        .gamma_set = vmw_du_crtc_gamma_set,
        .destroy = vmw_sou_crtc_destroy,
+       .reset = vmw_du_crtc_reset,
+       .atomic_duplicate_state = vmw_du_crtc_duplicate_state,
+       .atomic_destroy_state = vmw_du_crtc_destroy_state,
        .set_config = vmw_sou_crtc_set_config,
        .page_flip = vmw_sou_crtc_page_flip,
 };
@@ -535,6 +538,11 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
        sou->base.pref_width = dev_priv->initial_width;
        sou->base.pref_height = dev_priv->initial_height;
        sou->base.pref_mode = NULL;
+
+       /*
+        * Remove this after enabling atomic because property values can
+        * only exist in a state object
+        */
        sou->base.is_implicit = false;
 
        /* Initialize primary plane */
@@ -586,6 +594,8 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
                goto err_free_encoder;
        }
 
+       /* FIXME: Turn on after plane/connector states are implemented. */
+       /* vmw_du_crtc_reset(crtc); */
        ret = drm_crtc_init_with_planes(dev, crtc, &sou->base.primary,
                                        &sou->base.cursor,
                                        &vmw_screen_object_crtc_funcs, NULL);
index 4d9dd1b67b93b10e710508d17ac00729ee7a4c1d..3b8fafe1586e2574873e0691822fbf0d06ec7114 100644 (file)
@@ -1017,6 +1017,9 @@ out_finish:
 static const struct drm_crtc_funcs vmw_stdu_crtc_funcs = {
        .gamma_set = vmw_du_crtc_gamma_set,
        .destroy = vmw_stdu_crtc_destroy,
+       .reset = vmw_du_crtc_reset,
+       .atomic_duplicate_state = vmw_du_crtc_duplicate_state,
+       .atomic_destroy_state = vmw_du_crtc_destroy_state,
        .set_config = vmw_stdu_crtc_set_config,
        .page_flip = vmw_stdu_crtc_page_flip,
 };
@@ -1131,6 +1134,11 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit)
        stdu->base.pref_active = (unit == 0);
        stdu->base.pref_width  = dev_priv->initial_width;
        stdu->base.pref_height = dev_priv->initial_height;
+
+       /*
+        * Remove this after enabling atomic because property values can
+        * only exist in a state object
+        */
        stdu->base.is_implicit = false;
 
        /* Initialize primary plane */
@@ -1181,6 +1189,8 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit)
                goto err_free_encoder;
        }
 
+       /* FIXME: Turn on after plane/connector states are implemented. */
+       /* vmw_du_crtc_reset(crtc); */
        ret = drm_crtc_init_with_planes(dev, crtc, &stdu->base.primary,
                                        &stdu->base.cursor,
                                        &vmw_stdu_crtc_funcs, NULL);