diff options
author | Boris Brezillon <boris.brezillon@collabora.com> | 2020-01-28 14:55:03 +0100 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@collabora.com> | 2020-01-31 16:00:21 +0100 |
commit | 751465913f045a1120188ec91ed46d90ea5fd539 (patch) | |
tree | a22279887d908e0749e22bf4ab1260ad187fab95 /drivers/gpu/drm/drm_bridge.c | |
parent | 6d598a32ed871ee7ddb9612a3bdc8f3f1febea33 (diff) | |
download | lwn-751465913f045a1120188ec91ed46d90ea5fd539.tar.gz lwn-751465913f045a1120188ec91ed46d90ea5fd539.zip |
drm/bridge: Add a drm_bridge_state object
One of the last remaining objects to not have its atomic state.
This is being motivated by our attempt to support runtime bus-format
negotiation between elements of the bridge chain.
This patch just paves the road for such a feature by adding a new
drm_bridge_state object inheriting from drm_private_obj so we can
re-use some of the existing state initialization/tracking logic.
v10:
* Add changelog to the commit message
v9:
* Clarify the fact that the bridge->atomic_reset() and
{connector,plane,crtc,...}->reset() semantics are different
* Move the drm_atomic_private_obj_init() call back to
drm_bridge_attach()
* Check the presence of ->atomic_duplicate_state instead of
->atomic_reset in drm_atomic_add_encoder_bridges()
* Fix copy&paste errors in the atomic bridge state helpers doc
* Add A-b/R-b tags
v8:
* Move bridge state helpers out of the CONFIG_DEBUGFS section
v7:
* Move helpers, struct-defs, ... to atomic helper files to avoid the
drm -> drm_kms_helper -> drm circular dep
* Stop providing default implementation for atomic state reset,
duplicate and destroy hooks (has to do with the helper/core split)
* Drop all R-b/T-b as helpers have now be moved to other places
v6:
* Made helpers private, removed doc and moved them to satisfy dependencies
* Renamed helpers to _default_
v5:
* Re-introduced the helpers from v4
v4:
* Fix the doc
* Kill default helpers (inlined)
* Fix drm_atomic_get_bridge_state() to check for an ERR_PTR()
* Add Neil's R-b
v3:
* No changes
v2:
* Use drm_for_each_bridge_in_chain()
* Rename helpers to be more consistent with the rest of the DRM API
* Improve/fix the doc
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20200128135514.108171-2-boris.brezillon@collabora.com
Diffstat (limited to 'drivers/gpu/drm/drm_bridge.c')
-rw-r--r-- | drivers/gpu/drm/drm_bridge.c | 59 |
1 files changed, 54 insertions, 5 deletions
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index c2cf0c90fa26..6b08158ebb7e 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -25,6 +25,7 @@ #include <linux/module.h> #include <linux/mutex.h> +#include <drm/drm_atomic_state_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_encoder.h> @@ -89,6 +90,31 @@ void drm_bridge_remove(struct drm_bridge *bridge) } EXPORT_SYMBOL(drm_bridge_remove); +static struct drm_private_state * +drm_bridge_atomic_duplicate_priv_state(struct drm_private_obj *obj) +{ + struct drm_bridge *bridge = drm_priv_to_bridge(obj); + struct drm_bridge_state *state; + + state = bridge->funcs->atomic_duplicate_state(bridge); + return state ? &state->base : NULL; +} + +static void +drm_bridge_atomic_destroy_priv_state(struct drm_private_obj *obj, + struct drm_private_state *s) +{ + struct drm_bridge_state *state = drm_priv_to_bridge_state(s); + struct drm_bridge *bridge = drm_priv_to_bridge(obj); + + bridge->funcs->atomic_destroy_state(bridge, state); +} + +static const struct drm_private_state_funcs drm_bridge_priv_state_funcs = { + .atomic_duplicate_state = drm_bridge_atomic_duplicate_priv_state, + .atomic_destroy_state = drm_bridge_atomic_destroy_priv_state, +}; + /** * drm_bridge_attach - attach the bridge to an encoder's chain * @@ -135,15 +161,35 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, if (bridge->funcs->attach) { ret = bridge->funcs->attach(bridge); - if (ret < 0) { - list_del(&bridge->chain_node); - bridge->dev = NULL; - bridge->encoder = NULL; - return ret; + if (ret < 0) + goto err_reset_bridge; + } + + if (bridge->funcs->atomic_reset) { + struct drm_bridge_state *state; + + state = bridge->funcs->atomic_reset(bridge); + if (IS_ERR(state)) { + ret = PTR_ERR(state); + goto err_detach_bridge; } + + drm_atomic_private_obj_init(bridge->dev, &bridge->base, + &state->base, + &drm_bridge_priv_state_funcs); } return 0; + +err_detach_bridge: + if (bridge->funcs->detach) + bridge->funcs->detach(bridge); + +err_reset_bridge: + bridge->dev = NULL; + bridge->encoder = NULL; + list_del(&bridge->chain_node); + return ret; } EXPORT_SYMBOL(drm_bridge_attach); @@ -155,6 +201,9 @@ void drm_bridge_detach(struct drm_bridge *bridge) if (WARN_ON(!bridge->dev)) return; + if (bridge->funcs->atomic_reset) + drm_atomic_private_obj_fini(&bridge->base); + if (bridge->funcs->detach) bridge->funcs->detach(bridge); |