Commit da6c0596 authored by Daniel Vetter's avatar Daniel Vetter

drm/atomic: document how to handle driver private objects

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: default avatarDhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171214203054.20141-5-daniel.vetter@ffwll.ch
parent 924fe8df
...@@ -271,6 +271,12 @@ Taken all together there's two consequences for the atomic design: ...@@ -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 Read on in this chapter, and also in :ref:`drm_atomic_helper` for more detailed
coverage of specific topics. 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 Atomic Mode Setting Function Reference
-------------------------------------- --------------------------------------
......
...@@ -50,7 +50,8 @@ EXPORT_SYMBOL(__drm_crtc_commit_free); ...@@ -50,7 +50,8 @@ EXPORT_SYMBOL(__drm_crtc_commit_free);
* @state: atomic state * @state: atomic state
* *
* Free all the memory allocated by drm_atomic_state_init. * 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) void drm_atomic_state_default_release(struct drm_atomic_state *state)
{ {
...@@ -67,7 +68,8 @@ EXPORT_SYMBOL(drm_atomic_state_default_release); ...@@ -67,7 +68,8 @@ EXPORT_SYMBOL(drm_atomic_state_default_release);
* @state: atomic state * @state: atomic state
* *
* Default implementation for filling in a new 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 int
drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state) drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
...@@ -132,7 +134,8 @@ EXPORT_SYMBOL(drm_atomic_state_alloc); ...@@ -132,7 +134,8 @@ EXPORT_SYMBOL(drm_atomic_state_alloc);
* @state: atomic state * @state: atomic state
* *
* Default implementation for clearing 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) void drm_atomic_state_default_clear(struct drm_atomic_state *state)
{ {
...@@ -946,6 +949,42 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, ...@@ -946,6 +949,42 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
plane->funcs->atomic_print_state(p, state); plane->funcs->atomic_print_state(p, state);
} }
/**
* 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 * drm_atomic_private_obj_init - initialize private object
* @obj: private object * @obj: private object
......
...@@ -189,12 +189,40 @@ struct drm_private_state_funcs { ...@@ -189,12 +189,40 @@ struct drm_private_state_funcs {
struct drm_private_state *state); 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 { struct drm_private_obj {
/**
* @state: Current atomic state for this driver private object.
*/
struct drm_private_state *state; 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; 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_private_state {
struct drm_atomic_state *state; struct drm_atomic_state *state;
}; };
......
...@@ -268,6 +268,9 @@ struct drm_mode_config_funcs { ...@@ -268,6 +268,9 @@ struct drm_mode_config_funcs {
* state easily. If this hook is implemented, drivers must also * state easily. If this hook is implemented, drivers must also
* implement @atomic_state_clear and @atomic_state_free. * 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: * RETURNS:
* *
* A new &drm_atomic_state on success or NULL on failure. * A new &drm_atomic_state on success or NULL on failure.
...@@ -289,6 +292,9 @@ struct drm_mode_config_funcs { ...@@ -289,6 +292,9 @@ struct drm_mode_config_funcs {
* *
* Drivers that implement this must call drm_atomic_state_default_clear() * Drivers that implement this must call drm_atomic_state_default_clear()
* to clear common state. * 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); void (*atomic_state_clear)(struct drm_atomic_state *state);
...@@ -301,6 +307,9 @@ struct drm_mode_config_funcs { ...@@ -301,6 +307,9 @@ struct drm_mode_config_funcs {
* *
* Drivers that implement this must call * Drivers that implement this must call
* drm_atomic_state_default_release() to release common resources. * 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); void (*atomic_state_free)(struct drm_atomic_state *state);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment