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
此提交包含在:
Boris Brezillon
2020-01-28 14:55:03 +01:00
父節點 6d598a32ed
當前提交 751465913f
共有 7 個檔案被更改,包括 400 行新增5 行删除

查看文件

@@ -30,6 +30,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_bridge.h>
#include <drm/drm_debugfs.h>
#include <drm/drm_device.h>
#include <drm/drm_drv.h>
@@ -1017,6 +1018,121 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
connector->funcs->atomic_print_state(p, state);
}
/**
* drm_atomic_get_bridge_state - get bridge state
* @state: global atomic state object
* @bridge: bridge to get state object for
*
* This function returns the bridge state for the given bridge, allocating it
* if needed. It will also grab the relevant bridge lock to make sure that the
* state is consistent.
*
* Returns:
*
* Either the allocated state or the error code encoded into the pointer. When
* the error is EDEADLK then the w/w mutex code has detected a deadlock and the
* entire atomic sequence must be restarted.
*/
struct drm_bridge_state *
drm_atomic_get_bridge_state(struct drm_atomic_state *state,
struct drm_bridge *bridge)
{
struct drm_private_state *obj_state;
obj_state = drm_atomic_get_private_obj_state(state, &bridge->base);
if (IS_ERR(obj_state))
return ERR_CAST(obj_state);
return drm_priv_to_bridge_state(obj_state);
}
EXPORT_SYMBOL(drm_atomic_get_bridge_state);
/**
* drm_atomic_get_old_bridge_state - get old bridge state, if it exists
* @state: global atomic state object
* @bridge: bridge to grab
*
* This function returns the old bridge state for the given bridge, or NULL if
* the bridge is not part of the global atomic state.
*/
struct drm_bridge_state *
drm_atomic_get_old_bridge_state(struct drm_atomic_state *state,
struct drm_bridge *bridge)
{
struct drm_private_state *obj_state;
obj_state = drm_atomic_get_old_private_obj_state(state, &bridge->base);
if (!obj_state)
return NULL;
return drm_priv_to_bridge_state(obj_state);
}
EXPORT_SYMBOL(drm_atomic_get_old_bridge_state);
/**
* drm_atomic_get_new_bridge_state - get new bridge state, if it exists
* @state: global atomic state object
* @bridge: bridge to grab
*
* This function returns the new bridge state for the given bridge, or NULL if
* the bridge is not part of the global atomic state.
*/
struct drm_bridge_state *
drm_atomic_get_new_bridge_state(struct drm_atomic_state *state,
struct drm_bridge *bridge)
{
struct drm_private_state *obj_state;
obj_state = drm_atomic_get_new_private_obj_state(state, &bridge->base);
if (!obj_state)
return NULL;
return drm_priv_to_bridge_state(obj_state);
}
EXPORT_SYMBOL(drm_atomic_get_new_bridge_state);
/**
* drm_atomic_add_encoder_bridges - add bridges attached to an encoder
* @state: atomic state
* @encoder: DRM encoder
*
* This function adds all bridges attached to @encoder. This is needed to add
* bridge states to @state and make them available when
* &bridge_funcs.atomic_{check,pre_enable,enable,disable_post_disable}() are
* called
*
* Returns:
* 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
* then the w/w mutex code has detected a deadlock and the entire atomic
* sequence must be restarted. All other errors are fatal.
*/
int
drm_atomic_add_encoder_bridges(struct drm_atomic_state *state,
struct drm_encoder *encoder)
{
struct drm_bridge_state *bridge_state;
struct drm_bridge *bridge;
if (!encoder)
return 0;
DRM_DEBUG_ATOMIC("Adding all bridges for [encoder:%d:%s] to %p\n",
encoder->base.id, encoder->name, state);
drm_for_each_bridge_in_chain(encoder, bridge) {
/* Skip bridges that don't implement the atomic state hooks. */
if (!bridge->funcs->atomic_duplicate_state)
continue;
bridge_state = drm_atomic_get_bridge_state(state, bridge);
if (IS_ERR(bridge_state))
return PTR_ERR(bridge_state);
}
return 0;
}
EXPORT_SYMBOL(drm_atomic_add_encoder_bridges);
/**
* drm_atomic_add_affected_connectors - add connectors for CRTC
* @state: atomic state