Add a transitional helper for planes' .set_property() entrypoint,
similar to what we already have for .update_plane() and
.disable_plane().  This allows drivers that are still in the process of
transitioning to implement and exercise the .atomic_set_property()
driver entrypoint that will eventually be used by atomic.

Cc: dri-de...@lists.freedesktop.org
Signed-off-by: Matt Roper <matthew.d.ro...@intel.com>
---
 drivers/gpu/drm/drm_plane_helper.c | 105 +++++++++++++++++++++++++++++++++++++
 include/drm/drm_plane_helper.h     |   3 ++
 2 files changed, 108 insertions(+)

diff --git a/drivers/gpu/drm/drm_plane_helper.c 
b/drivers/gpu/drm/drm_plane_helper.c
index 7a5814a..0dce064 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -586,3 +586,108 @@ int drm_plane_helper_disable(struct drm_plane *plane)
        return drm_plane_helper_commit(plane, plane_state, plane->fb);
 }
 EXPORT_SYMBOL(drm_plane_helper_disable);
+
+/**
+ * drm_plane_helper_set_property() - Transitional helper for property updates
+ * @plane: plane object to update
+ * @prop: property to update
+ * @val: value to set property to
+ *
+ * Provides a default plane property handler using the atomic plane update
+ * functions.  Drivers in the process of transitioning to atomic should
+ * replace their plane.set_property() entrypoint with this function and
+ * then implement the plane.atomic_set_property() entrypoint.
+ *
+ * This is useful for piecewise transitioning of a driver to the atomic 
helpers.
+ *
+ * Note that this helper assumes that no hardware programming should be
+ * performed if the plane is disabled.  When the plane is not attached to a
+ * crtc, we just swap in the validated plane state and return; there's no
+ * call to atomic_begin()/atomic_update()/atomic_flush().
+ *
+ * RETURNS:
+ * Zero on success, error code on failure
+ */
+int drm_plane_helper_set_property(struct drm_plane *plane,
+                                 struct drm_property *prop,
+                                 uint64_t val)
+{
+       struct drm_plane_state *plane_state;
+       struct drm_plane_helper_funcs *plane_funcs = plane->helper_private;
+       struct drm_crtc_helper_funcs *crtc_funcs;
+       int ret;
+
+       /*
+        * Drivers may not have an .atomic_set_property() handler if they have
+        * no driver-specific properties, but they generally wouldn't setup a
+        * .set_property() handler (pointing to this function) for the plane in
+        * that case either; throw a warning since this is probably a mistake.
+        */
+       if (WARN_ON(!plane->funcs->atomic_set_property))
+               return -EINVAL;
+
+       if (plane->funcs->atomic_duplicate_state)
+               plane_state = plane->funcs->atomic_duplicate_state(plane);
+       else if (plane->state)
+               plane_state = drm_atomic_helper_plane_duplicate_state(plane);
+       else
+               plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL);
+       if (!plane_state)
+               return -ENOMEM;
+       plane_state->plane = plane;
+
+       /*
+        * Update the state object with the new property value we want to
+        * set.  If the property is not recognized as a driver-specific 
property,
+        * -EINVAL will be returned here.
+        */
+       ret = plane->funcs->atomic_set_property(plane, plane_state, prop, val);
+       if (ret)
+               goto out;
+
+       /*
+        * Check that the updated plane state is actually programmable (e.g.,
+        * doesn't violate hardware constraints).
+        */
+       if (plane_funcs->atomic_check) {
+               ret = plane_funcs->atomic_check(plane, plane_state);
+               if (ret)
+                       goto out;
+       }
+
+       /* Point of no return, commit sw state. */
+       swap(plane->state, plane_state);
+
+       /*
+        * If the plane is disabled, we're done.  No hardware programming is
+        * attempted when the plane is disabled.
+        */
+       if (!plane->crtc)
+               goto out;
+
+       /* Start hardware transaction to commit new state to hardware */
+       crtc_funcs = plane->crtc->helper_private;
+       if (crtc_funcs && crtc_funcs->atomic_begin)
+               crtc_funcs->atomic_begin(plane->crtc);
+       plane_funcs->atomic_update(plane, plane_state);
+       if (crtc_funcs && crtc_funcs->atomic_flush)
+               crtc_funcs->atomic_flush(plane->crtc);
+
+       /*
+        * Since we're not using full atomic yet, we still need to update the 
shadow
+        * property value that's managed by the DRM core since that's where the
+        * property values will be read back from.
+        */
+       drm_object_property_set_value(&plane->base, prop, val);
+
+out:
+       if (plane_state) {
+               if (plane->funcs->atomic_destroy_state)
+                       plane->funcs->atomic_destroy_state(plane, plane_state);
+               else
+                       drm_atomic_helper_plane_destroy_state(plane, 
plane_state);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(drm_plane_helper_set_property);
diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h
index a185392..4a56961 100644
--- a/include/drm/drm_plane_helper.h
+++ b/include/drm/drm_plane_helper.h
@@ -107,6 +107,9 @@ int drm_plane_helper_update(struct drm_plane *plane, struct 
drm_crtc *crtc,
                            uint32_t src_x, uint32_t src_y,
                            uint32_t src_w, uint32_t src_h);
 int drm_plane_helper_disable(struct drm_plane *plane);
+int drm_plane_helper_set_property(struct drm_plane *plane,
+                                 struct drm_property *prop,
+                                 uint64_t val);
 
 /* For use by drm_crtc_helper.c */
 int drm_plane_helper_commit(struct drm_plane *plane,
-- 
1.8.5.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to