diff options
Diffstat (limited to 'drivers/gpu/drm/drm_atomic.c')
| -rw-r--r-- | drivers/gpu/drm/drm_atomic.c | 117 | 
1 files changed, 117 insertions, 0 deletions
| diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index d33691512a8e..9ccfbf213d72 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -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> @@ -1018,6 +1019,122 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,  }  /** + * 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 + * &drm_bridge_funcs.atomic_check(), &drm_bridge_funcs.atomic_pre_enable(), + * &drm_bridge_funcs.atomic_enable(), + * &drm_bridge_funcs.atomic_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   * @crtc: DRM CRTC |