Quelle drm_atomic_state_helper.c
Sprache: C
/*
* Copyright ( C ) 2018 Intel Corp .
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the " Software " ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE COPYRIGHT HOLDER ( S ) OR AUTHOR ( S ) BE LIABLE FOR ANY CLAIM , DAMAGES OR
* OTHER LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE ,
* ARISING FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE .
*
* Authors :
* Rob Clark < robdclark @ gmail . com >
* Daniel Vetter < daniel . vetter @ ffwll . ch >
*/
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_blend.h>
#include <drm/drm_bridge.h>
#include <drm/drm_connector.h>
#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_plane.h>
#include <drm/drm_print.h>
#include <drm/drm_vblank.h>
#include <drm/drm_writeback.h>
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/dma-fence.h>
/**
* DOC : atomic state reset and initialization
*
* Both the drm core and the atomic helpers assume that there is always the full
* and correct atomic software state for all connectors , CRTCs and planes
* available . Which is a bit a problem on driver load and also after system
* suspend . One way to solve this is to have a hardware state read - out
* infrastructure which reconstructs the full software state ( e . g . the i915
* driver ) .
*
* The simpler solution is to just reset the software state to everything off ,
* which is easiest to do by calling drm_mode_config_reset ( ) . To facilitate this
* the atomic helpers provide default reset implementations for all hooks .
*
* On the upside the precise state tracking of atomic simplifies system suspend
* and resume a lot . For drivers using drm_mode_config_reset ( ) a complete recipe
* is implemented in drm_atomic_helper_suspend ( ) and drm_atomic_helper_resume ( ) .
* For other drivers the building blocks are split out , see the documentation
* for these functions .
*/
/**
* _ _ drm_atomic_helper_crtc_state_reset - reset the CRTC state
* @ crtc_state : atomic CRTC state , must not be NULL
* @ crtc : CRTC object , must not be NULL
*
* Initializes the newly allocated @ crtc_state with default
* values . This is useful for drivers that subclass the CRTC state .
*/
void
__drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state,
struct drm_crtc *crtc)
{
crtc_state->crtc = crtc;
}
EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset);
/**
* _ _ drm_atomic_helper_crtc_reset - reset state on CRTC
* @ crtc : drm CRTC
* @ crtc_state : CRTC state to assign
*
* Initializes the newly allocated @ crtc_state and assigns it to
* the & drm_crtc - > state pointer of @ crtc , usually required when
* initializing the drivers or when called from the & drm_crtc_funcs . reset
* hook .
*
* This is useful for drivers that subclass the CRTC state .
*/
void
__drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
struct drm_crtc_state *crtc_state)
{
if (crtc_state)
__drm_atomic_helper_crtc_state_reset(crtc_state, crtc);
if (drm_dev_has_vblank(crtc->dev))
drm_crtc_vblank_reset(crtc);
crtc->state = crtc_state;
}
EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset);
/**
* drm_atomic_helper_crtc_reset - default & drm_crtc_funcs . reset hook for CRTCs
* @ crtc : drm CRTC
*
* Resets the atomic state for @ crtc by freeing the state pointer ( which might
* be NULL , e . g . at driver load time ) and allocating a new empty state object .
*/
void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
{
struct drm_crtc_state *crtc_state =
kzalloc(sizeof (*crtc->state), GFP_KERNEL);
if (crtc->state)
crtc->funcs->atomic_destroy_state(crtc, crtc->state);
__drm_atomic_helper_crtc_reset(crtc, crtc_state);
}
EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
/**
* _ _ drm_atomic_helper_crtc_duplicate_state - copy atomic CRTC state
* @ crtc : CRTC object
* @ state : atomic CRTC state
*
* Copies atomic state from a CRTC ' s current state and resets inferred values .
* This is useful for drivers that subclass the CRTC state .
*/
void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
struct drm_crtc_state *state)
{
memcpy(state, crtc->state, sizeof (*state));
if (state->mode_blob)
drm_property_blob_get(state->mode_blob);
if (state->degamma_lut)
drm_property_blob_get(state->degamma_lut);
if (state->ctm)
drm_property_blob_get(state->ctm);
if (state->gamma_lut)
drm_property_blob_get(state->gamma_lut);
state->mode_changed = false ;
state->active_changed = false ;
state->planes_changed = false ;
state->connectors_changed = false ;
state->color_mgmt_changed = false ;
state->zpos_changed = false ;
state->commit = NULL;
state->event = NULL;
state->async_flip = false ;
/* Self refresh should be canceled when a new update is available */
state->active = drm_atomic_crtc_effectively_active(state);
state->self_refresh_active = false ;
}
EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
/**
* drm_atomic_helper_crtc_duplicate_state - default state duplicate hook
* @ crtc : drm CRTC
*
* Default CRTC state duplicate hook for drivers which don ' t have their own
* subclassed CRTC state structure .
*/
struct drm_crtc_state *
drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
{
struct drm_crtc_state *state;
if (WARN_ON(!crtc->state))
return NULL;
state = kmalloc(sizeof (*state), GFP_KERNEL);
if (state)
__drm_atomic_helper_crtc_duplicate_state(crtc, state);
return state;
}
EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
/**
* _ _ drm_atomic_helper_crtc_destroy_state - release CRTC state
* @ state : CRTC state object to release
*
* Releases all resources stored in the CRTC state without actually freeing
* the memory of the CRTC state . This is useful for drivers that subclass the
* CRTC state .
*/
void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
{
if (state->commit) {
/*
* In the event that a non - blocking commit returns
* - ERESTARTSYS before the commit_tail work is queued , we will
* have an extra reference to the commit object . Release it , if
* the event has not been consumed by the worker .
*
* state - > event may be freed , so we can ' t directly look at
* state - > event - > base . completion .
*/
if (state->event && state->commit->abort_completion)
drm_crtc_commit_put(state->commit);
kfree(state->commit->event);
state->commit->event = NULL;
drm_crtc_commit_put(state->commit);
}
drm_property_blob_put(state->mode_blob);
drm_property_blob_put(state->degamma_lut);
drm_property_blob_put(state->ctm);
drm_property_blob_put(state->gamma_lut);
}
EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
/**
* drm_atomic_helper_crtc_destroy_state - default state destroy hook
* @ crtc : drm CRTC
* @ state : CRTC state object to release
*
* Default CRTC state destroy hook for drivers which don ' t have their own
* subclassed CRTC state structure .
*/
void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
struct drm_crtc_state *state)
{
__drm_atomic_helper_crtc_destroy_state(state);
kfree(state);
}
EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
/**
* _ _ drm_atomic_helper_plane_state_reset - resets plane state to default values
* @ plane_state : atomic plane state , must not be NULL
* @ plane : plane object , must not be NULL
*
* Initializes the newly allocated @ plane_state with default
* values . This is useful for drivers that subclass the CRTC state .
*/
void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
struct drm_plane *plane)
{
u64 val;
plane_state->plane = plane;
plane_state->rotation = DRM_MODE_ROTATE_0;
plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
if (plane->color_encoding_property) {
if (!drm_object_property_get_default_value(&plane->base,
plane->color_encoding_property,
&val))
plane_state->color_encoding = val;
}
if (plane->color_range_property) {
if (!drm_object_property_get_default_value(&plane->base,
plane->color_range_property,
&val))
plane_state->color_range = val;
}
if (plane->zpos_property) {
if (!drm_object_property_get_default_value(&plane->base,
plane->zpos_property,
&val)) {
plane_state->zpos = val;
plane_state->normalized_zpos = val;
}
}
if (plane->hotspot_x_property) {
if (!drm_object_property_get_default_value(&plane->base,
plane->hotspot_x_property,
&val))
plane_state->hotspot_x = val;
}
if (plane->hotspot_y_property) {
if (!drm_object_property_get_default_value(&plane->base,
plane->hotspot_y_property,
&val))
plane_state->hotspot_y = val;
}
}
EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset);
/**
* _ _ drm_atomic_helper_plane_reset - reset state on plane
* @ plane : drm plane
* @ plane_state : plane state to assign
*
* Initializes the newly allocated @ plane_state and assigns it to
* the & drm_crtc - > state pointer of @ plane , usually required when
* initializing the drivers or when called from the & drm_plane_funcs . reset
* hook .
*
* This is useful for drivers that subclass the plane state .
*/
void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
struct drm_plane_state *plane_state)
{
if (plane_state)
__drm_atomic_helper_plane_state_reset(plane_state, plane);
plane->state = plane_state;
}
EXPORT_SYMBOL(__drm_atomic_helper_plane_reset);
/**
* drm_atomic_helper_plane_reset - default & drm_plane_funcs . reset hook for planes
* @ plane : drm plane
*
* Resets the atomic state for @ plane by freeing the state pointer ( which might
* be NULL , e . g . at driver load time ) and allocating a new empty state object .
*/
void drm_atomic_helper_plane_reset(struct drm_plane *plane)
{
if (plane->state)
__drm_atomic_helper_plane_destroy_state(plane->state);
kfree(plane->state);
plane->state = kzalloc(sizeof (*plane->state), GFP_KERNEL);
if (plane->state)
__drm_atomic_helper_plane_reset(plane, plane->state);
}
EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
/**
* _ _ drm_atomic_helper_plane_duplicate_state - copy atomic plane state
* @ plane : plane object
* @ state : atomic plane state
*
* Copies atomic state from a plane ' s current state . This is useful for
* drivers that subclass the plane state .
*/
void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
struct drm_plane_state *state)
{
memcpy(state, plane->state, sizeof (*state));
if (state->fb)
drm_framebuffer_get(state->fb);
state->fence = NULL;
state->commit = NULL;
state->fb_damage_clips = NULL;
state->color_mgmt_changed = false ;
}
EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
/**
* drm_atomic_helper_plane_duplicate_state - default state duplicate hook
* @ plane : drm plane
*
* Default plane state duplicate hook for drivers which don ' t have their own
* subclassed plane state structure .
*/
struct drm_plane_state *
drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
{
struct drm_plane_state *state;
if (WARN_ON(!plane->state))
return NULL;
state = kmalloc(sizeof (*state), GFP_KERNEL);
if (state)
__drm_atomic_helper_plane_duplicate_state(plane, state);
return state;
}
EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
/**
* _ _ drm_atomic_helper_plane_destroy_state - release plane state
* @ state : plane state object to release
*
* Releases all resources stored in the plane state without actually freeing
* the memory of the plane state . This is useful for drivers that subclass the
* plane state .
*/
void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
{
if (state->fb)
drm_framebuffer_put(state->fb);
if (state->fence)
dma_fence_put(state->fence);
if (state->commit)
drm_crtc_commit_put(state->commit);
drm_property_blob_put(state->fb_damage_clips);
}
EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
/**
* drm_atomic_helper_plane_destroy_state - default state destroy hook
* @ plane : drm plane
* @ state : plane state object to release
*
* Default plane state destroy hook for drivers which don ' t have their own
* subclassed plane state structure .
*/
void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
struct drm_plane_state *state)
{
__drm_atomic_helper_plane_destroy_state(state);
kfree(state);
}
EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
/**
* _ _ drm_atomic_helper_connector_state_reset - reset the connector state
* @ conn_state : atomic connector state , must not be NULL
* @ connector : connectotr object , must not be NULL
*
* Initializes the newly allocated @ conn_state with default
* values . This is useful for drivers that subclass the connector state .
*/
void
__drm_atomic_helper_connector_state_reset(struct drm_connector_state *conn_state,
struct drm_connector *connector)
{
conn_state->connector = connector;
}
EXPORT_SYMBOL(__drm_atomic_helper_connector_state_reset);
/**
* _ _ drm_atomic_helper_connector_reset - reset state on connector
* @ connector : drm connector
* @ conn_state : connector state to assign
*
* Initializes the newly allocated @ conn_state and assigns it to
* the & drm_connector - > state pointer of @ connector , usually required when
* initializing the drivers or when called from the & drm_connector_funcs . reset
* hook .
*
* This is useful for drivers that subclass the connector state .
*/
void
__drm_atomic_helper_connector_reset(struct drm_connector *connector,
struct drm_connector_state *conn_state)
{
if (conn_state)
__drm_atomic_helper_connector_state_reset(conn_state, connector);
connector->state = conn_state;
}
EXPORT_SYMBOL(__drm_atomic_helper_connector_reset);
/**
* drm_atomic_helper_connector_reset - default & drm_connector_funcs . reset hook for connectors
* @ connector : drm connector
*
* Resets the atomic state for @ connector by freeing the state pointer ( which
* might be NULL , e . g . at driver load time ) and allocating a new empty state
* object .
*/
void drm_atomic_helper_connector_reset(struct drm_connector *connector)
{
struct drm_connector_state *conn_state =
kzalloc(sizeof (*conn_state), GFP_KERNEL);
if (connector->state)
__drm_atomic_helper_connector_destroy_state(connector->state);
kfree(connector->state);
__drm_atomic_helper_connector_reset(connector, conn_state);
}
EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
/**
* drm_atomic_helper_connector_tv_margins_reset - Resets TV connector properties
* @ connector : DRM connector
*
* Resets the TV - related properties attached to a connector .
*/
void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector)
{
struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
struct drm_connector_state *state = connector->state;
state->tv.margins.left = cmdline->tv_margins.left;
state->tv.margins.right = cmdline->tv_margins.right;
state->tv.margins.top = cmdline->tv_margins.top;
state->tv.margins.bottom = cmdline->tv_margins.bottom;
}
EXPORT_SYMBOL(drm_atomic_helper_connector_tv_margins_reset);
/**
* drm_atomic_helper_connector_tv_reset - Resets Analog TV connector properties
* @ connector : DRM connector
*
* Resets the analog TV properties attached to a connector
*/
void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
struct drm_connector_state *state = connector->state;
struct drm_property *prop;
uint64_t val;
prop = dev->mode_config.tv_mode_property;
if (prop)
if (!drm_object_property_get_default_value(&connector->base,
prop, &val))
state->tv.mode = val;
if (cmdline->tv_mode_specified)
state->tv.mode = cmdline->tv_mode;
prop = dev->mode_config.tv_select_subconnector_property;
if (prop)
if (!drm_object_property_get_default_value(&connector->base,
prop, &val))
state->tv.select_subconnector = val;
prop = dev->mode_config.tv_subconnector_property;
if (prop)
if (!drm_object_property_get_default_value(&connector->base,
prop, &val))
state->tv.subconnector = val;
prop = dev->mode_config.tv_brightness_property;
if (prop)
if (!drm_object_property_get_default_value(&connector->base,
prop, &val))
state->tv.brightness = val;
prop = dev->mode_config.tv_contrast_property;
if (prop)
if (!drm_object_property_get_default_value(&connector->base,
prop, &val))
state->tv.contrast = val;
prop = dev->mode_config.tv_flicker_reduction_property;
if (prop)
if (!drm_object_property_get_default_value(&connector->base,
prop, &val))
state->tv.flicker_reduction = val;
prop = dev->mode_config.tv_overscan_property;
if (prop)
if (!drm_object_property_get_default_value(&connector->base,
prop, &val))
state->tv.overscan = val;
prop = dev->mode_config.tv_saturation_property;
if (prop)
if (!drm_object_property_get_default_value(&connector->base,
prop, &val))
state->tv.saturation = val;
prop = dev->mode_config.tv_hue_property;
if (prop)
if (!drm_object_property_get_default_value(&connector->base,
prop, &val))
state->tv.hue = val;
drm_atomic_helper_connector_tv_margins_reset(connector);
}
EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
/**
* drm_atomic_helper_connector_tv_check - Validate an analog TV connector state
* @ connector : DRM Connector
* @ state : the DRM State object
*
* Checks the state object to see if the requested state is valid for an
* analog TV connector .
*
* Return :
* % 0 for success , a negative error code on error .
*/
int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
struct drm_atomic_state *state)
{
struct drm_connector_state *old_conn_state =
drm_atomic_get_old_connector_state(state, connector);
struct drm_connector_state *new_conn_state =
drm_atomic_get_new_connector_state(state, connector);
struct drm_crtc_state *crtc_state;
struct drm_crtc *crtc;
crtc = new_conn_state->crtc;
if (!crtc)
return 0 ;
crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
if (!crtc_state)
return -EINVAL;
if (old_conn_state->tv.mode != new_conn_state->tv.mode)
crtc_state->mode_changed = true ;
if (old_conn_state->tv.margins.left != new_conn_state->tv.margins.left ||
old_conn_state->tv.margins.right != new_conn_state->tv.margins.right ||
old_conn_state->tv.margins.top != new_conn_state->tv.margins.top ||
old_conn_state->tv.margins.bottom != new_conn_state->tv.margins.bottom ||
old_conn_state->tv.mode != new_conn_state->tv.mode ||
old_conn_state->tv.brightness != new_conn_state->tv.brightness ||
old_conn_state->tv.contrast != new_conn_state->tv.contrast ||
old_conn_state->tv.flicker_reduction != new_conn_state->tv.flicker_reduction ||
old_conn_state->tv.overscan != new_conn_state->tv.overscan ||
old_conn_state->tv.saturation != new_conn_state->tv.saturation ||
old_conn_state->tv.hue != new_conn_state->tv.hue)
crtc_state->connectors_changed = true ;
return 0 ;
}
EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
/**
* _ _ drm_atomic_helper_connector_duplicate_state - copy atomic connector state
* @ connector : connector object
* @ state : atomic connector state
*
* Copies atomic state from a connector ' s current state . This is useful for
* drivers that subclass the connector state .
*/
void
__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
struct drm_connector_state *state)
{
memcpy(state, connector->state, sizeof (*state));
if (state->crtc)
drm_connector_get(connector);
state->commit = NULL;
if (state->hdr_output_metadata)
drm_property_blob_get(state->hdr_output_metadata);
/* Don't copy over a writeback job, they are used only once */
state->writeback_job = NULL;
}
EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
/**
* drm_atomic_helper_connector_duplicate_state - default state duplicate hook
* @ connector : drm connector
*
* Default connector state duplicate hook for drivers which don ' t have their own
* subclassed connector state structure .
*/
struct drm_connector_state *
drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
{
struct drm_connector_state *state;
if (WARN_ON(!connector->state))
return NULL;
state = kmalloc(sizeof (*state), GFP_KERNEL);
if (state)
__drm_atomic_helper_connector_duplicate_state(connector, state);
return state;
}
EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
/**
* _ _ drm_atomic_helper_connector_destroy_state - release connector state
* @ state : connector state object to release
*
* Releases all resources stored in the connector state without actually
* freeing the memory of the connector state . This is useful for drivers that
* subclass the connector state .
*/
void
__drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
{
if (state->crtc)
drm_connector_put(state->connector);
if (state->commit)
drm_crtc_commit_put(state->commit);
if (state->writeback_job)
drm_writeback_cleanup_job(state->writeback_job);
drm_property_blob_put(state->hdr_output_metadata);
}
EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
/**
* drm_atomic_helper_connector_destroy_state - default state destroy hook
* @ connector : drm connector
* @ state : connector state object to release
*
* Default connector state destroy hook for drivers which don ' t have their own
* subclassed connector state structure .
*/
void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
struct drm_connector_state *state)
{
__drm_atomic_helper_connector_destroy_state(state);
kfree(state);
}
EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
/**
* _ _ drm_atomic_helper_private_obj_duplicate_state - copy atomic private state
* @ obj : CRTC object
* @ state : new private object state
*
* Copies atomic state from a private objects ' s current state and resets inferred values .
* This is useful for drivers that subclass the private state .
*/
void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
struct drm_private_state *state)
{
memcpy(state, obj->state, sizeof (*state));
}
EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state);
/**
* _ _ drm_atomic_helper_bridge_duplicate_state ( ) - Copy atomic bridge state
* @ bridge : bridge object
* @ state : atomic bridge state
*
* Copies atomic state from a bridge ' s current state and resets inferred values .
* This is useful for drivers that subclass the bridge state .
*/
void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge,
struct drm_bridge_state *state)
{
__drm_atomic_helper_private_obj_duplicate_state(&bridge->base,
&state->base);
state->bridge = bridge;
}
EXPORT_SYMBOL(__drm_atomic_helper_bridge_duplicate_state);
/**
* drm_atomic_helper_bridge_duplicate_state ( ) - Duplicate a bridge state object
* @ bridge : bridge object
*
* Allocates a new bridge state and initializes it with the current bridge
* state values . This helper is meant to be used as a bridge
* & drm_bridge_funcs . atomic_duplicate_state hook for bridges that don ' t
* subclass the bridge state .
*/
struct drm_bridge_state *
drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge)
{
struct drm_bridge_state *new ;
if (WARN_ON(!bridge->base.state))
return NULL;
new = kzalloc(sizeof (*new ), GFP_KERNEL);
if (new )
__drm_atomic_helper_bridge_duplicate_state(bridge, new );
return new ;
}
EXPORT_SYMBOL(drm_atomic_helper_bridge_duplicate_state);
/**
* drm_atomic_helper_bridge_destroy_state ( ) - Destroy a bridge state object
* @ bridge : the bridge this state refers to
* @ state : bridge state to destroy
*
* Destroys a bridge state previously created by
* & drm_atomic_helper_bridge_reset ( ) or
* & drm_atomic_helper_bridge_duplicate_state ( ) . This helper is meant to be
* used as a bridge & drm_bridge_funcs . atomic_destroy_state hook for bridges
* that don ' t subclass the bridge state .
*/
void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge,
struct drm_bridge_state *state)
{
kfree(state);
}
EXPORT_SYMBOL(drm_atomic_helper_bridge_destroy_state);
/**
* _ _ drm_atomic_helper_bridge_reset ( ) - Initialize a bridge state to its
* default
* @ bridge : the bridge this state refers to
* @ state : bridge state to initialize
*
* Initializes the bridge state to default values . This is meant to be called
* by the bridge & drm_bridge_funcs . atomic_reset hook for bridges that subclass
* the bridge state .
*/
void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge,
struct drm_bridge_state *state)
{
memset(state, 0 , sizeof (*state));
state->bridge = bridge;
}
EXPORT_SYMBOL(__drm_atomic_helper_bridge_reset);
/**
* drm_atomic_helper_bridge_reset ( ) - Allocate and initialize a bridge state
* to its default
* @ bridge : the bridge this state refers to
*
* Allocates the bridge state and initializes it to default values . This helper
* is meant to be used as a bridge & drm_bridge_funcs . atomic_reset hook for
* bridges that don ' t subclass the bridge state .
*/
struct drm_bridge_state *
drm_atomic_helper_bridge_reset(struct drm_bridge *bridge)
{
struct drm_bridge_state *bridge_state;
bridge_state = kzalloc(sizeof (*bridge_state), GFP_KERNEL);
if (!bridge_state)
return ERR_PTR(-ENOMEM);
__drm_atomic_helper_bridge_reset(bridge, bridge_state);
return bridge_state;
}
EXPORT_SYMBOL(drm_atomic_helper_bridge_reset);
Messung V0.5 in Prozent C=98 H=100 G=98
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet am 2026-09-27)
¤
*© Formatika GbR, Deutschland
2026-10-10
Neuigkeiten
Aktuelles
Motto des Tages
Open Source Software
Jenseits des Üblichen ....
Besucherstatistik
Statistik
#Sources=1126864
#Domains=1897691