drm/atomic: document how to handle driver private objects
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 14 Dec 2017 20:30:53 +0000 (21:30 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 15 Dec 2017 10:26:54 +0000 (11:26 +0100)
DK put some nice docs into the commit introducing driver private
state, but in the git history alone it'll be lost.

Also, since Ville remove the void* usage it's a good opportunity to
give the driver private stuff some tlc on the doc front.

Finally try to explain why the "let's just subclass drm_atomic_state"
approach wasn't the greatest, and annotate all those functions as
deprecated in favour of more standardized driver private states. Also
note where we could/should extend driver private states going forward
(atm neither locking nor synchronization is handled in core/helpers,
which isn't really all that great).

v2: Spelling and phrasing improvements (Alex, DK).

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Rob Clark <robdclark@gmail.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171214203054.20141-5-daniel.vetter@ffwll.ch
Documentation/gpu/drm-kms.rst
drivers/gpu/drm/drm_atomic.c
include/drm/drm_atomic.h
include/drm/drm_mode_config.h

index 3072841..420025b 100644 (file)
@@ -271,6 +271,12 @@ Taken all together there's two consequences for the atomic design:
 Read on in this chapter, and also in :ref:`drm_atomic_helper` for more detailed
 coverage of specific topics.
 
+Handling Driver Private State
+-----------------------------
+
+.. kernel-doc:: drivers/gpu/drm/drm_atomic.c
+   :doc: handling driver private state
+
 Atomic Mode Setting Function Reference
 --------------------------------------
 
index 37445d5..b76d492 100644 (file)
@@ -50,7 +50,8 @@ EXPORT_SYMBOL(__drm_crtc_commit_free);
  * @state: atomic state
  *
  * Free all the memory allocated by drm_atomic_state_init.
- * This is useful for drivers that subclass the atomic state.
+ * This should only be used by drivers which are still subclassing
+ * &drm_atomic_state and haven't switched to &drm_private_state yet.
  */
 void drm_atomic_state_default_release(struct drm_atomic_state *state)
 {
@@ -67,7 +68,8 @@ EXPORT_SYMBOL(drm_atomic_state_default_release);
  * @state: atomic state
  *
  * Default implementation for filling in a new atomic state.
- * This is useful for drivers that subclass the atomic state.
+ * This should only be used by drivers which are still subclassing
+ * &drm_atomic_state and haven't switched to &drm_private_state yet.
  */
 int
 drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
@@ -132,7 +134,8 @@ EXPORT_SYMBOL(drm_atomic_state_alloc);
  * @state: atomic state
  *
  * Default implementation for clearing atomic state.
- * This is useful for drivers that subclass the atomic state.
+ * This should only be used by drivers which are still subclassing
+ * &drm_atomic_state and haven't switched to &drm_private_state yet.
  */
 void drm_atomic_state_default_clear(struct drm_atomic_state *state)
 {
@@ -947,6 +950,42 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
 }
 
 /**
+ * DOC: handling driver private state
+ *
+ * Very often the DRM objects exposed to userspace in the atomic modeset api
+ * (&drm_connector, &drm_crtc and &drm_plane) do not map neatly to the
+ * underlying hardware. Especially for any kind of shared resources (e.g. shared
+ * clocks, scaler units, bandwidth and fifo limits shared among a group of
+ * planes or CRTCs, and so on) it makes sense to model these as independent
+ * objects. Drivers then need to do similar state tracking and commit ordering for
+ * such private (since not exposed to userpace) objects as the atomic core and
+ * helpers already provide for connectors, planes and CRTCs.
+ *
+ * To make this easier on drivers the atomic core provides some support to track
+ * driver private state objects using struct &drm_private_obj, with the
+ * associated state struct &drm_private_state.
+ *
+ * Similar to userspace-exposed objects, private state structures can be
+ * acquired by calling drm_atomic_get_private_obj_state(). Since this function
+ * does not take care of locking, drivers should wrap it for each type of
+ * private state object they have with the required call to drm_modeset_lock()
+ * for the corresponding &drm_modeset_lock.
+ *
+ * All private state structures contained in a &drm_atomic_state update can be
+ * iterated using for_each_oldnew_private_obj_in_state(),
+ * for_each_new_private_obj_in_state() and for_each_old_private_obj_in_state().
+ * Drivers are recommended to wrap these for each type of driver private state
+ * object they have, filtering on &drm_private_obj.funcs using for_each_if(), at
+ * least if they want to iterate over all objects of a given type.
+ *
+ * An earlier way to handle driver private state was by subclassing struct
+ * &drm_atomic_state. But since that encourages non-standard ways to implement
+ * the check/commit split atomic requires (by using e.g. "check and rollback or
+ * commit instead" of "duplicate state, check, then either commit or release
+ * duplicated state) it is deprecated in favour of using &drm_private_state.
+ */
+
+/**
  * drm_atomic_private_obj_init - initialize private object
  * @obj: private object
  * @state: initial private object state
index 5afd6e3..22b6007 100644 (file)
@@ -189,12 +189,40 @@ struct drm_private_state_funcs {
                                     struct drm_private_state *state);
 };
 
+/**
+ * struct drm_private_obj - base struct for driver private atomic object
+ *
+ * A driver private object is initialized by calling
+ * drm_atomic_private_obj_init() and cleaned up by calling
+ * drm_atomic_private_obj_fini().
+ *
+ * Currently only tracks the state update functions and the opaque driver
+ * private state itself, but in the future might also track which
+ * &drm_modeset_lock is required to duplicate and update this object's state.
+ */
 struct drm_private_obj {
+       /**
+        * @state: Current atomic state for this driver private object.
+        */
        struct drm_private_state *state;
 
+       /**
+        * @funcs:
+        *
+        * Functions to manipulate the state of this driver private object, see
+        * &drm_private_state_funcs.
+        */
        const struct drm_private_state_funcs *funcs;
 };
 
+/**
+ * struct drm_private_state - base struct for driver private object state
+ * @state: backpointer to global drm_atomic_state
+ *
+ * Currently only contains a backpointer to the overall atomic update, but in
+ * the future also might hold synchronization information similar to e.g.
+ * &drm_crtc.commit.
+ */
 struct drm_private_state {
        struct drm_atomic_state *state;
 };
index a0afeb5..e5f3b43 100644 (file)
@@ -268,6 +268,9 @@ struct drm_mode_config_funcs {
         * state easily. If this hook is implemented, drivers must also
         * implement @atomic_state_clear and @atomic_state_free.
         *
+        * Subclassing of &drm_atomic_state is deprecated in favour of using
+        * &drm_private_state and &drm_private_obj.
+        *
         * RETURNS:
         *
         * A new &drm_atomic_state on success or NULL on failure.
@@ -289,6 +292,9 @@ struct drm_mode_config_funcs {
         *
         * Drivers that implement this must call drm_atomic_state_default_clear()
         * to clear common state.
+        *
+        * Subclassing of &drm_atomic_state is deprecated in favour of using
+        * &drm_private_state and &drm_private_obj.
         */
        void (*atomic_state_clear)(struct drm_atomic_state *state);
 
@@ -301,6 +307,9 @@ struct drm_mode_config_funcs {
         *
         * Drivers that implement this must call
         * drm_atomic_state_default_release() to release common resources.
+        *
+        * Subclassing of &drm_atomic_state is deprecated in favour of using
+        * &drm_private_state and &drm_private_obj.
         */
        void (*atomic_state_free)(struct drm_atomic_state *state);
 };