Drivers must initialize the mode setting core by calling drm_mode_config_init() on the DRM device. The function initializes the struct drm_device mode_config field and never fails. Once done, mode configuration must be setup by initializing the following fields.
The basic object structure KMS presents to userspace is fairly simple. Framebuffers (represented by struct drm_framebuffer, see Frame Buffer Abstraction) feed into planes. One or more (or even no) planes feed their pixel data into a CRTC (represented by struct drm_crtc, see CRTC Abstraction) for blending. The precise blending step is explained in more detail in Plane Composition Properties and related chapters.
For the output routing the first step is encoders (represented by struct drm_encoder, see Encoder Abstraction). Those are really just internal artifacts of the helper libraries used to implement KMS drivers. Besides that they make it unecessarily more complicated for userspace to figure out which connections between a CRTC and a connector are possible, and what kind of cloning is supported, they serve no purpose in the userspace API. Unfortunately encoders have been exposed to userspace, hence can’t remove them at this point. Futhermore the exposed restrictions are often wrongly set by drivers, and in many cases not powerful enough to express the real restrictions. A CRTC can be connected to multiple encoders, and for an active CRTC there must be at least one encoder.
The final, and real, endpoint in the display chain is the connector (represented by struct drm_connector, see Connector Abstraction). Connectors can have different possible encoders, but the kernel driver selects which encoder to use for each connector. The use case is DVI, which could switch between an analog and a digital encoder. Encoders can also drive multiple different connectors. There is exactly one active connector for every active encoder.
Internally the output pipeline is a bit more complex and matches today’s hardware more closely:
Internally two additional helper objects come into play. First, to be able to share code for encoders (sometimes on the same SoC, sometimes off-chip) one or more Bridges (represented by struct drm_bridge) can be linked to an encoder. This link is static and cannot be changed, which means the cross-bar (if there is any) needs to be mapped between the CRTC and any encoders. Often for drivers with bridges there’s no code left at the encoder level. Atomic drivers can leave out all the encoder callbacks to essentially only leave a dummy routing object behind, which is needed for backwards compatibility since encoders are exposed to userspace.
The second object is for panels, represented by struct drm_panel, see Panel Helper Reference. Panels do not have a fixed binding point, but are generally linked to the driver private structure that embeds struct drm_connector.
Note that currently the bridge chaining and interactions with connectors and panels are still in-flux and not really fully sorted out yet.
basic driver provided mode setting functions
Definition
struct drm_mode_config_funcs {
struct drm_framebuffer *(* fb_create) (struct drm_device *dev,struct drm_file *file_priv,const struct drm_mode_fb_cmd2 *mode_cmd);
const struct drm_format_info *(* get_format_info) (const struct drm_mode_fb_cmd2 *mode_cmd);
void (* output_poll_changed) (struct drm_device *dev);
int (* atomic_check) (struct drm_device *dev,struct drm_atomic_state *state);
int (* atomic_commit) (struct drm_device *dev,struct drm_atomic_state *state,bool nonblock);
struct drm_atomic_state *(* atomic_state_alloc) (struct drm_device *dev);
void (* atomic_state_clear) (struct drm_atomic_state *state);
void (* atomic_state_free) (struct drm_atomic_state *state);
};
Members
Create a new framebuffer object. The core does basic checks on the requested metadata, but most of that is left to the driver. See struct drm_mode_fb_cmd2 for details.
If the parameters are deemed valid and the backing storage objects in the underlying memory manager all exist, then the driver allocates a new drm_framebuffer structure, subclassed to contain driver-specific information (like the internal native buffer object references). It also needs to fill out all relevant metadata, which should be done by calling drm_helper_mode_fill_fb_struct().
The initialization is finalized by calling drm_framebuffer_init(), which registers the framebuffer and makes it accessible to other threads.
RETURNS:
A new framebuffer with an initial reference count of 1 or a negative error code encoded with ERR_PTR().
Allows a driver to return custom format information for special fb layouts (eg. ones with auxiliary compression control planes).
RETURNS:
The format information specific to the given fb metadata, or NULL if none is found.
Callback used by helpers to inform the driver of output configuration changes.
Drivers implementing fbdev emulation with the helpers can call drm_fb_helper_hotplug_changed from this hook to inform the fbdev helper of output changes.
FIXME:
Except that there’s no vtable for device-level helper callbacks there’s no reason this is a core function.
This is the only hook to validate an atomic modeset update. This function must reject any modeset and state changes which the hardware or driver doesn’t support. This includes but is of course not limited to:
- Checking that the modes, framebuffers, scaling and placement requirements and so on are within the limits of the hardware.
- Checking that any hidden shared resources are not oversubscribed. This can be shared PLLs, shared lanes, overall memory bandwidth, display fifo space (where shared between planes or maybe even CRTCs).
- Checking that virtualized resources exported to userspace are not oversubscribed. For various reasons it can make sense to expose more planes, crtcs or encoders than which are physically there. One example is dual-pipe operations (which generally should be hidden from userspace if when lockstepped in hardware, exposed otherwise), where a plane might need 1 hardware plane (if it’s just on one pipe), 2 hardware planes (when it spans both pipes) or maybe even shared a hardware plane with a 2nd plane (if there’s a compatible plane requested on the area handled by the other pipe).
- Check that any transitional state is possible and that if requested, the update can indeed be done in the vblank period without temporarily disabling some functions.
- Check any other constraints the driver or hardware might have.
- This callback also needs to correctly fill out the drm_crtc_state in this update to make sure that drm_atomic_crtc_needs_modeset() reflects the nature of the possible update and returns true if and only if the update cannot be applied without tearing within one vblank on that CRTC. The core uses that information to reject updates which require a full modeset (i.e. blanking the screen, or at least pausing updates for a substantial amount of time) if userspace has disallowed that in its request.
- The driver also does not need to repeat basic input validation like done for the corresponding legacy entry points. The core does that before calling this hook.
See the documentation of atomic_commit for an exhaustive list of error conditions which don’t have to be checked at the in this callback.
See the documentation for struct drm_atomic_state for how exactly an atomic modeset update is described.
Drivers using the atomic helpers can implement this hook using drm_atomic_helper_check(), or one of the exported sub-functions of it.
RETURNS:
0 on success or one of the below negative error codes:
- -EINVAL, if any of the above constraints are violated.
- -EDEADLK, when returned from an attempt to acquire an additional drm_modeset_lock through drm_modeset_lock().
- -ENOMEM, if allocating additional state sub-structures failed due to lack of memory.
- -EINTR, -EAGAIN or -ERESTARTSYS, if the IOCTL should be restarted. This can either be due to a pending signal, or because the driver needs to completely bail out to recover from an exceptional situation like a GPU hang. From a userspace point all errors are treated equally.
This is the only hook to commit an atomic modeset update. The core guarantees that atomic_check has been called successfully before calling this function, and that nothing has been changed in the interim.
See the documentation for struct drm_atomic_state for how exactly an atomic modeset update is described.
Drivers using the atomic helpers can implement this hook using drm_atomic_helper_commit(), or one of the exported sub-functions of it.
Nonblocking commits (as indicated with the nonblock parameter) must do any preparatory work which might result in an unsuccessful commit in the context of this callback. The only exceptions are hardware errors resulting in -EIO. But even in that case the driver must ensure that the display pipe is at least running, to avoid compositors crashing when pageflips don’t work. Anything else, specifically committing the update to the hardware, should be done without blocking the caller. For updates which do not require a modeset this must be guaranteed.
The driver must wait for any pending rendering to the new framebuffers to complete before executing the flip. It should also wait for any pending rendering from other drivers if the underlying buffer is a shared dma-buf. Nonblocking commits must not wait for rendering in the context of this callback.
An application can request to be notified when the atomic commit has completed. These events are per-CRTC and can be distinguished by the CRTC index supplied in drm_event to userspace.
The drm core will supply a struct drm_event in each CRTC’s drm_crtc_state.event. See the documentation for drm_crtc_state.event for more details about the precise semantics of this event.
NOTE:
Drivers are not allowed to shut down any display pipe successfully enabled through an atomic commit on their own. Doing so can result in compositors crashing if a page flip is suddenly rejected because the pipe is off.
RETURNS:
0 on success or one of the below negative error codes:
- -EBUSY, if a nonblocking updated is requested and there is an earlier updated pending. Drivers are allowed to support a queue of outstanding updates, but currently no driver supports that. Note that drivers must wait for preceding updates to complete if a synchronous update is requested, they are not allowed to fail the commit in that case.
- -ENOMEM, if the driver failed to allocate memory. Specifically this can happen when trying to pin framebuffers, which must only be done when committing the state.
- -ENOSPC, as a refinement of the more generic -ENOMEM to indicate that the driver has run out of vram, iommu space or similar GPU address space needed for framebuffer.
- -EIO, if the hardware completely died.
- -EINTR, -EAGAIN or -ERESTARTSYS, if the IOCTL should be restarted. This can either be due to a pending signal, or because the driver needs to completely bail out to recover from an exceptional situation like a GPU hang. From a userspace point of view all errors are treated equally.
This list is exhaustive. Specifically this hook is not allowed to return -EINVAL (any invalid requests should be caught in atomic_check) or -EDEADLK (this function must not acquire additional modeset locks).
This optional hook can be used by drivers that want to subclass struct drm_atomic_state to be able to track their own driver-private global state easily. If this hook is implemented, drivers must also implement atomic_state_clear and atomic_state_free.
RETURNS:
A new drm_atomic_state on success or NULL on failure.
This hook must clear any driver private state duplicated into the passed-in drm_atomic_state. This hook is called when the caller encountered a drm_modeset_lock deadlock and needs to drop all already acquired locks as part of the deadlock avoidance dance implemented in drm_modeset_backoff().
Any duplicated state must be invalidated since a concurrent atomic update might change it, and the drm atomic interfaces always apply updates as relative changes to the current state.
Drivers that implement this must call drm_atomic_state_default_clear() to clear common state.
This hook needs driver private resources and the drm_atomic_state itself. Note that the core first calls drm_atomic_state_clear() to avoid code duplicate between the clear and free hooks.
Drivers that implement this must call drm_atomic_state_default_release() to release common resources.
Description
Some global (i.e. not per-CRTC, connector, etc) mode setting functions that involve drivers.
Mode configuration control structure
Definition
struct drm_mode_config {
struct mutex mutex;
struct drm_modeset_lock connection_mutex;
struct drm_modeset_acquire_ctx * acquire_ctx;
struct mutex idr_mutex;
struct idr crtc_idr;
struct idr tile_idr;
struct mutex fb_lock;
int num_fb;
struct list_head fb_list;
spinlock_t connector_list_lock;
int num_connector;
struct ida connector_ida;
struct list_head connector_list;
int num_encoder;
struct list_head encoder_list;
int num_overlay_plane;
int num_total_plane;
struct list_head plane_list;
int num_crtc;
struct list_head crtc_list;
struct list_head property_list;
int min_width;
int min_height;
int max_width;
int max_height;
const struct drm_mode_config_funcs * funcs;
resource_size_t fb_base;
bool poll_enabled;
bool poll_running;
bool delayed_event;
struct delayed_work output_poll_work;
struct mutex blob_lock;
struct list_head property_blob_list;
struct drm_property * edid_property;
struct drm_property * dpms_property;
struct drm_property * path_property;
struct drm_property * tile_property;
struct drm_property * link_status_property;
struct drm_property * plane_type_property;
struct drm_property * prop_src_x;
struct drm_property * prop_src_y;
struct drm_property * prop_src_w;
struct drm_property * prop_src_h;
struct drm_property * prop_crtc_x;
struct drm_property * prop_crtc_y;
struct drm_property * prop_crtc_w;
struct drm_property * prop_crtc_h;
struct drm_property * prop_fb_id;
struct drm_property * prop_in_fence_fd;
struct drm_property * prop_out_fence_ptr;
struct drm_property * prop_crtc_id;
struct drm_property * prop_active;
struct drm_property * prop_mode_id;
struct drm_property * dvi_i_subconnector_property;
struct drm_property * dvi_i_select_subconnector_property;
struct drm_property * tv_subconnector_property;
struct drm_property * tv_select_subconnector_property;
struct drm_property * tv_mode_property;
struct drm_property * tv_left_margin_property;
struct drm_property * tv_right_margin_property;
struct drm_property * tv_top_margin_property;
struct drm_property * tv_bottom_margin_property;
struct drm_property * tv_brightness_property;
struct drm_property * tv_contrast_property;
struct drm_property * tv_flicker_reduction_property;
struct drm_property * tv_overscan_property;
struct drm_property * tv_saturation_property;
struct drm_property * tv_hue_property;
struct drm_property * scaling_mode_property;
struct drm_property * aspect_ratio_property;
struct drm_property * degamma_lut_property;
struct drm_property * degamma_lut_size_property;
struct drm_property * ctm_property;
struct drm_property * gamma_lut_property;
struct drm_property * gamma_lut_size_property;
struct drm_property * suggested_x_property;
struct drm_property * suggested_y_property;
uint32_t preferred_depth;
uint32_t prefer_shadow;
bool async_page_flip;
bool allow_fb_modifiers;
uint32_t cursor_width;
uint32_t cursor_height;
const struct drm_mode_config_helper_funcs * helper_private;
};
Members
This is the big scary modeset BKL which protects everything that isn’t protect otherwise. Scope is unclear and fuzzy, try to remove anything from under it’s protection and move it into more well-scoped locks.
The one important thing this protects is the use of acquire_ctx.
This protects connector state and the connector to encoder to CRTC routing chain.
For atomic drivers specifically this protects drm_connector.state.
Number of overlay planes on this device, excluding primary and cursor planes.
Track number of overlay planes separately from number of total planes. By default we only advertise overlay planes to userspace; if userspace sets the “universal plane” capability bit, we’ll go ahead and expose all planes. This is invariant over the lifetime of a device and hence doesn’t need any locks.
Description
Core mode resource tracking structure. All CRTC, encoders, and connectors enumerated by the driver are added here, as are global properties. Some global restrictions are also here, e.g. dimension restrictions.
call ->reset callbacks
Parameters
Description
This functions calls all the crtc’s, encoder’s and connector’s ->reset callback. Drivers can use this in e.g. their driver load or resume code to reset hardware and software state.
initialize DRM mode_configuration structure
Parameters
Description
Initialize dev‘s mode_config structure, used for tracking the graphics configuration of dev.
Since this initializes the modeset locks, no locking is possible. Which is no problem, since this should happen single threaded at init time. It is the driver’s problem to ensure this guarantee.
free up DRM mode_config info
Parameters
Description
Free up all the connectors and CRTCs associated with this DRM device, then free up the framebuffers and associated buffer objects.
Note that since this /should/ happen single-threaded at driver/device teardown time, no locking is required. It’s the driver’s job to ensure that this guarantee actually holds true.
FIXME: cleanup any dangling user buffer objects too
The base structure for all KMS objects is struct drm_mode_object. One of the base services it provides is tracking properties, which are especially important for the atomic IOCTL (see Atomic Mode Setting). The somewhat surprising part here is that properties are not directly instantiated on each object, but free-standing mode objects themselves, represented by struct drm_property, which only specify the type and value range of a property. Any given property can be attached multiple times to different objects using drm_object_attach_property().
base structure for modeset objects
Definition
struct drm_mode_object {
uint32_t id;
uint32_t type;
struct drm_object_properties * properties;
struct kref refcount;
void (* free_cb) (struct kref *kref);
};
Members
Description
Base structure for modeset objects visible to userspace. Objects can be looked up using drm_mode_object_find(). Besides basic uapi interface properties like id and type it provides two services:
property tracking for drm_mode_object
Definition
struct drm_object_properties {
int count;
struct drm_property * properties[DRM_OBJECT_MAX_PROPERTY];
uint64_t values[DRM_OBJECT_MAX_PROPERTY];
};
Members
Array of pointers to drm_property.
NOTE: if we ever start dynamically destroying properties (ie. not at drm_mode_config_cleanup() time), then we’d have to do a better job of detaching property from mode objects to avoid dangling property pointers:
Array to store the property values, matching properties. Do not read/write values directly, but use drm_object_property_get_value() and drm_object_property_set_value().
Note that atomic drivers do not store mutable properties in this array, but only the decoded values in the corresponding state structure. The decoding is done using the drm_crtc.atomic_get_property and drm_crtc.atomic_set_property hooks for struct drm_crtc. For struct drm_plane the hooks are drm_plane_funcs.atomic_get_property and drm_plane_funcs.atomic_set_property. And for struct drm_connector the hooks are drm_connector_funcs.atomic_get_property and drm_connector_funcs.atomic_set_property .
Hence atomic drivers should not use drm_object_property_set_value() and drm_object_property_get_value() on mutable objects, i.e. those without the DRM_MODE_PROP_IMMUTABLE flag set.
acquire a mode object reference
Parameters
Description
This is a compatibility alias for drm_mode_object_get() and should not be used by new code.
release a mode object reference
Parameters
Description
This is a compatibility alias for drm_mode_object_put() and should not be used by new code.
look up a drm object with static lifetime
Parameters
Description
This function is used to look up a modeset object. It will acquire a reference for reference counted objects. This reference must be dropped again by callind drm_mode_object_put().
release a mode object reference
Parameters
Description
This function decrements the object’s refcount if it is a refcounted modeset object. It is a no-op on any other object. This is used to drop references acquired with drm_mode_object_get().
acquire a mode object reference
Parameters
Description
This function increments the object’s refcount if it is a refcounted modeset object. It is a no-op on any other object. References should be dropped again by calling drm_mode_object_put().
attach a property to a modeset object
Parameters
Description
This attaches the given property to the modeset object with the given initial value. Currently this function cannot fail since the properties are stored in a statically sized array.
set the value of a property
Parameters
Description
This function sets a given property on a given object. This function only changes the software state of the property, it does not call into the driver’s ->set_property callback.
Note that atomic drivers should not have any need to call this, the core will ensure consistency of values reported back to userspace through the appropriate ->atomic_get_property callback. Only legacy drivers should call this function to update the tracked value (after clamping and other restrictions have been applied).
Return
Zero on success, error code on failure.
retrieve the value of a property
Parameters
Description
This function retrieves the softare state of the given property for the given property. Since there is no driver callback to retrieve the current property value this might be out of sync with the hardware, depending upon the driver and property.
Atomic drivers should never call this function directly, the core will read out property values through the various ->atomic_get_property callbacks.
Return
Zero on success, error code on failure.
Atomic provides transactional modeset (including planes) updates, but a bit differently from the usual transactional approach of try-commit and rollback:
Taken all together there’s two consequences for the atomic design:
Read on in this chapter, and also in Atomic Modeset Helper Functions Reference for more detailed coverage of specific topics.
track modeset commits on a CRTC
Definition
struct drm_crtc_commit {
struct drm_crtc * crtc;
struct kref ref;
struct completion flip_done;
struct completion hw_done;
struct completion cleanup_done;
struct list_head commit_entry;
struct drm_pending_vblank_event * event;
};
Members
Will be signalled when all hw register changes for this commit have been written out. Especially when disabling a pipe this can be much later than than flip_done, since that can signal already when the screen goes black, whereas to fully shut down a pipe more register I/O is required.
Note that this does not need to include separately reference-counted resources like backing storage buffer pinning, or runtime pm management.
Description
This structure is used to track pending modeset changes and atomic commit on a per-CRTC basis. Since updating the list should never block this structure is reference counted to allow waiters to safely wait on an event to complete, without holding any locks.
It has 3 different events in total to allow a fine-grained synchronization between outstanding updates:
atomic commit thread hardware
write new state into hardware ----> ...
signal hw_done
switch to new state on next
... v/hblank
wait for buffers to show up ...
... send completion irq
irq handler signals flip_done
cleanup old buffers
signal cleanup_done
wait for flip_done <----
clean up atomic state
The important bit to know is that cleanup_done is the terminal event, but the ordering between flip_done and hw_done is entirely up to the specific driver and modeset state change.
For an implementation of how to use this look at drm_atomic_helper_setup_commit() from the atomic helper library.
the global state object for atomic updates
Definition
struct drm_atomic_state {
struct kref ref;
struct drm_device * dev;
bool allow_modeset:1;
bool legacy_cursor_update:1;
bool legacy_set_config:1;
struct __drm_planes_state * planes;
struct __drm_crtcs_state * crtcs;
int num_connector;
struct __drm_connnectors_state * connectors;
struct drm_modeset_acquire_ctx * acquire_ctx;
struct work_struct commit_work;
};
Members
acquire a reference to the CRTC commit
Parameters
Description
Increases the reference of commit.
release a reference to the CRTC commmit
Parameters
Description
This releases a reference to commit which is freed after removing the final reference. No locking required and callable from any context.
acquire a reference to the atomic state
Parameters
Description
Returns a new reference to the state
release a reference to the atomic state
Parameters
Description
This releases a reference to state which is freed after removing the final reference. No locking required and callable from any context.
get crtc state, if it exists
Parameters
Description
This function returns the crtc state for the given crtc, or NULL if the crtc is not part of the global atomic state.
This function is deprecated, drm_atomic_get_old_crtc_state or drm_atomic_get_new_crtc_state should be used instead.
get old crtc state, if it exists
Parameters
Description
This function returns the old crtc state for the given crtc, or NULL if the crtc is not part of the global atomic state.
get new crtc state, if it exists
Parameters
Description
This function returns the new crtc state for the given crtc, or NULL if the crtc is not part of the global atomic state.
get plane state, if it exists
Parameters
Description
This function returns the plane state for the given plane, or NULL if the plane is not part of the global atomic state.
This function is deprecated, drm_atomic_get_old_plane_state or drm_atomic_get_new_plane_state should be used instead.
get plane state, if it exists
Parameters
Description
This function returns the old plane state for the given plane, or NULL if the plane is not part of the global atomic state.
get plane state, if it exists
Parameters
Description
This function returns the new plane state for the given plane, or NULL if the plane is not part of the global atomic state.
get connector state, if it exists
Parameters
Description
This function returns the connector state for the given connector, or NULL if the connector is not part of the global atomic state.
This function is deprecated, drm_atomic_get_old_connector_state or drm_atomic_get_new_connector_state should be used instead.
get connector state, if it exists
Parameters
Description
This function returns the old connector state for the given connector, or NULL if the connector is not part of the global atomic state.
get connector state, if it exists
Parameters
Description
This function returns the new connector state for the given connector, or NULL if the connector is not part of the global atomic state.
get current plane state
Parameters
Description
This function returns the plane state for the given plane, either from state, or if the plane isn’t part of the atomic state update, from plane. This is useful in atomic check callbacks, when drivers need to peek at, but not change, state of other planes, since it avoids threading an error code back up the call chain.
WARNING:
Note that this function is in general unsafe since it doesn’t check for the required locking for access state structures. Drivers must ensure that it is safe to access the returned state structure through other means. One common example is when planes are fixed to a single CRTC, and the driver knows that the CRTC lock is held already. In that case holding the CRTC lock gives a read-lock on all planes connected to that CRTC. But if planes can be reassigned things get more tricky. In that case it’s better to use drm_atomic_get_plane_state and wire up full error handling.
Return
Read-only pointer to the current plane state.
iterate over all connectors in an atomic update
Parameters
Description
This iterates over all connectors in an atomic update. Note that before the software state is committed (by calling drm_atomic_helper_swap_state(), this points to the new state, while afterwards it points to the old state. Due to this tricky confusion this macro is deprecated.
FIXME:
Replace all usage of this with one of the explicit iterators below and then remove this macro.
iterate over all connectors in an atomic update
Parameters
Description
This iterates over all connectors in an atomic update, tracking both old and new state. This is useful in places where the state delta needs to be considered, for example in atomic check functions.
iterate over all connectors in an atomic update
Parameters
Description
This iterates over all connectors in an atomic update, tracking only the old state. This is useful in disable functions, where we need the old state the hardware is still in.
iterate over all connectors in an atomic update
Parameters
Description
This iterates over all connectors in an atomic update, tracking only the new state. This is useful in enable functions, where we need the new state the hardware should be in when the atomic commit operation has completed.
iterate over all connectors in an atomic update
Parameters
Description
This iterates over all CRTCs in an atomic update. Note that before the software state is committed (by calling drm_atomic_helper_swap_state(), this points to the new state, while afterwards it points to the old state. Due to this tricky confusion this macro is deprecated.
FIXME:
Replace all usage of this with one of the explicit iterators below and then remove this macro.
iterate over all CRTCs in an atomic update
Parameters
Description
This iterates over all CRTCs in an atomic update, tracking both old and new state. This is useful in places where the state delta needs to be considered, for example in atomic check functions.
iterate over all CRTCs in an atomic update
Parameters
Description
This iterates over all CRTCs in an atomic update, tracking only the old state. This is useful in disable functions, where we need the old state the hardware is still in.
iterate over all CRTCs in an atomic update
Parameters
Description
This iterates over all CRTCs in an atomic update, tracking only the new state. This is useful in enable functions, where we need the new state the hardware should be in when the atomic commit operation has completed.
iterate over all planes in an atomic update
Parameters
Description
This iterates over all planes in an atomic update. Note that before the software state is committed (by calling drm_atomic_helper_swap_state(), this points to the new state, while afterwards it points to the old state. Due to this tricky confusion this macro is deprecated.
FIXME:
Replace all usage of this with one of the explicit iterators below and then remove this macro.
iterate over all planes in an atomic update
Parameters
Description
This iterates over all planes in an atomic update, tracking both old and new state. This is useful in places where the state delta needs to be considered, for example in atomic check functions.
iterate over all planes in an atomic update
Parameters
Description
This iterates over all planes in an atomic update, tracking only the old state. This is useful in disable functions, where we need the old state the hardware is still in.
iterate over all planes in an atomic update
Parameters
Description
This iterates over all planes in an atomic update, tracking only the new state. This is useful in enable functions, where we need the new state the hardware should be in when the atomic commit operation has completed.
compute combined modeset need
Parameters
Description
To give drivers flexibility struct drm_crtc_state has 3 booleans to track whether the state CRTC changed enough to need a full modeset cycle: planes_changed, mode_changed and active_changed. This helper simply combines these three to compute the overall need for a modeset for state.
The atomic helper code sets these booleans, but drivers can and should change them appropriately to accurately represent whether a modeset is really needed. In general, drivers should avoid full modesets whenever possible.
For example if the CRTC mode has changed, and the hardware is able to enact the requested mode change without going through a full modeset, the driver should clear mode_changed in its drm_mode_config_funcs.atomic_check implementation.
release memory initialized by drm_atomic_state_init
Parameters
Description
Free all the memory allocated by drm_atomic_state_init. This is useful for drivers that subclass the atomic state.
init new atomic state
Parameters
Description
Default implementation for filling in a new atomic state. This is useful for drivers that subclass the atomic state.
allocate atomic state
Parameters
Description
This allocates an empty atomic state to track updates.
clear base atomic state
Parameters
Description
Default implementation for clearing atomic state. This is useful for drivers that subclass the atomic state.
clear state object
Parameters
Description
When the w/w mutex algorithm detects a deadlock we need to back off and drop all locks. So someone else could sneak in and change the current modeset configuration. Which means that all the state assembled in state is no longer an atomic update to the current state, but to some arbitrary earlier state. Which could break assumptions the driver’s drm_mode_config_funcs.atomic_check likely relies on.
Hence we must clear all cached state and completely start over, using this function.
free all memory for an atomic state
Parameters
Description
This frees all memory associated with an atomic state, including all the per-object state for planes, crtcs and connectors.
get crtc state
Parameters
Description
This function returns the crtc state for the given crtc, allocating it if needed. It will also grab the relevant crtc lock to make sure that the state is consistent.
Return
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. All other errors are fatal.
set mode for CRTC
Parameters
Description
Set a mode (originating from the kernel) on the desired CRTC state and update the enable property.
Return
Zero on success, error code on failure. Cannot return -EDEADLK.
set mode for CRTC
Parameters
Description
Set a mode (originating from a blob property) on the desired CRTC state. This function will take a reference on the blob property for the CRTC state, and release the reference held on the state’s existing mode property, if any was set.
Return
Zero on success, error code on failure. Cannot return -EDEADLK.
set property on CRTC
Parameters
Description
This function handles generic/core properties and calls out to driver’s drm_crtc_funcs.atomic_set_property for driver properties. To ensure consistent behavior you must call this function rather than the driver hook directly.
Return
Zero on success, error code on failure
get plane state
Parameters
Description
This function returns the plane state for the given plane, allocating it if needed. It will also grab the relevant plane lock to make sure that the state is consistent.
Return
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. All other errors are fatal.
set property on plane
Parameters
Description
This function handles generic/core properties and calls out to driver’s drm_plane_funcs.atomic_set_property for driver properties. To ensure consistent behavior you must call this function rather than the driver hook directly.
Return
Zero on success, error code on failure
get connector state
Parameters
Description
This function returns the connector state for the given connector, allocating it if needed. It will also grab the relevant connector lock to make sure that the state is consistent.
Return
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. All other errors are fatal.
set property on connector.
Parameters
Description
This function handles generic/core properties and calls out to driver’s drm_connector_funcs.atomic_set_property for driver properties. To ensure consistent behavior you must call this function rather than the driver hook directly.
Return
Zero on success, error code on failure
set crtc for plane
Parameters
Description
Changing the assigned crtc for a plane requires us to grab the lock and state for the new crtc, as needed. This function takes care of all these details besides updating the pointer in the state object itself.
Return
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.
set framebuffer for plane
Parameters
Description
Changing the assigned framebuffer for a plane requires us to grab a reference to the new fb and drop the reference to the old fb, if there is one. This function takes care of all these details besides updating the pointer in the state object itself.
set fence for plane
Parameters
Description
Helper to setup the plane_state fence in case it is not set yet. By using this drivers doesn’t need to worry if the user choose implicit or explicit fencing.
This function will not set the fence to the state if it was set via explicit fencing interfaces on the atomic ioctl. In that case it will drop the reference to the fence as we are not storing it anywhere. Otherwise, if drm_plane_state.fence is not set this function we just set it with the received implicit fence. In both cases this function consumes a reference for fence.
set crtc for connector
Parameters
Description
Changing the assigned crtc for a connector requires us to grab the lock and state for the new crtc, as needed. This function takes care of all these details besides updating the pointer in the state object itself.
Return
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.
add connectors for crtc
Parameters
Description
This function walks the current configuration and adds all connectors currently using crtc to the atomic configuration state. Note that this function must acquire the connection mutex. This can potentially cause unneeded seralization if the update is just for the planes on one crtc. Hence drivers and helpers should only call this when really needed (e.g. when a full modeset needs to happen due to some change).
Return
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.
add planes for crtc
Parameters
Description
This function walks the current configuration and adds all planes currently used by crtc to the atomic configuration state. This is useful when an atomic commit also needs to check all currently enabled plane on crtc, e.g. when changing the mode. It’s also useful when re-enabling a CRTC to avoid special code to force-enable all planes.
Since acquiring a plane state will always also acquire the w/w mutex of the current CRTC for that plane (if there is any) adding all the plane states for a CRTC will not reduce parallism of atomic updates.
Return
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.
locking backoff for legacy ioctls
Parameters
Description
This function should be used by legacy entry points which don’t understand -EDEADLK semantics. For simplicity this one will grab all modeset locks after the slowpath completed.
check whether a given config would work
Parameters
Description
Note that this function can return -EDEADLK if the driver needed to acquire more locks but encountered a deadlock. The caller must then do the usual w/w backoff dance and restart. All other errors are fatal.
Return
0 on success, negative error code on failure.
commit configuration atomically
Parameters
Description
Note that this function can return -EDEADLK if the driver needed to acquire more locks but encountered a deadlock. The caller must then do the usual w/w backoff dance and restart. All other errors are fatal.
This function will take its own reference on state. Callers should always release their reference with drm_atomic_state_put().
Return
0 on success, negative error code on failure.
atomic nonblocking commit
Parameters
Description
Note that this function can return -EDEADLK if the driver needed to acquire more locks but encountered a deadlock. The caller must then do the usual w/w backoff dance and restart. All other errors are fatal.
This function will take its own reference on state. Callers should always release their reference with drm_atomic_state_put().
Return
0 on success, negative error code on failure.
dump entire device atomic state
Parameters
Description
Just for debugging. Drivers might want an option to dump state to dmesg in case of error irq’s. (Hint, you probably want to ratelimit this!)
The caller must drm_modeset_lock_all(), or if this is called from error irq handler, it should not be enabled by default. (Ie. if you are debugging errors you might not care that this is racey. But calling this without all modeset locks held is not inherently safe.)
Parameters
Description
Before doing an update drm_plane.old_fb is set to drm_plane.fb, but before dropping the locks old_fb needs to be set to NULL and plane->fb updated. This is a common operation for each atomic update, so this call is split off as a helper.
A CRTC represents the overall display pipeline. It receives pixel data from drm_plane and blends them together. The drm_display_mode is also attached to the CRTC, specifying display timings. On the output side the data is fed to one or more drm_encoder, which are then each connected to one drm_connector.
To create a CRTC, a KMS drivers allocates and zeroes an instances of struct drm_crtc (possibly as part of a larger structure) and registers it with a call to drm_crtc_init_with_planes().
The CRTC is also the entry point for legacy modeset operations, see drm_crtc_funcs.set_config, legacy plane operations, see drm_crtc_funcs.page_flip and drm_crtc_funcs.cursor_set2, and other legacy operations like drm_crtc_funcs.gamma_set. For atomic drivers all these features are controlled through drm_property and drm_mode_config_funcs.atomic_check and drm_mode_config_funcs.atomic_check.
mutable CRTC state
Definition
struct drm_crtc_state {
struct drm_crtc * crtc;
bool enable;
bool active;
bool planes_changed:1;
bool mode_changed:1;
bool active_changed:1;
bool connectors_changed:1;
bool zpos_changed:1;
bool color_mgmt_changed:1;
u32 plane_mask;
u32 connector_mask;
u32 encoder_mask;
struct drm_display_mode adjusted_mode;
struct drm_display_mode mode;
struct drm_property_blob * mode_blob;
struct drm_property_blob * degamma_lut;
struct drm_property_blob * ctm;
struct drm_property_blob * gamma_lut;
u32 target_vblank;
u32 pageflip_flags;
struct drm_pending_vblank_event * event;
struct drm_atomic_state * state;
};
Members
Optional pointer to a DRM event to signal upon completion of the state update. The driver must send out the event when the atomic commit operation completes. There are two cases:
- The event is for a CRTC which is being disabled through this atomic commit. In that case the event can be send out any time after the hardware has stopped scanning out the current framebuffers. It should contain the timestamp and counter for the last vblank before the display pipeline was shut off.
- For a CRTC which is enabled at the end of the commit (even when it undergoes an full modeset) the vblank timestamp and counter must be for the vblank right before the first frame that scans out the new set of buffers. Again the event can only be sent out after the hardware has stopped scanning out the old buffers.
- Events for disabled CRTCs are not allowed, and drivers can ignore that case.
This can be handled by the drm_crtc_send_vblank_event() function, which the driver should call on the provided event upon completion of the atomic commit. Note that if the driver supports vblank signalling and timestamping the vblank counters and timestamps must agree with the ones returned from page flip events. With the current vblank helper infrastructure this can be achieved by holding a vblank reference while the page flip is pending, acquired through drm_crtc_vblank_get() and released with drm_crtc_vblank_put(). Drivers are free to implement their own vblank counter and timestamp tracking though, e.g. if they have accurate timestamp registers in hardware.
For hardware which supports some means to synchronize vblank interrupt delivery with committing display state there’s also drm_crtc_arm_vblank_event(). See the documentation of that function for a detailed discussion of the constraints it needs to be used safely.
If the device can’t notify of flip completion in a race-free way at all, then the event should be armed just after the page flip is committed. In the worst case the driver will send the event to userspace one frame too late. This doesn’t allow for a real atomic update, but it should avoid tearing.
Description
Note that the distinction between enable and active is rather subtile: Flipping active while enable is set without changing anything else may never return in a failure from the drm_mode_config_funcs.atomic_check callback. Userspace assumes that a DPMS On will always succeed. In other words: enable controls resource assignment, active controls the actual hardware state.
The three booleans active_changed, connectors_changed and mode_changed are intended to indicate whether a full modeset is needed, rather than strictly describing what has changed in a commit. See also: drm_atomic_crtc_needs_modeset()
control CRTCs for a given device
Definition
struct drm_crtc_funcs {
void (* reset) (struct drm_crtc *crtc);
int (* cursor_set) (struct drm_crtc *crtc, struct drm_file *file_priv,uint32_t handle, uint32_t width, uint32_t height);
int (* cursor_set2) (struct drm_crtc *crtc, struct drm_file *file_priv,uint32_t handle, uint32_t width, uint32_t height,int32_t hot_x, int32_t hot_y);
int (* cursor_move) (struct drm_crtc *crtc, int x, int y);
int (* gamma_set) (struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,uint32_t size);
void (* destroy) (struct drm_crtc *crtc);
int (* set_config) (struct drm_mode_set *set,struct drm_modeset_acquire_ctx *ctx);
int (* page_flip) (struct drm_crtc *crtc,struct drm_framebuffer *fb,struct drm_pending_vblank_event *event,uint32_t flags,struct drm_modeset_acquire_ctx *ctx);
int (* page_flip_target) (struct drm_crtc *crtc,struct drm_framebuffer *fb,struct drm_pending_vblank_event *event,uint32_t flags, uint32_t target,struct drm_modeset_acquire_ctx *ctx);
int (* set_property) (struct drm_crtc *crtc,struct drm_property *property, uint64_t val);
struct drm_crtc_state *(* atomic_duplicate_state) (struct drm_crtc *crtc);
void (* atomic_destroy_state) (struct drm_crtc *crtc,struct drm_crtc_state *state);
int (* atomic_set_property) (struct drm_crtc *crtc,struct drm_crtc_state *state,struct drm_property *property,uint64_t val);
int (* atomic_get_property) (struct drm_crtc *crtc,const struct drm_crtc_state *state,struct drm_property *property,uint64_t *val);
int (* late_register) (struct drm_crtc *crtc);
void (* early_unregister) (struct drm_crtc *crtc);
int (* set_crc_source) (struct drm_crtc *crtc, const char *source,size_t *values_cnt);
void (* atomic_print_state) (struct drm_printer *p,const struct drm_crtc_state *state);
u32 (* get_vblank_counter) (struct drm_crtc *crtc);
int (* enable_vblank) (struct drm_crtc *crtc);
void (* disable_vblank) (struct drm_crtc *crtc);
};
Members
Reset CRTC hardware and software state to off. This function isn’t called by the core directly, only through drm_mode_config_reset(). It’s not a helper hook only for historical reasons.
Atomic drivers can use drm_atomic_helper_crtc_reset() to reset atomic state using this hook.
Update the cursor image. The cursor position is relative to the CRTC and can be partially or fully outside of the visible area.
Note that contrary to all other KMS functions the legacy cursor entry points don’t take a framebuffer object, but instead take directly a raw buffer object id from the driver’s buffer manager (which is either GEM or TTM for current drivers).
This entry point is deprecated, drivers should instead implement universal plane support and register a proper cursor plane using drm_crtc_init_with_planes().
This callback is optional
RETURNS:
0 on success or a negative error code on failure.
Update the cursor image, including hotspot information. The hotspot must not affect the cursor position in CRTC coordinates, but is only meant as a hint for virtualized display hardware to coordinate the guests and hosts cursor position. The cursor hotspot is relative to the cursor image. Otherwise this works exactly like cursor_set.
This entry point is deprecated, drivers should instead implement universal plane support and register a proper cursor plane using drm_crtc_init_with_planes().
This callback is optional.
RETURNS:
0 on success or a negative error code on failure.
Update the cursor position. The cursor does not need to be visible when this hook is called.
This entry point is deprecated, drivers should instead implement universal plane support and register a proper cursor plane using drm_crtc_init_with_planes().
This callback is optional.
RETURNS:
0 on success or a negative error code on failure.
Set gamma on the CRTC.
This callback is optional.
NOTE:
Drivers that support gamma tables and also fbdev emulation through the provided helper library need to take care to fill out the gamma hooks for both. Currently there’s a bit an unfortunate duplication going on, which should eventually be unified to just one set of hooks.
This is the main legacy entry point to change the modeset state on a CRTC. All the details of the desired configuration are passed in a struct drm_mode_set - see there for details.
Drivers implementing atomic modeset should use drm_atomic_helper_set_config() to implement this hook.
RETURNS:
0 on success or a negative error code on failure.
Legacy entry point to schedule a flip to the given framebuffer.
Page flipping is a synchronization mechanism that replaces the frame buffer being scanned out by the CRTC with a new frame buffer during vertical blanking, avoiding tearing (except when requested otherwise through the DRM_MODE_PAGE_FLIP_ASYNC flag). When an application requests a page flip the DRM core verifies that the new frame buffer is large enough to be scanned out by the CRTC in the currently configured mode and then calls this hook with a pointer to the new frame buffer.
The driver must wait for any pending rendering to the new framebuffer to complete before executing the flip. It should also wait for any pending rendering from other drivers if the underlying buffer is a shared dma-buf.
An application can request to be notified when the page flip has completed. The drm core will supply a struct drm_event in the event parameter in this case. This can be handled by the drm_crtc_send_vblank_event() function, which the driver should call on the provided event upon completion of the flip. Note that if the driver supports vblank signalling and timestamping the vblank counters and timestamps must agree with the ones returned from page flip events. With the current vblank helper infrastructure this can be achieved by holding a vblank reference while the page flip is pending, acquired through drm_crtc_vblank_get() and released with drm_crtc_vblank_put(). Drivers are free to implement their own vblank counter and timestamp tracking though, e.g. if they have accurate timestamp registers in hardware.
This callback is optional.
NOTE:
Very early versions of the KMS ABI mandated that the driver must block (but not reject) any rendering to the old framebuffer until the flip operation has completed and the old framebuffer is no longer visible. This requirement has been lifted, and userspace is instead expected to request delivery of an event and wait with recycling old buffers until such has been received.
RETURNS:
0 on success or a negative error code on failure. Note that if a page flip operation is already pending the callback should return -EBUSY. Pageflips on a disabled CRTC (either by setting a NULL mode or just runtime disabled through DPMS respectively the new atomic “ACTIVE” state) should result in an -EINVAL error code. Note that drm_atomic_helper_page_flip() checks this already for atomic drivers.
Same as page_flip but with an additional parameter specifying the absolute target vertical blank period (as reported by drm_crtc_vblank_count()) when the flip should take effect.
Note that the core code calls drm_crtc_vblank_get before this entry point, and will call drm_crtc_vblank_put if this entry point returns any non-0 error code. It’s the driver’s responsibility to call drm_crtc_vblank_put after this entry point returns 0, typically when the flip completes.
This is the legacy entry point to update a property attached to the CRTC.
Drivers implementing atomic modeset should use drm_atomic_helper_crtc_set_property() to implement this hook.
This callback is optional if the driver does not support any legacy driver-private properties.
RETURNS:
0 on success or a negative error code on failure.
Duplicate the current atomic state for this CRTC and return it. The core and helpers guarantee that any atomic state duplicated with this hook and still owned by the caller (i.e. not transferred to the driver by calling drm_mode_config_funcs.atomic_commit) will be cleaned up by calling the atomic_destroy_state hook in this structure.
Atomic drivers which don’t subclass struct drm_crtc_state should use drm_atomic_helper_crtc_duplicate_state(). Drivers that subclass the state structure to extend it with driver-private state should use __drm_atomic_helper_crtc_duplicate_state() to make sure shared state is duplicated in a consistent fashion across drivers.
It is an error to call this hook before drm_crtc.state has been initialized correctly.
NOTE:
If the duplicate state references refcounted resources this hook must acquire a reference for each of them. The driver must release these references again in atomic_destroy_state.
RETURNS:
Duplicated atomic state or NULL when the allocation failed.
Decode a driver-private property value and store the decoded value into the passed-in state structure. Since the atomic core decodes all standardized properties (even for extensions beyond the core set of properties which might not be implemented by all drivers) this requires drivers to subclass the state structure.
Such driver-private properties should really only be implemented for truly hardware/vendor specific state. Instead it is preferred to standardize atomic extension and decode the properties used to expose such an extension in the core.
Do not call this function directly, use drm_atomic_crtc_set_property() instead.
This callback is optional if the driver does not support any driver-private atomic properties.
NOTE:
This function is called in the state assembly phase of atomic modesets, which can be aborted for any reason (including on userspace’s request to just check whether a configuration would be possible). Drivers MUST NOT touch any persistent state (hardware or software) or data structures except the passed in state parameter.
Also since userspace controls in which order properties are set this function must not do any input validation (since the state update is incomplete and hence likely inconsistent). Instead any such input validation must be done in the various atomic_check callbacks.
RETURNS:
0 if the property has been found, -EINVAL if the property isn’t implemented by the driver (which should never happen, the core only asks for properties attached to this CRTC). No other validation is allowed by the driver. The core already checks that the property value is within the range (integer, valid enum value, ...) the driver set when registering the property.
Reads out the decoded driver-private property. This is used to implement the GETCRTC IOCTL.
Do not call this function directly, use drm_atomic_crtc_get_property() instead.
This callback is optional if the driver does not support any driver-private atomic properties.
RETURNS:
0 on success, -EINVAL if the property isn’t implemented by the driver (which should never happen, the core only asks for properties attached to this CRTC).
This optional hook can be used to register additional userspace interfaces attached to the crtc like debugfs interfaces. It is called late in the driver load sequence from drm_dev_register(). Everything added from this callback should be unregistered in the early_unregister callback.
Returns:
0 on success, or a negative error code on failure.
Changes the source of CRC checksums of frames at the request of userspace, typically for testing purposes. The sources available are specific of each driver and a NULL value indicates that CRC generation is to be switched off.
When CRC generation is enabled, the driver should call drm_crtc_add_crc_entry() at each frame, providing any information that characterizes the frame contents in the crcN arguments, as provided from the configured source. Drivers must accept an “auto” source name that will select a default source for this CRTC.
Note that “auto” can depend upon the current modeset configuration, e.g. it could pick an encoder or output specific CRC sampling point.
This callback is optional if the driver does not support any CRC generation functionality.
RETURNS:
0 on success or a negative error code on failure.
If driver subclasses struct drm_crtc_state, it should implement this optional hook for printing additional driver specific state.
Do not call this directly, use drm_atomic_crtc_print_state() instead.
Driver callback for fetching a raw hardware vblank counter for the CRTC. It’s meant to be used by new drivers as the replacement of drm_driver.get_vblank_counter hook.
This callback is optional. If a device doesn’t have a hardware counter, the driver can simply leave the hook as NULL. The DRM core will account for missed vblank events while interrupts where disabled based on system timestamps.
Wraparound handling and loss of events due to modesetting is dealt with in the DRM core code, as long as drivers call drm_crtc_vblank_off() and drm_crtc_vblank_on() when disabling or enabling a CRTC.
Returns:
Raw vblank counter value.
Enable vblank interrupts for the CRTC. It’s meant to be used by new drivers as the replacement of drm_driver.enable_vblank hook.
Returns:
Zero on success, appropriate errno if the vblank interrupt cannot be enabled.
Description
The drm_crtc_funcs structure is the central CRTC management structure in the DRM. Each CRTC controls one or more connectors (note that the name CRTC is simply historical, a CRTC may control LVDS, VGA, DVI, TV out, etc. connectors, not just CRTs).
Each driver is responsible for filling out this structure at startup time, in addition to providing other modesetting features, like i2c and DDC bus accessors.
central CRTC control structure
Definition
struct drm_crtc {
struct drm_device * dev;
struct device_node * port;
struct list_head head;
char * name;
struct drm_modeset_lock mutex;
struct drm_mode_object base;
struct drm_plane * primary;
struct drm_plane * cursor;
unsigned index;
int cursor_x;
int cursor_y;
bool enabled;
struct drm_display_mode mode;
struct drm_display_mode hwmode;
int x;
int y;
const struct drm_crtc_funcs * funcs;
uint32_t gamma_size;
uint16_t * gamma_store;
const struct drm_crtc_helper_funcs * helper_private;
struct drm_object_properties properties;
struct drm_crtc_state * state;
struct list_head commit_list;
spinlock_t commit_lock;
struct drm_modeset_acquire_ctx * acquire_ctx;
#ifdef CONFIG_DEBUG_FS
struct dentry * debugfs_entry;
#endif
struct drm_crtc_crc crc;
unsigned int fence_context;
spinlock_t fence_lock;
unsigned long fence_seqno;
char timeline_name[32];
};
Members
This provides a read lock for the overall CRTC state (mode, dpms state, ...) and a write lock for everything which can be update without a full modeset (fb, cursor data, CRTC properties ...). A full modeset also need to grab drm_mode_config.connection_mutex.
For atomic drivers specifically this protects state.
Current atomic state for this CRTC.
This is protected by mutex. Note that nonblocking atomic commits access the current CRTC state without taking locks. Either by going through the struct drm_atomic_state pointers, see for_each_crtc_in_state(), for_each_oldnew_crtc_in_state(), for_each_old_crtc_in_state() and for_each_new_crtc_in_state(). Or through careful ordering of atomic commit operations as implemented in the atomic helpers, see struct drm_crtc_commit.
Description
Each CRTC may have one or more connectors associated with it. This structure allows the CRTC to be controlled.
new values for a CRTC config change
Definition
struct drm_mode_set {
struct drm_framebuffer * fb;
struct drm_crtc * crtc;
struct drm_display_mode * mode;
uint32_t x;
uint32_t y;
struct drm_connector ** connectors;
size_t num_connectors;
};
Members
Description
This represents a modeset configuration for the legacy SETCRTC ioctl and is also used internally. Atomic drivers instead use drm_atomic_state.
Parameters
Description
Given a registered CRTC, return the index of that CRTC within a DRM device’s list of CRTCs.
Parameters
Description
Given a registered CRTC, return the mask bit of that CRTC for an encoder’s possible_crtcs field.
look up a CRTC object from its ID
Parameters
Description
This can be used to look up a CRTC from its userspace ID. Only used by drivers for legacy IOCTLs and interface, nowadays extensions to the KMS userspace interface should be done using drm_property.
iterate over all CRTCs
Parameters
Description
Iterate over all CRTCs of dev.
find the registered CRTC at an index
Parameters
Description
Given a CRTC index, return the registered CRTC from DRM device’s list of CRTCs with matching index. This is the inverse of drm_crtc_index(). It’s useful in the vblank callbacks (like drm_driver.enable_vblank or drm_driver.disable_vblank), since that still deals with indices instead of pointers to struct drm_crtc.”
Parameters
Note
This should only be used by non-atomic legacy drivers.
Return
Zero on success, error code on failure.
Forcibly turn off all enabled CRTCs
Parameters
Description
Drivers may want to call this on unload to ensure that all displays are unlit and the GPU is in a consistent, low power state. Takes modeset locks.
Note
This should only be used by non-atomic legacy drivers. For an atomic version look at drm_atomic_helper_shutdown().
Return
Zero on success, error code on failure.
Initialise a new CRTC object with specified primary and cursor planes.
Parameters
Description
Inits a new object created as base part of a driver crtc object. Drivers should use this function instead of drm_crtc_init(), which is only provided for backwards compatibility with drivers which do not yet support universal planes). For really simple hardware which has only 1 plane look at drm_simple_display_pipe_init() instead.
Return
Zero on success, error code on failure.
Parameters
Description
This function cleans up crtc and removes it from the DRM mode setting core. Note that the function does not free the crtc structure itself, this is the responsibility of the caller.
helper to call drm_mode_config_funcs.set_config
Parameters
Description
This is a little helper to wrap internal calls to the drm_mode_config_funcs.set_config driver interface. The only thing it adds is correct refcounting dance.
This should only be used by non-atomic legacy drivers.
Return
Zero on success, negative errno on failure.
Checks that a framebuffer is big enough for the CRTC viewport
Parameters
Frame buffers are abstract memory objects that provide a source of pixels to scanout to a CRTC. Applications explicitly request the creation of frame buffers through the DRM_IOCTL_MODE_ADDFB(2) ioctls and receive an opaque handle that can be passed to the KMS CRTC control, plane configuration and page flip functions.
Frame buffers rely on the underlying memory manager for allocating backing storage. When creating a frame buffer applications pass a memory handle (or a list of memory handles for multi-planar formats) through the struct drm_mode_fb_cmd2 argument. For drivers using GEM as their userspace buffer management interface this would be a GEM handle. Drivers are however free to use their own backing storage object handles, e.g. vmwgfx directly exposes special TTM handles to userspace and so expects TTM handles in the create ioctl and not GEM handles.
Framebuffers are tracked with struct drm_framebuffer. They are published using drm_framebuffer_init() - after calling that function userspace can use and access the framebuffer object. The helper function drm_helper_mode_fill_fb_struct() can be used to pre-fill the required metadata fields.
The lifetime of a drm framebuffer is controlled with a reference count, drivers can grab additional references with drm_framebuffer_get() and drop them again with drm_framebuffer_put(). For driver-private framebuffers for which the last reference is never dropped (e.g. for the fbdev framebuffer when the struct struct drm_framebuffer is embedded into the fbdev helper struct) drivers can manually clean up a framebuffer at module unload time with drm_framebuffer_unregister_private(). But doing this is not recommended, and it’s better to have a normal free-standing struct drm_framebuffer.
framebuffer hooks
Definition
struct drm_framebuffer_funcs {
void (* destroy) (struct drm_framebuffer *framebuffer);
int (* create_handle) (struct drm_framebuffer *fb,struct drm_file *file_priv,unsigned int *handle);
int (* dirty) (struct drm_framebuffer *framebuffer,struct drm_file *file_priv, unsigned flags,unsigned color, struct drm_clip_rect *clips,unsigned num_clips);
};
Members
Create a buffer handle in the driver-specific buffer manager (either GEM or TTM) valid for the passed-in struct drm_file. This is used by the core to implement the GETFB IOCTL, which returns (for sufficiently priviledged user) also a native buffer handle. This can be used for seamless transitions between modesetting clients by copying the current screen contents to a private buffer and blending between that and the new contents.
GEM based drivers should call drm_gem_handle_create() to create the handle.
RETURNS:
0 on success or a negative error code on failure.
Optional callback for the dirty fb IOCTL.
Userspace can notify the driver via this callback that an area of the framebuffer has changed and should be flushed to the display hardware. This can also be used internally, e.g. by the fbdev emulation, though that’s not the case currently.
See documentation in drm_mode.h for the struct drm_mode_fb_dirty_cmd for more information as all the semantics and arguments have a one to one mapping on this function.
RETURNS:
0 on success or a negative error code on failure.
frame buffer object
Definition
struct drm_framebuffer {
struct drm_device * dev;
struct list_head head;
struct drm_mode_object base;
const struct drm_format_info * format;
const struct drm_framebuffer_funcs * funcs;
unsigned int pitches[4];
unsigned int offsets[4];
uint64_t modifier;
unsigned int width;
unsigned int height;
int flags;
int hot_x;
int hot_y;
struct list_head filp_head;
};
Members
Offset from buffer start to the actual pixel data in bytes, per buffer. For userspace created object this is copied from drm_mode_fb_cmd2.
Note that this is a linear offset and does not take into account tiling or buffer laytou per modifier. It meant to be used when the actual pixel data for this framebuffer plane starts at an offset, e.g. when multiple planes are allocated within the same backing storage buffer object. For tiled layouts this generally means it offsets must at least be tile-size aligned, but hardware often has stricter requirements.
This should not be used to specifiy x/y pixel offsets into the buffer data (even for linear buffers). Specifying an x/y pixel offset is instead done through the source rectangle in struct drm_plane_state.
Description
Note that the fb is refcounted for the benefit of driver internals, for example some hw, disabling a CRTC/plane is asynchronous, and scanout does not actually complete until the next vblank. So some cleanup (like releasing the reference(s) on the backing GEM bo(s)) should be deferred. In cases like this, the driver would like to hold a ref to the fb even though it has already been removed from userspace perspective. See drm_framebuffer_get() and drm_framebuffer_put().
The refcount is stored inside the mode object base.
acquire a framebuffer reference
Parameters
Description
This function increments the framebuffer’s reference count.
release a framebuffer reference
Parameters
Description
This function decrements the framebuffer’s reference count and frees the framebuffer if the reference count drops to zero.
acquire a framebuffer reference
Parameters
Description
This is a compatibility alias for drm_framebuffer_get() and should not be used by new code.
release a framebuffer reference
Parameters
Description
This is a compatibility alias for drm_framebuffer_put() and should not be used by new code.
read the framebuffer reference count.
Parameters
Description
This functions returns the framebuffer’s reference count.
store a reference to the fb
Parameters
Description
This functions sets the location to store a reference to the framebuffer, unreferencing the framebuffer that was previously stored in that location.
initialize a framebuffer
Parameters
Description
Allocates an ID for the framebuffer’s parent mode object, sets its mode functions & device file and adds it to the master fd list.
IMPORTANT: This functions publishes the fb and makes it available for concurrent access by other users. Which means by this point the fb _must_ be fully set up - since all the fb attributes are invariant over its lifetime, no further locking but only correct reference counting is required.
Return
Zero on success, error code on failure.
look up a drm framebuffer and grab a reference
Parameters
Description
If successful, this grabs an additional reference to the framebuffer - callers need to make sure to eventually unreference the returned framebuffer again, using drm_framebuffer_put().
unregister a private fb from the lookup idr
Parameters
Description
Drivers need to call this when cleaning up driver-private framebuffers, e.g. those used for fbdev. Note that the caller must hold a reference of it’s own, i.e. the object may not be destroyed through this call (since it’ll lead to a locking inversion).
NOTE
This function is deprecated. For driver-private framebuffers it is not recommended to embed a framebuffer struct info fbdev struct, instead, a framebuffer pointer is preferred and drm_framebuffer_put() should be called when the framebuffer is to be cleaned up.
remove a framebuffer object
Parameters
Description
Cleanup framebuffer. This function is intended to be used from the drivers drm_framebuffer_funcs.destroy callback. It can also be used to clean up driver private framebuffers embedded into a larger structure.
Note that this function does not remove the fb from active usage - if it is still used anywhere, hilarity can ensue since userspace could call getfb on the id and get back -EINVAL. Obviously no concern at driver unload time.
Also, the framebuffer will not be removed from the lookup idr - for user-created framebuffers this will happen in in the rmfb ioctl. For driver-private objects (e.g. for fbdev) drivers need to explicitly call drm_framebuffer_unregister_private.
remove and unreference a framebuffer object
Parameters
Description
Scans all the CRTCs and planes in dev‘s mode_config. If they’re using fb, removes it, setting it to NULL. Then drops the reference to the passed-in framebuffer. Might take the modeset locks.
Note that this function optimizes the cleanup away if the caller holds the last reference to the framebuffer. It is also guaranteed to not take the modeset locks in this case.
width of the plane given the first plane
Parameters
Return
The width of plane, given that the width of the first plane is width.
height of the plane given the first plane
Parameters
Return
The height of plane, given that the height of the first plane is height.
information about a DRM format
Definition
struct drm_format_info {
u32 format;
u8 depth;
u8 num_planes;
u8 cpp[3];
u8 hsub;
u8 vsub;
};
Members
name of a DRM format
Definition
struct drm_format_name_buf {
char str[32];
};
Members
compute drm fourcc code from legacy description
Parameters
Description
Computes a drm fourcc pixel format code for the given bpp/depth values. Useful in fbdev emulation code, since that deals in those values.
fill a string with a drm fourcc format’s name
Parameters
query information for a given format
Parameters
Description
The caller should only pass a supported pixel format to this function. Unsupported pixel formats will generate a warning in the kernel log.
Return
The instance of struct drm_format_info that describes the pixel format, or NULL if the format is unsupported.
query information for a given framebuffer configuration
Parameters
Return
The instance of struct drm_format_info that describes the pixel format, or NULL if the format is unsupported.
get the number of planes for format
Parameters
Return
The number of planes used by the specified pixel format.
determine the bytes per pixel value
Parameters
Return
The bytes per pixel value for the specified plane.
get the horizontal chroma subsampling factor
Parameters
Return
The horizontal chroma subsampling factor for the specified pixel format.
get the vertical chroma subsampling factor
Parameters
Return
The vertical chroma subsampling factor for the specified pixel format.
width of the plane given the first plane
Parameters
Return
The width of plane, given that the width of the first plane is width.
height of the plane given the first plane
Parameters
Return
The height of plane, given that the height of the first plane is height.
The KMS API doesn’t standardize backing storage object creation and leaves it to driver-specific ioctls. Furthermore actually creating a buffer object even for GEM-based drivers is done through a driver-specific ioctl - GEM only has a common userspace interface for sharing and destroying objects. While not an issue for full-fledged graphics stacks that include device-specific userspace components (in libdrm for instance), this limit makes DRM-based early boot graphics unnecessarily complex.
Dumb objects partly alleviate the problem by providing a standard API to create dumb buffers suitable for scanout, which can then be used to create KMS frame buffers.
To support dumb objects drivers must implement the drm_driver.dumb_create, drm_driver.dumb_destroy and drm_driver.dumb_map_offset operations. See there for further details.
Note that dumb objects may not be used for gpu acceleration, as has been attempted on some ARM embedded platforms. Such drivers really must have a hardware-specific ioctl to allocate suitable buffer objects.
A plane represents an image source that can be blended with or overlayed on top of a CRTC during the scanout process. Planes take their input data from a drm_framebuffer object. The plane itself specifies the cropping and scaling of that image, and where it is placed on the visible are of a display pipeline, represented by drm_crtc. A plane can also have additional properties that specify how the pixels are positioned and blended, like rotation or Z-position. All these properties are stored in drm_plane_state.
To create a plane, a KMS drivers allocates and zeroes an instances of struct drm_plane (possibly as part of a larger structure) and registers it with a call to drm_universal_plane_init().
Cursor and overlay planes are optional. All drivers should provide one primary plane per CRTC to avoid surprising userspace too much. See enum drm_plane_type for a more in-depth discussion of these special uapi-relevant plane types. Special planes are associated with their CRTC by calling drm_crtc_init_with_planes().
The type of a plane is exposed in the immutable “type” enumeration property, which has one of the following values: “Overlay”, “Primary”, “Cursor”.
mutable plane state
Definition
struct drm_plane_state {
struct drm_plane * plane;
struct drm_crtc * crtc;
struct drm_framebuffer * fb;
struct dma_fence * fence;
int32_t crtc_x;
int32_t crtc_y;
uint32_t crtc_w;
uint32_t crtc_h;
uint32_t src_x;
uint32_t src_y;
uint32_t src_h;
uint32_t src_w;
unsigned int rotation;
unsigned int zpos;
unsigned int normalized_zpos;
struct drm_rect src;
struct drm_rect dst;
bool visible;
struct drm_atomic_state * state;
};
Members
driver plane control functions
Definition
struct drm_plane_funcs {
int (* update_plane) (struct drm_plane *plane,struct drm_crtc *crtc, struct drm_framebuffer *fb,int crtc_x, int crtc_y,unsigned int crtc_w, unsigned int crtc_h,uint32_t src_x, uint32_t src_y,uint32_t src_w, uint32_t src_h,struct drm_modeset_acquire_ctx *ctx);
int (* disable_plane) (struct drm_plane *plane,struct drm_modeset_acquire_ctx *ctx);
void (* destroy) (struct drm_plane *plane);
void (* reset) (struct drm_plane *plane);
int (* set_property) (struct drm_plane *plane,struct drm_property *property, uint64_t val);
struct drm_plane_state *(* atomic_duplicate_state) (struct drm_plane *plane);
void (* atomic_destroy_state) (struct drm_plane *plane,struct drm_plane_state *state);
int (* atomic_set_property) (struct drm_plane *plane,struct drm_plane_state *state,struct drm_property *property,uint64_t val);
int (* atomic_get_property) (struct drm_plane *plane,const struct drm_plane_state *state,struct drm_property *property,uint64_t *val);
int (* late_register) (struct drm_plane *plane);
void (* early_unregister) (struct drm_plane *plane);
void (* atomic_print_state) (struct drm_printer *p,const struct drm_plane_state *state);
};
Members
This is the legacy entry point to enable and configure the plane for the given CRTC and framebuffer. It is never called to disable the plane, i.e. the passed-in crtc and fb paramters are never NULL.
The source rectangle in frame buffer memory coordinates is given by the src_x, src_y, src_w and src_h parameters (as 16.16 fixed point values). Devices that don’t support subpixel plane coordinates can ignore the fractional part.
The destination rectangle in CRTC coordinates is given by the crtc_x, crtc_y, crtc_w and crtc_h parameters (as integer values). Devices scale the source rectangle to the destination rectangle. If scaling is not supported, and the source rectangle size doesn’t match the destination rectangle size, the driver must return a -<errorname>EINVAL</errorname> error.
Drivers implementing atomic modeset should use drm_atomic_helper_update_plane() to implement this hook.
RETURNS:
0 on success or a negative error code on failure.
This is the legacy entry point to disable the plane. The DRM core calls this method in response to a DRM_IOCTL_MODE_SETPLANE IOCTL call with the frame buffer ID set to 0. Disabled planes must not be processed by the CRTC.
Drivers implementing atomic modeset should use drm_atomic_helper_disable_plane() to implement this hook.
RETURNS:
0 on success or a negative error code on failure.
Reset plane hardware and software state to off. This function isn’t called by the core directly, only through drm_mode_config_reset(). It’s not a helper hook only for historical reasons.
Atomic drivers can use drm_atomic_helper_plane_reset() to reset atomic state using this hook.
This is the legacy entry point to update a property attached to the plane.
Drivers implementing atomic modeset should use drm_atomic_helper_plane_set_property() to implement this hook.
This callback is optional if the driver does not support any legacy driver-private properties.
RETURNS:
0 on success or a negative error code on failure.
Duplicate the current atomic state for this plane and return it. The core and helpers guarantee that any atomic state duplicated with this hook and still owned by the caller (i.e. not transferred to the driver by calling drm_mode_config_funcs.atomic_commit) will be cleaned up by calling the atomic_destroy_state hook in this structure.
Atomic drivers which don’t subclass struct drm_plane_state should use drm_atomic_helper_plane_duplicate_state(). Drivers that subclass the state structure to extend it with driver-private state should use __drm_atomic_helper_plane_duplicate_state() to make sure shared state is duplicated in a consistent fashion across drivers.
It is an error to call this hook before drm_plane.state has been initialized correctly.
NOTE:
If the duplicate state references refcounted resources this hook must acquire a reference for each of them. The driver must release these references again in atomic_destroy_state.
RETURNS:
Duplicated atomic state or NULL when the allocation failed.
Decode a driver-private property value and store the decoded value into the passed-in state structure. Since the atomic core decodes all standardized properties (even for extensions beyond the core set of properties which might not be implemented by all drivers) this requires drivers to subclass the state structure.
Such driver-private properties should really only be implemented for truly hardware/vendor specific state. Instead it is preferred to standardize atomic extension and decode the properties used to expose such an extension in the core.
Do not call this function directly, use drm_atomic_plane_set_property() instead.
This callback is optional if the driver does not support any driver-private atomic properties.
NOTE:
This function is called in the state assembly phase of atomic modesets, which can be aborted for any reason (including on userspace’s request to just check whether a configuration would be possible). Drivers MUST NOT touch any persistent state (hardware or software) or data structures except the passed in state parameter.
Also since userspace controls in which order properties are set this function must not do any input validation (since the state update is incomplete and hence likely inconsistent). Instead any such input validation must be done in the various atomic_check callbacks.
RETURNS:
0 if the property has been found, -EINVAL if the property isn’t implemented by the driver (which shouldn’t ever happen, the core only asks for properties attached to this plane). No other validation is allowed by the driver. The core already checks that the property value is within the range (integer, valid enum value, ...) the driver set when registering the property.
Reads out the decoded driver-private property. This is used to implement the GETPLANE IOCTL.
Do not call this function directly, use drm_atomic_plane_get_property() instead.
This callback is optional if the driver does not support any driver-private atomic properties.
RETURNS:
0 on success, -EINVAL if the property isn’t implemented by the driver (which should never happen, the core only asks for properties attached to this plane).
This optional hook can be used to register additional userspace interfaces attached to the plane like debugfs interfaces. It is called late in the driver load sequence from drm_dev_register(). Everything added from this callback should be unregistered in the early_unregister callback.
Returns:
0 on success, or a negative error code on failure.
If driver subclasses struct drm_plane_state, it should implement this optional hook for printing additional driver specific state.
Do not call this directly, use drm_atomic_plane_print_state() instead.
uapi plane type enumeration
Constants
Description
For historical reasons not all planes are made the same. This enumeration is used to tell the different types of planes apart to implement the different uapi semantics for them. For userspace which is universal plane aware and which is using that atomic IOCTL there’s no difference between these planes (beyong what the driver and hardware can support of course).
For compatibility with legacy userspace, only overlay planes are made available to userspace by default. Userspace clients may set the DRM_CLIENT_CAP_UNIVERSAL_PLANES client capability bit to indicate that they wish to receive a universal plane list containing all plane types. See also drm_for_each_legacy_plane().
WARNING: The values of this enum is UABI since they’re exposed in the “type” property.
central DRM plane control structure
Definition
struct drm_plane {
struct drm_device * dev;
struct list_head head;
char * name;
struct drm_modeset_lock mutex;
struct drm_mode_object base;
uint32_t possible_crtcs;
uint32_t * format_types;
unsigned int format_count;
bool format_default;
struct drm_crtc * crtc;
struct drm_framebuffer * fb;
struct drm_framebuffer * old_fb;
const struct drm_plane_funcs * funcs;
struct drm_object_properties properties;
enum drm_plane_type type;
unsigned index;
const struct drm_plane_helper_funcs * helper_private;
struct drm_plane_state * state;
struct drm_property * zpos_property;
struct drm_property * rotation_property;
};
Members
Protects modeset plane state, together with the drm_crtc.mutex of CRTC this plane is linked to (when active, getting activated or getting disabled).
For atomic drivers specifically this protects state.
Current atomic state for this plane.
This is protected by mutex. Note that nonblocking atomic commits access the current plane state without taking locks. Either by going through the struct drm_atomic_state pointers, see for_each_plane_in_state(), for_each_oldnew_plane_in_state(), for_each_old_plane_in_state() and for_each_new_plane_in_state(). Or through careful ordering of atomic commit operations as implemented in the atomic helpers, see struct drm_crtc_commit.
Parameters
Description
Given a registered plane, return the index of that plane within a DRM device’s list of planes.
Parameters
Description
Returns the plane with id, NULL if it doesn’t exist. Simple wrapper around drm_mode_object_find().
iterate over planes specified by bitmask
Parameters
Description
Iterate over all planes specified by bitmask.
iterate over all planes for legacy userspace
Parameters
Description
Iterate over all legacy planes of dev, excluding primary and cursor planes. This is useful for implementing userspace apis when userspace is not universal plane aware. See also enum drm_plane_type.
iterate over all planes
Parameters
Description
Iterate over all planes of dev, include primary and cursor planes.
Initialize a new universal plane object
Parameters
Description
Initializes a plane object of type type.
Return
Zero on success, error code on failure.
Initialize a legacy plane
Parameters
Description
Legacy API to initialize a DRM plane.
New drivers should call drm_universal_plane_init() instead.
Return
Zero on success, error code on failure.
Parameters
Description
This function cleans up plane and removes it from the DRM mode setting core. Note that the function does not free the plane structure itself, this is the responsibility of the caller.
find the registered plane at an index
Parameters
Description
Given a plane index, return the registered plane from DRM device’s list of planes with matching index. This is the inverse of drm_plane_index().
Parameters
Description
Forces the plane to be disabled.
Used when the plane’s current framebuffer is destroyed, and when restoring fbdev mode.
Note that this function is not suitable for atomic drivers, since it doesn’t wire through the lock acquisition context properly and hence can’t handle retries or driver private locks. You probably want to use drm_atomic_helper_disable_plane() or drm_atomic_helper_disable_planes_on_crtc() instead.
set the value of a property
Parameters
Description
This functions sets a given property on a given plane object. This function calls the driver’s ->set_property callback and changes the software state of the property if the callback succeeds.
Return
Zero on success, error code on failure.
hardware support status of a mode
Constants
Description
This enum is used to filter out modes not supported by the driver/hardware combination.
DRM kernel-internal display mode structure
Definition
struct drm_display_mode {
struct list_head head;
struct drm_mode_object base;
char name[DRM_DISPLAY_MODE_LEN];
enum drm_mode_status status;
unsigned int type;
int clock;
int hdisplay;
int hsync_start;
int hsync_end;
int htotal;
int hskew;
int vdisplay;
int vsync_start;
int vsync_end;
int vtotal;
int vscan;
unsigned int flags;
int width_mm;
int height_mm;
int crtc_clock;
int crtc_hdisplay;
int crtc_hblank_start;
int crtc_hblank_end;
int crtc_hsync_start;
int crtc_hsync_end;
int crtc_htotal;
int crtc_hskew;
int crtc_vdisplay;
int crtc_vblank_start;
int crtc_vblank_end;
int crtc_vsync_start;
int crtc_vsync_end;
int crtc_vtotal;
int * private;
int private_flags;
int vrefresh;
int hsync;
enum hdmi_picture_aspect picture_aspect_ratio;
};
Members
A display mode is a normal modeset object, possibly including public userspace id.
FIXME:
This can probably be removed since the entire concept of userspace managing modes explicitly has never landed in upstream kernel mode setting support.
A bitmask of flags, mostly about the source of a mode. Possible flags are:
- DRM_MODE_TYPE_BUILTIN: Meant for hard-coded modes, effectively unused.
- DRM_MODE_TYPE_PREFERRED: Preferred mode, usually the native resolution of an LCD panel. There should only be one preferred mode per connector at any given time.
- DRM_MODE_TYPE_DRIVER: Mode created by the driver, which is all of them really. Drivers must set this bit for all modes they create and expose to userspace.
Plus a big list of flags which shouldn’t be used at all, but are still around since these flags are also used in the userspace ABI:
- DRM_MODE_TYPE_DEFAULT: Again a leftover, use DRM_MODE_TYPE_PREFERRED instead.
- DRM_MODE_TYPE_CLOCK_C and DRM_MODE_TYPE_CRTC_C: Define leftovers which are stuck around for hysterical raisins only. No one has an idea what they were meant for. Don’t use.
- DRM_MODE_TYPE_USERDEF: Mode defined by userspace, again a vestige from older kms designs where userspace had to first add a custom mode to the kernel’s mode list before it could use it. Don’t use.
Sync and timing flags:
- DRM_MODE_FLAG_PHSYNC: horizontal sync is active high.
- DRM_MODE_FLAG_NHSYNC: horizontal sync is active low.
- DRM_MODE_FLAG_PVSYNC: vertical sync is active high.
- DRM_MODE_FLAG_NVSYNC: vertical sync is active low.
- DRM_MODE_FLAG_INTERLACE: mode is interlaced.
- DRM_MODE_FLAG_DBLSCAN: mode uses doublescan.
- DRM_MODE_FLAG_CSYNC: mode uses composite sync.
- DRM_MODE_FLAG_PCSYNC: composite sync is active high.
- DRM_MODE_FLAG_NCSYNC: composite sync is active low.
- DRM_MODE_FLAG_HSKEW: hskew provided (not used?).
- DRM_MODE_FLAG_BCAST: not used?
- DRM_MODE_FLAG_PIXMUX: not used?
- DRM_MODE_FLAG_DBLCLK: double-clocked mode.
- DRM_MODE_FLAG_CLKDIV2: half-clocked mode.
Additionally there’s flags to specify how 3D modes are packed:
- DRM_MODE_FLAG_3D_NONE: normal, non-3D mode.
- DRM_MODE_FLAG_3D_FRAME_PACKING: 2 full frames for left and right.
- DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE: interleaved like fields.
- DRM_MODE_FLAG_3D_LINE_ALTERNATIVE: interleaved lines.
- DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL: side-by-side full frames.
- DRM_MODE_FLAG_3D_L_DEPTH: ?
- DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH: ?
- DRM_MODE_FLAG_3D_TOP_AND_BOTTOM: frame split into top and bottom parts.
- DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF: frame split into left and right parts.
Actual pixel or dot clock in the hardware. This differs from the logical clock when e.g. using interlacing, double-clocking, stereo modes or other fancy stuff that changes the timings and signals actually sent over the wire.
This is again in kHz.
Note that with digital outputs like HDMI or DP there’s usually a massive confusion between the dot clock and the signal clock at the bit encoding level. Especially when a 8b/10b encoding is used and the difference is exactly a factor of 10.
Vertical refresh rate, for debug output in human readable form. Not used in a functional way.
This value is in Hz.
Horizontal refresh rate, for debug output in human readable form. Not used in a functional way.
This value is in kHz.
Description
The horizontal and vertical timings are defined per the following diagram.
Active Front Sync Back
Region Porch Porch
<-----------------------><----------------><-------------><-------------->
//////////////////////|
////////////////////// |
////////////////////// |.................. ................
_______________
<----- [hv]display ----->
<------------- [hv]sync_start ------------>
<--------------------- [hv]sync_end --------------------->
<-------------------------------- [hv]total ----------------------------->*
This structure contains two copies of timings. First are the plain timings, which specify the logical mode, as it would be for a progressive 1:1 scanout at the refresh rate userspace can observe through vblank timestamps. Then there’s the hardware timings, which are corrected for interlacing, double-clocking and similar things. They are provided as a convenience, and can be appropriately computed using drm_mode_set_crtcinfo().
check for stereo mode flags
Parameters
Return
True if the mode is one of the stereo modes (like side-by-side), false if not.
print a mode to dmesg
Parameters
Description
Describe mode using DRM_DEBUG.
create a new display mode
Parameters
Description
Create a new, cleared drm_display_mode with kzalloc, allocate an ID for it and return it.
Return
Pointer to new mode on success, NULL on error.
remove a mode
Parameters
Description
Release mode‘s unique ID, then free it mode structure itself using kfree.
add a mode to a connector’s probed_mode list
Parameters
Description
Add mode to connector‘s probed_mode list for later use. This list should then in a second step get filtered and all the modes actually supported by the hardware moved to the connector‘s modes list.
create a modeline based on the CVT algorithm
Parameters
Description
This function is called to generate the modeline based on CVT algorithm according to the hdisplay, vdisplay, vrefresh. It is based from the VESA(TM) Coordinated Video Timing Generator by Graham Loveridge April 9, 2003 available at http://www.elo.utfsm.cl/~elo212/docs/CVTd6r1.xls
And it is copied from xf86CVTmode in xserver/hw/xfree86/modes/xf86cvt.c. What I have done is to translate it by using integer calculation.
Return
The modeline based on the CVT algorithm stored in a drm_display_mode object. The display mode object is allocated with drm_mode_create(). Returns NULL when no mode could be allocated.
create the modeline based on the full GTF algorithm
Parameters
Description
GTF feature blocks specify C and J in multiples of 0.5, so we pass them in here multiplied by two. For a C of 40, pass in 80.
Return
The modeline based on the full GTF algorithm stored in a drm_display_mode object. The display mode object is allocated with drm_mode_create(). Returns NULL when no mode could be allocated.
create the modeline based on the GTF algorithm
Parameters
Description
return the modeline based on GTF algorithm
This function is to create the modeline based on the GTF algorithm. Generalized Timing Formula is derived from:
GTF Spreadsheet by Andy Morrish (1/5/97) available at http://www.vesa.org
And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c. What I have done is to translate it by using integer calculation. I also refer to the function of fb_get_mode in the file of drivers/video/fbmon.c
Standard GTF parameters:
M = 600
C = 40
K = 128
J = 20
Return
The modeline based on the GTF algorithm stored in a drm_display_mode object. The display mode object is allocated with drm_mode_create(). Returns NULL when no mode could be allocated.
fill in dmode using vm,
Parameters
Description
Fills out dmode using the display mode specified in vm.
fill in vm using dmode,
Parameters
Description
Fills out vm using the display mode specified in dmode.
extract information about pixelclk and DE polarity from videomode and store it in a separate variable
Parameters
Description
Sets DRM_BUS_FLAG_DE_(LOW|HIGH) and DRM_BUS_FLAG_PIXDATA_(POS|NEG)EDGE in bus_flags according to DISPLAY_FLAGS found in vm
get a drm_display_mode from devicetree
Parameters
Description
This function is expensive and should only be used, if only one mode is to be read from DT. To get multiple modes start with of_get_display_timings and work with that instead.
Return
0 on success, a negative errno code when no of videomode node was found.
set the name on a mode
Parameters
Description
Set the name of mode to a standard format which is <hdisplay>x<vdisplay> with an optional ‘i’ suffix for interlaced modes.
get the hsync of a mode
Parameters
Return
modes‘s hsync rate in kHz, rounded to the nearest integer. Calculates the value first if it is not yet set.
get the vrefresh of a mode
Parameters
Return
modes‘s vrefresh rate in Hz, rounded to the nearest integer. Calculates the value first if it is not yet set.
Fetches hdisplay/vdisplay for given mode
Parameters
Description
The vdisplay value will be doubled if the specified mode is a stereo mode of the appropriate layout.
set CRTC modesetting timing parameters
Parameters
Description
Setup the CRTC modesetting timing parameters for p, adjusting if necessary.
copy the mode
Parameters
Description
Copy an existing mode into another mode, preserving the object id and list head of the destination mode.
allocate and duplicate an existing mode
Parameters
Description
Just allocate a new mode, copy the existing mode into it, and return a pointer to it. Used to create new instances of established modes.
Return
Pointer to duplicated mode on success, NULL on error.
test modes for equality
Parameters
Description
Check to see if mode1 and mode2 are equivalent.
Return
True if the modes are equal, false otherwise.
test modes for equality
Parameters
Description
Check to see if mode1 and mode2 are equivalent, but don’t check the pixel clocks.
Return
True if the modes are equal, false otherwise.
test modes for equality
Parameters
Description
Check to see if mode1 and mode2 are equivalent, but don’t check the pixel clocks nor the stereo layout.
Return
True if the modes are equal, false otherwise.
make sure the mode is somewhat sane
Parameters
Description
Check that the mode timings are at least somewhat reasonable. Any hardware specific limits are left up for each driver to check.
Return
The mode status
make sure modes adhere to size constraints
Parameters
Description
This function is a helper which can be used to validate modes against size limitations of the DRM device/connector. If a mode is too big its status member is updated with the appropriate validation failure code. The list itself is not changed.
Return
The mode status
remove invalid modes from mode list
Parameters
Description
This helper function can be used to prune a display mode list after validation has been completed. All modes who’s status is not MODE_OK will be removed from the list, and if verbose the status code and mode name is also printed to dmesg.
sort mode list
Parameters
Description
Sort mode_list by favorability, moving good modes to the head of the list.
update the mode list for the connector
Parameters
Description
This moves the modes from the connector probed_modes list to the actual mode list. It compares the probed mode against the current list and only adds different/new modes.
This is just a helper functions doesn’t validate any modes itself and also doesn’t prune any invalid modes. Callers need to do that themselves.
parse command line modeline for connector
Parameters
Description
This parses mode_option command line modeline for modes and options to configure the connector. If mode_option is NULL the default command line modeline in fb_mode_option will be parsed instead.
This uses the same parameters as the fb modedb.c, except for an extra force-enable, force-enable-digital and force-disable bit at the end:
<xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
The intermediate drm_cmdline_mode structure is required to store additional options from the command line modline like the force-enable/disable flag.
Return
True if a valid modeline has been parsed, false otherwise.
convert a command line modeline into a DRM display mode
Parameters
Return
Pointer to converted mode on success, NULL on error.
In DRM connectors are the general abstraction for display sinks, and include als fixed panels or anything else that can display pixels in some form. As opposed to all other KMS objects representing hardware (like CRTC, encoder or plane abstractions) connectors can be hotplugged and unplugged at runtime. Hence they are reference-counted using drm_connector_get() and drm_connector_put().
KMS driver must create, initialize, register and attach at a struct drm_connector for each such sink. The instance is created as other KMS objects and initialized by setting the following fields. The connector is initialized with a call to drm_connector_init() with a pointer to the struct drm_connector_funcs and a connector type, and then exposed to userspace with a call to drm_connector_register().
Connectors must be attached to an encoder to be used. For devices that map connectors to encoders 1:1, the connector should be attached at initialization time with a call to drm_mode_connector_attach_encoder(). The driver must also set the drm_connector.encoder field to point to the attached encoder.
For connectors which are not fixed (like built-in panels) the driver needs to support hotplug notifications. The simplest way to do that is by using the probe helpers, see drm_kms_helper_poll_init() for connectors which don’t have hardware support for hotplug interrupts. Connectors with hardware hotplug support can instead use e.g. drm_helper_hpd_irq_event().
status for a drm_connector
Constants
Description
This enum is used to track the connector status. There are no separate #defines for the uapi!
Definition
struct drm_scrambling {
bool supported;
bool low_rates;
};
Members
runtime information about the connected HDMI sink
Definition
struct drm_hdmi_info {
struct drm_scdc scdc;
};
Members
Description
Describes if a given display supports advanced HDMI 2.0 features. This information is available in CEA-861-F extension blocks (like HF-VSDB).
connector’s link_status property value
Constants
Description
This enum is used as the connector’s link status property value. It is set to the values defined in uapi.
runtime data about the connected sink
Definition
struct drm_display_info {
char name[DRM_DISPLAY_INFO_LEN];
unsigned int width_mm;
unsigned int height_mm;
unsigned int pixel_clock;
unsigned int bpc;
enum subpixel_order subpixel_order;
#define DRM_COLOR_FORMAT_RGB444 (1\\\lt;\\\lt;0)
#define DRM_COLOR_FORMAT_YCRCB444 (1\\\lt;\\\lt;1)
#define DRM_COLOR_FORMAT_YCRCB422 (1\\\lt;\\\lt;2)
u32 color_formats;
const u32 * bus_formats;
unsigned int num_bus_formats;
#define DRM_BUS_FLAG_DE_LOW (1\\\lt;\\\lt;0)
#define DRM_BUS_FLAG_DE_HIGH (1\\\lt;\\\lt;1)
#define DRM_BUS_FLAG_PIXDATA_POSEDGE (1\\\lt;\\\lt;2)
#define DRM_BUS_FLAG_PIXDATA_NEGEDGE (1\\\lt;\\\lt;3)
u32 bus_flags;
int max_tmds_clock;
bool dvi_dual;
u8 edid_hdmi_dc_modes;
u8 cea_rev;
struct drm_hdmi_info hdmi;
};
Members
Description
Describes a given display (e.g. CRT or flat panel) and its limitations. For fixed display sinks like built-in panels there’s not much difference between this and struct drm_connector. But for sinks with a real cable this structure is meant to describe all the things at the other end of the cable.
For sinks which provide an EDID this can be filled out by calling drm_add_edid_modes().
TV connector related states
Definition
struct drm_tv_connector_state {
enum drm_mode_subconnector subconnector;
struct margins;
unsigned int mode;
unsigned int brightness;
unsigned int contrast;
unsigned int flicker_reduction;
unsigned int overscan;
unsigned int saturation;
unsigned int hue;
};
Members
mutable connector state
Definition
struct drm_connector_state {
struct drm_connector * connector;
struct drm_crtc * crtc;
struct drm_encoder * best_encoder;
enum drm_link_status link_status;
struct drm_atomic_state * state;
struct drm_tv_connector_state tv;
};
Members
CRTC to connect connector to, NULL if disabled.
Do not change this directly, use drm_atomic_set_crtc_for_connector() instead.
control connectors on a given device
Definition
struct drm_connector_funcs {
int (* dpms) (struct drm_connector *connector, int mode);
void (* reset) (struct drm_connector *connector);
enum drm_connector_status (* detect) (struct drm_connector *connector,bool force);
void (* force) (struct drm_connector *connector);
int (* fill_modes) (struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
int (* set_property) (struct drm_connector *connector, struct drm_property *property,uint64_t val);
int (* late_register) (struct drm_connector *connector);
void (* early_unregister) (struct drm_connector *connector);
void (* destroy) (struct drm_connector *connector);
struct drm_connector_state *(* atomic_duplicate_state) (struct drm_connector *connector);
void (* atomic_destroy_state) (struct drm_connector *connector,struct drm_connector_state *state);
int (* atomic_set_property) (struct drm_connector *connector,struct drm_connector_state *state,struct drm_property *property,uint64_t val);
int (* atomic_get_property) (struct drm_connector *connector,const struct drm_connector_state *state,struct drm_property *property,uint64_t *val);
void (* atomic_print_state) (struct drm_printer *p,const struct drm_connector_state *state);
};
Members
Legacy entry point to set the per-connector DPMS state. Legacy DPMS is exposed as a standard property on the connector, but diverted to this callback in the drm core. Note that atomic drivers don’t implement the 4 level DPMS support on the connector any more, but instead only have an on/off “ACTIVE” property on the CRTC object.
Drivers implementing atomic modeset should use drm_atomic_helper_connector_dpms() to implement this hook.
RETURNS:
0 on success or a negative error code on failure.
Reset connector hardware and software state to off. This function isn’t called by the core directly, only through drm_mode_config_reset(). It’s not a helper hook only for historical reasons.
Atomic drivers can use drm_atomic_helper_connector_reset() to reset atomic state using this hook.
Check to see if anything is attached to the connector. The parameter force is set to false whilst polling, true when checking the connector due to a user request. force can be used by the driver to avoid expensive, destructive operations during automated probing.
This callback is optional, if not implemented the connector will be considered as always being attached.
FIXME:
Note that this hook is only called by the probe helper. It’s not in the helper library vtable purely for historical reasons. The only DRM core entry point to probe connector state is fill_modes.
RETURNS:
drm_connector_status indicating the connector’s status.
This function is called to update internal encoder state when the connector is forced to a certain state by userspace, either through the sysfs interfaces or on the kernel cmdline. In that case the detect callback isn’t called.
FIXME:
Note that this hook is only called by the probe helper. It’s not in the helper library vtable purely for historical reasons. The only DRM core entry point to probe connector state is fill_modes.
Entry point for output detection and basic mode validation. The driver should reprobe the output if needed (e.g. when hotplug handling is unreliable), add all detected modes to drm_connector.modes and filter out any the device can’t support in any configuration. It also needs to filter out any modes wider or higher than the parameters max_width and max_height indicate.
The drivers must also prune any modes no longer valid from drm_connector.modes. Furthermore it must update drm_connector.status and drm_connector.edid. If no EDID has been received for this output connector->edid must be NULL.
Drivers using the probe helpers should use drm_helper_probe_single_connector_modes() or drm_helper_probe_single_connector_modes_nomerge() to implement this function.
RETURNS:
The number of modes detected and filled into drm_connector.modes.
This is the legacy entry point to update a property attached to the connector.
Drivers implementing atomic modeset should use drm_atomic_helper_connector_set_property() to implement this hook.
This callback is optional if the driver does not support any legacy driver-private properties.
RETURNS:
0 on success or a negative error code on failure.
This optional hook can be used to register additional userspace interfaces attached to the connector, light backlight control, i2c, DP aux or similar interfaces. It is called late in the driver load sequence from drm_connector_register() when registering all the core drm connector interfaces. Everything added from this callback should be unregistered in the early_unregister callback.
This is called while holding drm_connector.mutex.
Returns:
0 on success, or a negative error code on failure.
This optional hook should be used to unregister the additional userspace interfaces attached to the connector from late_register(). It is called from drm_connector_unregister(), early in the driver unload sequence to disable userspace access before data structures are torndown.
This is called while holding drm_connector.mutex.
Duplicate the current atomic state for this connector and return it. The core and helpers guarantee that any atomic state duplicated with this hook and still owned by the caller (i.e. not transferred to the driver by calling drm_mode_config_funcs.atomic_commit) will be cleaned up by calling the atomic_destroy_state hook in this structure.
Atomic drivers which don’t subclass struct drm_connector_state should use drm_atomic_helper_connector_duplicate_state(). Drivers that subclass the state structure to extend it with driver-private state should use __drm_atomic_helper_connector_duplicate_state() to make sure shared state is duplicated in a consistent fashion across drivers.
It is an error to call this hook before drm_connector.state has been initialized correctly.
NOTE:
If the duplicate state references refcounted resources this hook must acquire a reference for each of them. The driver must release these references again in atomic_destroy_state.
RETURNS:
Duplicated atomic state or NULL when the allocation failed.
Decode a driver-private property value and store the decoded value into the passed-in state structure. Since the atomic core decodes all standardized properties (even for extensions beyond the core set of properties which might not be implemented by all drivers) this requires drivers to subclass the state structure.
Such driver-private properties should really only be implemented for truly hardware/vendor specific state. Instead it is preferred to standardize atomic extension and decode the properties used to expose such an extension in the core.
Do not call this function directly, use drm_atomic_connector_set_property() instead.
This callback is optional if the driver does not support any driver-private atomic properties.
NOTE:
This function is called in the state assembly phase of atomic modesets, which can be aborted for any reason (including on userspace’s request to just check whether a configuration would be possible). Drivers MUST NOT touch any persistent state (hardware or software) or data structures except the passed in state parameter.
Also since userspace controls in which order properties are set this function must not do any input validation (since the state update is incomplete and hence likely inconsistent). Instead any such input validation must be done in the various atomic_check callbacks.
RETURNS:
0 if the property has been found, -EINVAL if the property isn’t implemented by the driver (which shouldn’t ever happen, the core only asks for properties attached to this connector). No other validation is allowed by the driver. The core already checks that the property value is within the range (integer, valid enum value, ...) the driver set when registering the property.
Reads out the decoded driver-private property. This is used to implement the GETCONNECTOR IOCTL.
Do not call this function directly, use drm_atomic_connector_get_property() instead.
This callback is optional if the driver does not support any driver-private atomic properties.
RETURNS:
0 on success, -EINVAL if the property isn’t implemented by the driver (which shouldn’t ever happen, the core only asks for properties attached to this connector).
If driver subclasses struct drm_connector_state, it should implement this optional hook for printing additional driver specific state.
Do not call this directly, use drm_atomic_connector_print_state() instead.
Description
Each CRTC may have one or more connectors attached to it. The functions below allow the core DRM code to control connectors, enumerate available modes, etc.
central DRM connector control structure
Definition
struct drm_connector {
struct drm_device * dev;
struct device * kdev;
struct device_attribute * attr;
struct list_head head;
struct drm_mode_object base;
char * name;
struct mutex mutex;
unsigned index;
int connector_type;
int connector_type_id;
bool interlace_allowed;
bool doublescan_allowed;
bool stereo_allowed;
bool registered;
struct list_head modes;
enum drm_connector_status status;
struct list_head probed_modes;
struct drm_display_info display_info;
const struct drm_connector_funcs * funcs;
struct drm_property_blob * edid_blob_ptr;
struct drm_object_properties properties;
struct drm_property_blob * path_blob_ptr;
struct drm_property_blob * tile_blob_ptr;
#define DRM_CONNECTOR_POLL_HPD (1 \\\lt;\\\lt; 0)
#define DRM_CONNECTOR_POLL_CONNECT (1 \\\lt;\\\lt; 1)
#define DRM_CONNECTOR_POLL_DISCONNECT (1 \\\lt;\\\lt; 2)
uint8_t polled;
int dpms;
const struct drm_connector_helper_funcs * helper_private;
struct drm_cmdline_mode cmdline_mode;
enum drm_connector_force force;
bool override_edid;
#define DRM_CONNECTOR_MAX_ENCODER 3
uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
struct drm_encoder * encoder;
#define MAX_ELD_BYTES 128
uint8_t eld[MAX_ELD_BYTES];
bool latency_present[2];
int video_latency[2];
int audio_latency[2];
int null_edid_counter;
unsigned bad_edid_counter;
bool edid_corrupt;
struct dentry * debugfs_entry;
struct drm_connector_state * state;
bool has_tile;
struct drm_tile_group * tile_group;
bool tile_is_single_monitor;
uint8_t num_h_tile;
uint8_t num_v_tile;
uint8_t tile_h_loc;
uint8_t tile_v_loc;
uint16_t tile_h_size;
uint16_t tile_v_size;
};
Members
Display information is filled from EDID information when a display is detected. For non hot-pluggable displays such as flat panels in embedded systems, the driver should initialize the drm_display_info.width_mm and drm_display_info.height_mm fields with the physical size of the display.
Protected by drm_mode_config.mutex.
Connector polling mode, a combination of
Set to 0 for connectors that don’t support connection status discovery.
Current atomic state for this connector.
This is protected by drm_mode_config.connection_mutex. Note that nonblocking atomic commits access the current connector state without taking locks. Either by going through the struct drm_atomic_state pointers, see for_each_connector_in_state(), for_each_oldnew_connector_in_state(), for_each_old_connector_in_state() and for_each_new_connector_in_state(). Or through careful ordering of atomic commit operations as implemented in the atomic helpers, see struct drm_crtc_commit.
Description
Each connector may be connected to one or more CRTCs, or may be clonable by another connector if they can share a CRTC. Each connector also has a specific position in the broader display (referred to as a ‘screen’ though it could span multiple monitors).
lookup connector object
Parameters
Description
This function looks up the connector object specified by id add takes a reference to it.
acquire a connector reference
Parameters
Description
This function increments the connector’s refcount.
release a connector reference
Parameters
Description
This function decrements the connector’s reference count and frees the object if the reference count drops to zero.
acquire a connector reference
Parameters
Description
This is a compatibility alias for drm_connector_get() and should not be used by new code.
release a connector reference
Parameters
Description
This is a compatibility alias for drm_connector_put() and should not be used by new code.
Tile group metadata
Definition
struct drm_tile_group {
struct kref refcount;
struct drm_device * dev;
int id;
u8 group_data[8];
};
Members
Description
group_data corresponds to displayid vend/prod/serial for external screens with an EDID.
iterate over all connectors
Parameters
Description
Iterate over all connectors of dev.
WARNING:
This iterator is not safe against hotadd/removal of connectors and is deprecated. Use drm_for_each_connector_iter() instead.
connector_list iterator
Definition
struct drm_connector_list_iter {
};
Members
Description
This iterator tracks state needed to be able to walk the connector_list within struct drm_mode_config. Only use together with drm_connector_list_iter_begin(), drm_connector_list_iter_end() and drm_connector_list_iter_next() respectively the convenience macro drm_for_each_connector_iter().
connector_list iterator macro
Parameters
Description
Note that connector is only valid within the list body, if you want to use connector after calling drm_connector_list_iter_end() then you need to grab your own reference first using drm_connector_begin().
Init a preallocated connector
Parameters
Description
Initialises a preallocated connector. Connectors should be subclassed as part of driver connector objects.
Return
Zero on success, error code on failure.
attach a connector to an encoder
Parameters
Description
This function links up a connector to an encoder. Note that the routing restrictions between encoders and crtcs are exposed to userspace through the possible_clones and possible_crtcs bitmasks.
Return
Zero on success, negative errno on failure.
cleans up an initialised connector
Parameters
Description
Cleans up the connector but doesn’t free the object.
register a connector
Parameters
Description
Register userspace interfaces for a connector
Return
Zero on success, error code on failure.
unregister a connector
Parameters
Description
Unregister userspace interfaces for a connector
return a string for connector status
Parameters
Description
In contrast to the other drm_get_*_name functions this one here returns a const pointer and hence is threadsafe.
initialize a connector_list iterator
Parameters
Description
Sets iter up to walk the drm_mode_config.connector_list of dev. iter must always be cleaned up again by calling drm_connector_list_iter_end(). Iteration itself happens using drm_connector_list_iter_next() or drm_for_each_connector_iter().
return next connector
Parameters
Description
Returns the next connector for iter, or NULL when the list walk has completed.
tear down a connector_list iterator
Parameters
Description
Tears down iter and releases any resources (like drm_connector references) acquired while walking the list. This must always be called, both when the iteration completes fully or when it was aborted without walking the entire list.
return a string for a given subpixel enum
Parameters
Description
Note you could abuse this and return something out of bounds, but that would be a caller error. No unscrubbed user data should make it here.
set the supported bus formats
Parameters
Description
Store the supported bus formats in display info structure. See MEDIA_BUS_FMT_* definitions in include/uapi/linux/media-bus-format.h for a full list of available formats.
create DVI-I specific connector properties
Parameters
Description
Called by a driver the first time a DVI-I connector is made.
create TV specific connector properties
Parameters
Description
Called by a driver’s TV initialization routine, this function creates the TV specific connector properties for a given device. Caller is responsible for allocating a list of format names and passing them to this routine.
create scaling mode property
Parameters
Description
Called by a driver the first time it’s needed, must be attached to desired connectors.
create aspect ratio property
Parameters
Description
Called by a driver the first time it’s needed, must be attached to desired connectors.
Return
Zero on success, negative errno on failure.
create suggests offset properties
Parameters
Description
Create the the suggested x/y offset property for connectors.
set tile property on connector
Parameters
Description
This creates a property to expose to userspace to specify a connector path. This is mainly used for DisplayPort MST where connectors have a topology and we want to allow userspace to give them more meaningful names.
Return
Zero on success, negative errno on failure.
set tile property on connector
Parameters
Description
This looks up the tile information for a connector, and creates a property for userspace to parse if it exists. The property is of the form of 8 integers using ‘:’ as a separator.
Return
Zero on success, errno on failure.
update the edid property of a connector
Parameters
Description
This function creates a new blob modeset object and assigns its id to the connector’s edid property.
Return
Zero on success, negative errno on failure.
Set link status property of a connector
Parameters
Description
In usual working scenario, this link status property will always be set to “GOOD”. If something fails during or after a mode set, the kernel driver may set this link status property to “BAD”. The caller then needs to send a hotplug uevent for userspace to re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
Note
Drivers cannot rely on userspace to support this property and issue a modeset. As such, they may choose to handle issues (like re-training a link) without userspace’s intervention.
The reason for adding this property is to handle link training failures, but it is not limited to DP or link training. For example, if we implement asynchronous setcrtc, this property can be used to report any failures in that.
drop a reference to a tile group.
Parameters
Description
drop reference to tile group and free if 0.
get a reference to an existing tile group
Parameters
Description
Use the unique bytes to get a reference to an existing tile group.
Return
tile group or NULL if not found.
create a tile group from a displayid description
Parameters
Description
Create a tile group for the unique monitor, and get a unique identifier for the tile group.
Return
new tile group or error.
Encoders represent the connecting element between the CRTC (as the overall pixel pipeline, represented by struct drm_crtc) and the connectors (as the generic sink entity, represented by struct drm_connector). An encoder takes pixel data from a CRTC and converts it to a format suitable for any attached connector. Encoders are objects exposed to userspace, originally to allow userspace to infer cloning and connector/CRTC restrictions. Unfortunately almost all drivers get this wrong, making the uabi pretty much useless. On top of that the exposed restrictions are too simple for today’s hardware, and the recommended way to infer restrictions is by using the DRM_MODE_ATOMIC_TEST_ONLY flag for the atomic IOCTL.
Otherwise encoders aren’t used in the uapi at all (any modeset request from userspace directly connects a connector with a CRTC), drivers are therefore free to use them however they wish. Modeset helper libraries make strong use of encoders to facilitate code sharing. But for more complex settings it is usually better to move shared code into a separate drm_bridge. Compared to encoders, bridges also have the benefit of being purely an internal abstraction since they are not exposed to userspace at all.
Encoders are initialized with drm_encoder_init() and cleaned up using drm_encoder_cleanup().
encoder controls
Definition
struct drm_encoder_funcs {
void (* reset) (struct drm_encoder *encoder);
void (* destroy) (struct drm_encoder *encoder);
int (* late_register) (struct drm_encoder *encoder);
void (* early_unregister) (struct drm_encoder *encoder);
};
Members
This optional hook can be used to register additional userspace interfaces attached to the encoder like debugfs interfaces. It is called late in the driver load sequence from drm_dev_register(). Everything added from this callback should be unregistered in the early_unregister callback.
Returns:
0 on success, or a negative error code on failure.
Description
Encoders sit between CRTCs and connectors.
central DRM encoder structure
Definition
struct drm_encoder {
struct drm_device * dev;
struct list_head head;
struct drm_mode_object base;
char * name;
int encoder_type;
unsigned index;
uint32_t possible_crtcs;
uint32_t possible_clones;
struct drm_crtc * crtc;
struct drm_bridge * bridge;
const struct drm_encoder_funcs * funcs;
const struct drm_encoder_helper_funcs * helper_private;
};
Members
One of the DRM_MODE_ENCODER_<foo> types in drm_mode.h. The following encoder types are defined thus far:
Bitmask of potential CRTC bindings, using drm_crtc_index() as the index into the bitfield. The driver must set the bits for all drm_crtc objects this encoder can be connected to before calling drm_encoder_init().
In reality almost every driver gets this wrong.
Note that since CRTC objects can’t be hotplugged the assigned indices are stable and hence known before registering all objects.
Bitmask of potential sibling encoders for cloning, using drm_encoder_index() as the index into the bitfield. The driver must set the bits for all drm_encoder objects which can clone a drm_crtc together with this encoder before calling drm_encoder_init(). Drivers should set the bit representing the encoder itself, too. Cloning bits should be set such that when two encoders can be used in a cloned configuration, they both should have each another bits set.
In reality almost every driver gets this wrong.
Note that since encoder objects can’t be hotplugged the assigned indices are stable and hence known before registering all objects.
Description
CRTCs drive pixels to encoders, which convert them into signals appropriate for a given connector or set of connectors.
find the index of a registered encoder
Parameters
Description
Given a registered encoder, return the index of that encoder within a DRM device’s list of encoders.
can a given crtc drive a given encoder?
Parameters
Description
Returns false if encoder can’t be driven by crtc, true otherwise.
find a drm_encoder
Parameters
Description
Returns the encoder with id, NULL if it doesn’t exist. Simple wrapper around drm_mode_object_find().
iterate over encoders specified by bitmask
Parameters
Description
Iterate over all encoders specified by bitmask.
iterate over all encoders
Parameters
Description
Iterate over all encoders of dev.
Init a preallocated encoder
Parameters
Description
Initialises a preallocated encoder. Encoder should be subclassed as part of driver encoder objects. At driver unload time drm_encoder_cleanup() should be called from the driver’s drm_encoder_funcs.destroy hook.
Return
Zero on success, error code on failure.
cleans up an initialised encoder
Parameters
Description
Cleans up the encoder but doesn’t free the object.
A KMS device is abstracted and exposed as a set of planes, CRTCs, encoders and connectors. KMS drivers must thus create and initialize all those objects at load time after initializing mode setting.
A CRTC is an abstraction representing a part of the chip that contains a pointer to a scanout buffer. Therefore, the number of CRTCs available determines how many independent scanout buffers can be active at any given time. The CRTC structure contains several fields to support this: a pointer to some video memory (abstracted as a frame buffer object), a display mode, and an (x, y) offset into the video memory to support panning or configurations where one piece of video memory spans multiple CRTCs.
A KMS device must create and register at least one struct struct drm_crtc instance. The instance is allocated and zeroed by the driver, possibly as part of a larger structure, and registered with a call to drm_crtc_init() with a pointer to CRTC functions.
The DRM core manages its objects’ lifetime. When an object is not needed anymore the core calls its destroy function, which must clean up and free every resource allocated for the object. Every drm_*_init() call must be matched with a corresponding drm_*_cleanup() call to cleanup CRTCs (drm_crtc_cleanup()), planes (drm_plane_cleanup()), encoders (drm_encoder_cleanup()) and connectors (drm_connector_cleanup()). Furthermore, connectors that have been added to sysfs must be removed by a call to drm_connector_unregister() before calling drm_connector_cleanup().
Connectors state change detection must be cleanup up with a call to drm_kms_helper_poll_fini().
void intel_crt_init(struct drm_device *dev)
{
struct drm_connector *connector;
struct intel_output *intel_output;
intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
if (!intel_output)
return;
connector = &intel_output->base;
drm_connector_init(dev, &intel_output->base,
&intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs,
DRM_MODE_ENCODER_DAC);
drm_mode_connector_attach_encoder(&intel_output->base,
&intel_output->enc);
/* Set up the DDC bus. */
intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A");
if (!intel_output->ddc_bus) {
dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
"failed.\n");
return;
}
intel_output->type = INTEL_OUTPUT_ANALOG;
connector->interlace_allowed = 0;
connector->doublescan_allowed = 0;
drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs);
drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
drm_connector_register(connector);
}
In the example above (taken from the i915 driver), a CRTC, connector and encoder combination is created. A device-specific i2c bus is also created for fetching EDID data and performing monitor detection. Once the process is complete, the new connector is registered with sysfs to make its properties available to applications.
As KMS moves toward more fine grained locking, and atomic ioctl where userspace can indirectly control locking order, it becomes necessary to use ww_mutex and acquire-contexts to avoid deadlocks. But because the locking is more distributed around the driver code, we want a bit of extra utility/tracking out of our acquire-ctx. This is provided by struct drm_modeset_lock and struct drm_modeset_acquire_ctx.
For basic principles of ww_mutex, see: Documentation/locking/ww-mutex-design.txt
The basic usage pattern is to:
drm_modeset_acquire_init(:c:type:`ctx`)
retry:
foreach (lock in random_ordered_set_of_locks) {
ret = drm_modeset_lock(lock, :c:type:`ctx`)
if (ret == -EDEADLK) {
drm_modeset_backoff(:c:type:`ctx`);
goto retry;
}
}
... do stuff ...
drm_modeset_drop_locks(:c:type:`ctx`);
drm_modeset_acquire_fini(:c:type:`ctx`);
On top of of these per-object locks using ww_mutex there’s also an overall drm_mode_config.mutex, for protecting everything else. Mostly this means probe state of connectors, and preventing hotplug add/removal of connectors.
Finally there’s a bunch of dedicated locks to protect drm core internal lists and lookup data structures.
locking context (see ww_acquire_ctx)
Definition
struct drm_modeset_acquire_ctx {
struct ww_acquire_ctx ww_ctx;
struct drm_modeset_lock * contended;
struct list_head locked;
bool trylock_only;
};
Members
Description
Each thread competing for a set of locks must use one acquire ctx. And if any lock fxn returns -EDEADLK, it must backoff and retry.
used for locking modeset resources.
Definition
struct drm_modeset_lock {
struct ww_mutex mutex;
struct list_head head;
};
Members
Description
Used for locking CRTCs and other modeset resources.
cleanup lock
Parameters
equivalent to mutex_is_locked()
Parameters
take all modeset locks
Parameters
Description
This function takes all modeset locks, suitable where a more fine-grained scheme isn’t (yet) implemented. Locks must be dropped by calling the drm_modeset_unlock_all() function.
This function is deprecated. It allocates a lock acquisition context and stores it in drm_device.mode_config. This facilitate conversion of existing code because it removes the need to manually deal with the acquisition context, but it is also brittle because the context is global and care must be taken not to nest calls. New code should use the drm_modeset_lock_all_ctx() function and pass in the context explicitly.
drop all modeset locks
Parameters
Description
This function drops all modeset locks taken by a previous call to the drm_modeset_lock_all() function.
This function is deprecated. It uses the lock acquisition context stored in drm_device.mode_config. This facilitates conversion of existing code because it removes the need to manually deal with the acquisition context, but it is also brittle because the context is global and care must be taken not to nest calls. New code should pass the acquisition context directly to the drm_modeset_drop_locks() function.
lock crtc with hidden acquire ctx for a plane update
Parameters
Description
This function locks the given crtc and plane (which should be either the primary or cursor plane) using a hidden acquire context. This is necessary so that drivers internally using the atomic interfaces can grab further locks with the lock acquire context.
Note that plane can be NULL, e.g. when the cursor support hasn’t yet been converted to universal planes yet.
find acquire ctx for legacy ioctls
Parameters
Description
Legacy ioctl operations like cursor updates or page flips only have per-crtc locking, and store the acquire ctx in the corresponding crtc. All other legacy operations take all locks and use a global acquire context. This function grabs the right one.
Parameters
Description
This drops the crtc lock acquire with drm_modeset_lock_crtc() and all other locks acquired through the hidden context.
check that all modeset locks are locked
Parameters
Description
Useful as a debug assert.
initialize acquire context
Parameters
cleanup acquire context
Parameters
drop all locks
Parameters
Description
Drop all locks currently held against this acquire context.
deadlock avoidance backoff
Parameters
Description
If deadlock is detected (ie. drm_modeset_lock() returns -EDEADLK), you must call this function to drop all currently held locks and block until the contended lock becomes available.
deadlock avoidance backoff
Parameters
Description
Interruptible version of drm_modeset_backoff()
initialize lock
Parameters
take modeset lock
Parameters
Description
If ctx is not NULL, then its ww acquire context is used and the lock will be tracked by the context and can be released by calling drm_modeset_drop_locks(). If -EDEADLK is returned, this means a deadlock scenario has been detected and it is an error to attempt to take any more locks without first calling drm_modeset_backoff().
take modeset lock
Parameters
Description
Interruptible version of drm_modeset_lock()
drop modeset lock
Parameters
take all modeset locks
Parameters
Description
This function takes all modeset locks, suitable where a more fine-grained scheme isn’t (yet) implemented.
Unlike drm_modeset_lock_all(), it doesn’t take the drm_mode_config.mutex since that lock isn’t required for modeset state changes. Callers which need to grab that lock too need to do so outside of the acquire context ctx.
Locks acquired with this function should be released by calling the drm_modeset_drop_locks() function on ctx.
Return
0 on success or a negative error-code on failure.
Properties as represented by drm_property are used to extend the modeset interface exposed to userspace. For the atomic modeset IOCTL properties are even the only way to transport metadata about the desired new modeset configuration from userspace to the kernel. Properties have a well-defined value range, which is enforced by the drm core. See the documentation of the flags member of struct drm_property for an overview of the different property types and ranges.
Properties don’t store the current value directly, but need to be instatiated by attaching them to a drm_mode_object with drm_object_attach_property().
Property values are only 64bit. To support bigger piles of data (like gamma tables, color correction matrices or large structures) a property can instead point at a drm_property_blob with that additional data.
Properties are defined by their symbolic name, userspace must keep a per-object mapping from those names to the property ID used in the atomic IOCTL and in the get/set property IOCTL.
symbolic values for enumerations
Definition
struct drm_property_enum {
uint64_t value;
struct list_head head;
char name[DRM_PROP_NAME_LEN];
};
Members
Description
For enumeration and bitmask properties this structure stores the symbolic decoding for each value. This is used for example for the rotation property.
modeset object property
Definition
struct drm_property {
struct list_head head;
struct drm_mode_object base;
uint32_t flags;
char name[DRM_PROP_NAME_LEN];
uint32_t num_values;
uint64_t * values;
struct drm_device * dev;
struct list_head enum_list;
};
Members
Property flags and type. A property needs to be one of the following types:
Object properties are used to link modeset objects. This is used extensively in the atomic support to create the display pipeline, by linking drm_framebuffer to drm_plane, drm_plane to drm_crtc and drm_connector to drm_crtc. An object property can only link to a specific type of drm_mode_object, this limit is enforced by the core. Object properties are created using drm_property_create_object().
Object properties work like blob properties, but in a more general fashion. They are limited to atomic drivers and must have the DRM_MODE_PROP_ATOMIC flag set.
Blob properties store a binary blob without any format restriction. The binary blobs are created as KMS standalone objects, and blob property instance values store the ID of their associated blob object. Blob properties are created by calling drm_property_create() with DRM_MODE_PROP_BLOB as the type.
Actual blob objects to contain blob data are created using drm_property_create_blob(), or through the corresponding IOCTL.
Besides the built-in limit to only accept blob objects blob properties work exactly like object properties. The only reasons blob properties exist is backwards compatibility with existing userspace.
In addition a property can have any combination of the below flags:
Description
This structure represent a modeset object property. It combines both the name of the property with the set of permissible values. This means that when a driver wants to use a property with the same name on different objects, but with different value ranges, then it must create property for each one. An example would be rotation of drm_plane, when e.g. the primary plane cannot be rotated. But if both the name and the value range match, then the same property structure can be instantiated multiple times for the same object. Userspace must be able to cope with this and cannot assume that the same symbolic property will have the same modeset object ID on all modeset objects.
Properties are created by one of the special functions, as explained in detail in the flags structure member.
To actually expose a property it must be attached to each object using drm_object_attach_property(). Currently properties can only be attached to drm_connector, drm_crtc and drm_plane.
Properties are also used as the generic metadatatransport for the atomic IOCTL. Everything that was set directly in structures in the legacy modeset IOCTLs (like the plane source or destination windows, or e.g. the links to the CRTC) is exposed as a property with the DRM_MODE_PROP_ATOMIC flag set.
Blob data for drm_property
Definition
struct drm_property_blob {
struct drm_mode_object base;
struct drm_device * dev;
struct list_head head_global;
struct list_head head_file;
size_t length;
unsigned char data[];
};
Members
Description
Blobs are used to store bigger values than what fits directly into the 64 bits available for a drm_property.
Blobs are reference counted using drm_property_blob_get() and drm_property_blob_put(). They are created using drm_property_create_blob().
check the type of a property
Parameters
Description
This is a helper function becauase the uapi encoding of property types is a bit special for historical reasons.
acquire a blob property reference
Parameters
Description
This is a compatibility alias for drm_property_blob_get() and should not be used by new code.
release a blob property reference
Parameters
Description
This is a compatibility alias for drm_property_blob_put() and should not be used by new code.
find property object
Parameters
Description
This function looks up the property object specified by id and returns it.
create a new property type
Parameters
Description
This creates a new generic drm property which can then be attached to a drm object with drm_object_attach_property(). The returned property object must be freed with drm_property_destroy(), which is done automatically when calling drm_mode_config_cleanup().
Return
A pointer to the newly created property on success, NULL on failure.
create a new enumeration property type
Parameters
Description
This creates a new generic drm property which can then be attached to a drm object with drm_object_attach_property(). The returned property object must be freed with drm_property_destroy(), which is done automatically when calling drm_mode_config_cleanup().
Userspace is only allowed to set one of the predefined values for enumeration properties.
Return
A pointer to the newly created property on success, NULL on failure.
create a new bitmask property type
Parameters
Description
This creates a new bitmask drm property which can then be attached to a drm object with drm_object_attach_property(). The returned property object must be freed with drm_property_destroy(), which is done automatically when calling drm_mode_config_cleanup().
Compared to plain enumeration properties userspace is allowed to set any or’ed together combination of the predefined property bitflag values
Return
A pointer to the newly created property on success, NULL on failure.
create a new unsigned ranged property type
Parameters
Description
This creates a new generic drm property which can then be attached to a drm object with drm_object_attach_property(). The returned property object must be freed with drm_property_destroy(), which is done automatically when calling drm_mode_config_cleanup().
Userspace is allowed to set any unsigned integer value in the (min, max) range inclusive.
Return
A pointer to the newly created property on success, NULL on failure.
create a new signed ranged property type
Parameters
Description
This creates a new generic drm property which can then be attached to a drm object with drm_object_attach_property(). The returned property object must be freed with drm_property_destroy(), which is done automatically when calling drm_mode_config_cleanup().
Userspace is allowed to set any signed integer value in the (min, max) range inclusive.
Return
A pointer to the newly created property on success, NULL on failure.
create a new object property type
Parameters
Description
This creates a new generic drm property which can then be attached to a drm object with drm_object_attach_property(). The returned property object must be freed with drm_property_destroy(), which is done automatically when calling drm_mode_config_cleanup().
Userspace is only allowed to set this to any property value of the given type. Only useful for atomic properties, which is enforced.
Return
A pointer to the newly created property on success, NULL on failure.
create a new boolean property type
Parameters
Description
This creates a new generic drm property which can then be attached to a drm object with drm_object_attach_property(). The returned property object must be freed with drm_property_destroy(), which is done automatically when calling drm_mode_config_cleanup().
This is implemented as a ranged property with only {0, 1} as valid values.
Return
A pointer to the newly created property on success, NULL on failure.
add a possible value to an enumeration property
Parameters
Description
This functions adds enumerations to a property.
It’s use is deprecated, drivers should use one of the more specific helpers to directly create the property with all enumerations already attached.
Return
Zero on success, error code on failure.
destroy a drm property
Parameters
Description
This function frees a property including any attached resources like enumeration values.
Create new blob property
Parameters
Description
Creates a new blob property for a specified DRM device, optionally copying data. Note that blob properties are meant to be invariant, hence the data must be filled out before the blob is used as the value of any property.
Return
New blob property with a single reference on success, or an ERR_PTR value on failure.
release a blob property reference
Parameters
Description
Releases a reference to a blob property. May free the object.
acquire blob property reference
Parameters
Description
Acquires a reference to an existing blob property. Returns blob, which allows this to be used as a shorthand in assignments.
look up a blob property and take a reference
Parameters
Description
If successful, this takes an additional reference to the blob property. callers need to make sure to eventually unreference the returned property again, using drm_property_blob_put().
Return
NULL on failure, pointer to the blob on success.
replace existing blob property
Parameters
Description
This function will replace a global property in the blob list, optionally updating a property which holds the ID of that property.
If length is 0 or data is NULL, no new blob will be created, and the holding property, if specified, will be set to 0.
Access to the replace pointer is assumed to be protected by the caller, e.g. by holding the relevant modesetting object lock for its parent.
For example, a drm_connector has a ‘PATH’ property, which contains the ID of a blob property with the value of the MST path information. Calling this function with replace pointing to the connector’s path_blob_ptr, length and data set for the new path information, obj_holds_id set to the connector’s base object, and prop_holds_id set to the path property name, will perform a completely atomic update. The access to path_blob_ptr is protected by the caller holding a lock on the connector.
DRM connectors have a few standardized properties:
Connectors also have one standardized atomic property:
The basic plane composition model supported by standard plane properties only has a source rectangle (in logical pixels within the drm_framebuffer), with sub-pixel accuracy, which is scaled up to a pixel-aligned destination rectangle in the visible area of a drm_crtc. The visible area of a CRTC is defined by the horizontal and vertical visible pixels (stored in hdisplay and vdisplay) of the requested mode (stored in drm_crtc_state.mode). These two rectangles are both stored in the drm_plane_state.
For the atomic ioctl the following standard (atomic) properties on the plane object encode the basic plane composition model:
Note that the source rectangle must fully lie within the bounds of the drm_framebuffer. The destination rectangle can lie outside of the visible area of the current mode of the CRTC. It must be apprpriately clipped by the driver, which can be done by calling drm_plane_helper_check_update(). Drivers are also allowed to round the subpixel sampling positions appropriately, but only to the next full pixel. No pixel outside of the source rectangle may ever be sampled, which is important when applying more sophisticated filtering than just a bilinear one when scaling. The filtering mode when scaling is unspecified.
On top of this basic transformation additional properties can be exposed by the driver:
Note that all the property extensions described here apply either to the plane or the CRTC (e.g. for the background color, which currently is not exposed and assumed to be black).
create a new rotation property
Parameters
Description
This creates a new property with the selected support for transformations.
Since a rotation by 180° degress is the same as reflecting both along the x and the y axis the rotation property is somewhat redundant. Drivers can use drm_rotation_simplify() to normalize values of this property.
The property exposed to userspace is a bitmask property (see drm_property_create_bitmask()) called “rotation” and has the following bitmask enumaration values:
Rotation is the specified amount in degrees in counter clockwise direction, the X and Y axis are within the source rectangle, i.e. the X/Y axis before rotation. After reflection, the rotation is applied to the image sampled from the source rectangle, before scaling it to fit the destination rectangle.
Try to simplify the rotation
Parameters
Description
Attempt to simplify the rotation to a form that is supported. Eg. if the hardware supports everything except DRM_REFLECT_X one could call this function like this:
to eliminate the DRM_ROTATE_X flag. Depending on what kind of transforms the hardware supports, this function may not be able to produce a supported transform, so the caller should check the result afterwards.
create mutable zpos property
Parameters
Description
This function initializes generic mutable zpos property and enables support for it in drm core. Drivers can then attach this property to planes to enable support for configurable planes arrangement during blending operation. Once mutable zpos property has been enabled, the DRM core will automatically calculate drm_plane_state.normalized_zpos values. Usually min should be set to 0 and max to maximal number of planes for given crtc - 1.
If zpos of some planes cannot be changed (like fixed background or cursor/topmost planes), driver should adjust min/max values and assign those planes immutable zpos property with lower or higher values (for more information, see drm_plane_create_zpos_immutable_property() function). In such case driver should also assign proper initial zpos values for all planes in its plane_reset() callback, so the planes will be always sorted properly.
See also drm_atomic_normalize_zpos().
The property exposed to userspace is called “zpos”.
Return
Zero on success, negative errno on failure.
create immuttable zpos property
Parameters
Description
This function initializes generic immutable zpos property and enables support for it in drm core. Using this property driver lets userspace to get the arrangement of the planes for blending operation and notifies it that the hardware (or driver) doesn’t support changing of the planes’ order. For mutable zpos see drm_plane_create_zpos_property().
The property exposed to userspace is called “zpos”.
Return
Zero on success, negative errno on failure.
calculate normalized zpos values for all crtcs
Parameters
Description
This function calculates normalized zpos value for all modified planes in the provided atomic state of DRM device.
For every CRTC this function checks new states of all planes assigned to it and calculates normalized zpos value for these planes. Planes are compared first by their zpos values, then by plane id (if zpos is equal). The plane with lowest zpos value is at the bottom. The drm_plane_state.normalized_zpos is then filled with unique values from 0 to number of active planes in crtc minus one.
RETURNS Zero for success or -errno
Color management or color space adjustments is supported through a set of 5 properties on the drm_crtc object. They are set up by calling drm_crtc_enable_color_mgmt().
Blob property to set the degamma lookup table (LUT) mapping pixel data from the framebuffer before it is given to the transformation matrix. The data is interpreted as an array of struct drm_color_lut elements. Hardware might choose not to use the full precision of the LUT elements nor use all the elements of the LUT (for example the hardware might choose to interpolate between LUT[0] and LUT[4]).
Setting this to NULL (blob property value set to 0) means a linear/pass-thru gamma table should be used. This is generally the driver boot-up state too.
Blob property to set the current transformation matrix (CTM) apply to pixel data after the lookup through the degamma LUT and before the lookup through the gamma LUT. The data is interpreted as a struct drm_color_ctm.
Setting this to NULL (blob property value set to 0) means a unit/pass-thru matrix should be used. This is generally the driver boot-up state too.
Blob property to set the gamma lookup table (LUT) mapping pixel data after the transformation matrix to data sent to the connector. The data is interpreted as an array of struct drm_color_lut elements. Hardware might choose not to use the full precision of the LUT elements nor use all the elements of the LUT (for example the hardware might choose to interpolate between LUT[0] and LUT[4]).
Setting this to NULL (blob property value set to 0) means a linear/pass-thru gamma table should be used. This is generally the driver boot-up state too.
There is also support for a legacy gamma table, which is set up by calling drm_mode_crtc_set_gamma_size(). Drivers which support both should use drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the “GAMMA_LUT” property above.
clamp and round LUT entries
Parameters
Description
Extract a degamma/gamma LUT value provided by user (in the form of drm_color_lut entries) and round it to the precision supported by the hardware.
enable color management properties
Parameters
Description
This function lets the driver enable the color correction properties on a CRTC. This includes 3 degamma, csc and gamma properties that userspace can set and 2 size properties to inform the userspace of the lut sizes. Each of the properties are optional. The gamma and degamma properties are only attached if their size is not 0 and ctm_property is only attached if has_ctm is true.
Parameters
Description
Drivers which support gamma tables should set this to the supported gamma table size when initializing the CRTC. Currently the drm core only supports a fixed gamma table size.
Return
Zero on success, negative errno on failure.
Tile groups are used to represent tiled monitors with a unique integer identifier. Tiled monitors using DisplayID v1.3 have a unique 8-byte handle, we store this in a tile group, so we have a common identifier for all tiles in a monitor group. The property is called “TILE”. Drivers can manage tile groups using drm_mode_create_tile_group(), drm_mode_put_tile_group() and drm_mode_get_tile_group(). But this is only needed for internal panels where the tile group information is exposed through a non-standard way.
Explicit fencing allows userspace to control the buffer synchronization between devices. A Fence or a group of fences are transfered to/from userspace using Sync File fds and there are two DRM properties for that. IN_FENCE_FD on each DRM Plane to send fences to the kernel and OUT_FENCE_PTR on each DRM CRTC to receive fences from the kernel.
As a contrast, with implicit fencing the kernel keeps track of any ongoing rendering, and automatically ensures that the atomic update waits for any pending rendering to complete. For shared buffers represented with a struct dma_buf this is tracked in struct reservation_object. Implicit syncing is how Linux traditionally worked (e.g. DRI2/3 on X.org), whereas explicit fencing is what Android wants.
Use this property to pass a fence that DRM should wait on before proceeding with the Atomic Commit request and show the framebuffer for the plane on the screen. The fence can be either a normal fence or a merged one, the sync_file framework will handle both cases and use a fence_array if a merged fence is received. Passing -1 here means no fences to wait on.
If the Atomic Commit request has the DRM_MODE_ATOMIC_TEST_ONLY flag it will only check if the Sync File is a valid one.
On the driver side the fence is stored on the fence parameter of struct drm_plane_state. Drivers which also support implicit fencing should set the implicit fence using drm_atomic_set_fence_for_plane(), to make sure there’s consistent behaviour between drivers in precedence of implicit vs. explicit fencing.
Use this property to pass a file descriptor pointer to DRM. Once the Atomic Commit request call returns OUT_FENCE_PTR will be filled with the file descriptor number of a Sync File. This Sync File contains the CRTC fence that will be signaled when all framebuffers present on the Atomic Commit * request for that given CRTC are scanned out on the screen.
The Atomic Commit request fails if a invalid pointer is passed. If the Atomic Commit request fails for any other reason the out fence fd returned will be -1. On a Atomic Commit with the DRM_MODE_ATOMIC_TEST_ONLY flag the out fence will also be set to -1.
Note that out-fences don’t have a special interface to drivers and are internally represented by a struct drm_pending_vblank_event in struct drm_crtc_state, which is also used by the nonblocking atomic commit helpers and for the DRM event handling for existing userspace.
The following table gives description of drm properties exposed by various modules/drivers.
Owner Module/Drivers | Group | Property Name | Type | Property Values | Object attached | Description/Restrictions |
---|---|---|---|---|---|---|
“scaling mode” | ENUM | { “None”, “Full”, “Center”, “Full aspect” } | Connector | Supported by: amdgpu, gma500, i915, nouveau and radeon. | ||
DVI-I | “subconnector” | ENUM | { “Unknown”, “DVI-D”, “DVI-A” } | Connector | TBD | |
“select subconnector” | ENUM | { “Automatic”, “DVI-D”, “DVI-A” } | Connector | TBD | ||
TV | “subconnector” | ENUM | { “Unknown”, “Composite”, “SVIDEO”, “Component”, “SCART” } | Connector | TBD | |
“select subconnector” | ENUM | { “Automatic”, “Composite”, “SVIDEO”, “Component”, “SCART” } | Connector | TBD | ||
“mode” | ENUM | { “NTSC_M”, “NTSC_J”, “NTSC_443”, “PAL_B” } etc. | Connector | TBD | ||
“left margin” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“right margin” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“top margin” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“bottom margin” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“brightness” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“contrast” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“flicker reduction” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“overscan” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“saturation” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“hue” | RANGE | Min=0, Max=100 | Connector | TBD | ||
Virtual GPU | “suggested X” | RANGE | Min=0, Max=0xffffffff | Connector | property to suggest an X offset for a connector | |
“suggested Y” | RANGE | Min=0, Max=0xffffffff | Connector | property to suggest an Y offset for a connector | ||
Optional | “aspect ratio” | ENUM | { “None”, “4:3”, “16:9” } | Connector | TDB | |
i915 | Generic | “Broadcast RGB” | ENUM | { “Automatic”, “Full”, “Limited 16:235” } | Connector | When this property is set to Limited 16:235 and CTM is set, the hardware will be programmed with the result of the multiplication of CTM by the limited range matrix to ensure the pixels normaly in the range 0..1.0 are remapped to the range 16/255..235/255. |
“audio” | ENUM | { “force-dvi”, “off”, “auto”, “on” } | Connector | TBD | ||
SDVO-TV | “mode” | ENUM | { “NTSC_M”, “NTSC_J”, “NTSC_443”, “PAL_B” } etc. | Connector | TBD | |
“left_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“right_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“top_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“bottom_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“hpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“vpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“contrast” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“saturation” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“hue” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“sharpness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“flicker_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“flicker_filter_adaptive” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“flicker_filter_2d” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“tv_chroma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“tv_luma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“dot_crawl” | RANGE | Min=0, Max=1 | Connector | TBD | ||
SDVO-TV/LVDS | “brightness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | |
CDV gma-500 | Generic | “Broadcast RGB” | ENUM | { “Full”, “Limited 16:235” } | Connector | TBD |
“Broadcast RGB” | ENUM | { “off”, “auto”, “on” } | Connector | TBD | ||
Poulsbo | Generic | “backlight” | RANGE | Min=0, Max=100 | Connector | TBD |
SDVO-TV | “mode” | ENUM | { “NTSC_M”, “NTSC_J”, “NTSC_443”, “PAL_B” } etc. | Connector | TBD | |
“left_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“right_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“top_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“bottom_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“hpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“vpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“contrast” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“saturation” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“hue” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“sharpness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“flicker_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“flicker_filter_adaptive” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“flicker_filter_2d” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“tv_chroma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“tv_luma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“dot_crawl” | RANGE | Min=0, Max=1 | Connector | TBD | ||
SDVO-TV/LVDS | “brightness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | |
armada | CRTC | “CSC_YUV” | ENUM | { “Auto” , “CCIR601”, “CCIR709” } | CRTC | TBD |
“CSC_RGB” | ENUM | { “Auto”, “Computer system”, “Studio” } | CRTC | TBD | ||
Overlay | “colorkey” | RANGE | Min=0, Max=0xffffff | Plane | TBD | |
“colorkey_min” | RANGE | Min=0, Max=0xffffff | Plane | TBD | ||
“colorkey_max” | RANGE | Min=0, Max=0xffffff | Plane | TBD | ||
“colorkey_val” | RANGE | Min=0, Max=0xffffff | Plane | TBD | ||
“colorkey_alpha” | RANGE | Min=0, Max=0xffffff | Plane | TBD | ||
“colorkey_mode” | ENUM | { “disabled”, “Y component”, “U component” , “V component”, “RGB”, “R component”, “G component”, “B component” } | Plane | TBD | ||
“brightness” | RANGE | Min=0, Max=256 + 255 | Plane | TBD | ||
“contrast” | RANGE | Min=0, Max=0x7fff | Plane | TBD | ||
“saturation” | RANGE | Min=0, Max=0x7fff | Plane | TBD | ||
exynos | CRTC | “mode” | ENUM | { “normal”, “blank” } | CRTC | TBD |
i2c/ch7006_drv | Generic | “scale” | RANGE | Min=0, Max=2 | Connector | TBD |
TV | “mode” | ENUM | { “PAL”, “PAL-M”,”PAL-N”}, ”PAL-Nc” , “PAL-60”, “NTSC-M”, “NTSC-J” } | Connector | TBD | |
nouveau | NV10 Overlay | “colorkey” | RANGE | Min=0, Max=0x01ffffff | Plane | TBD |
“contrast” | RANGE | Min=0, Max=8192-1 | Plane | TBD | ||
“brightness” | RANGE | Min=0, Max=1024 | Plane | TBD | ||
“hue” | RANGE | Min=0, Max=359 | Plane | TBD | ||
“saturation” | RANGE | Min=0, Max=8192-1 | Plane | TBD | ||
“iturbt_709” | RANGE | Min=0, Max=1 | Plane | TBD | ||
Nv04 Overlay | “colorkey” | RANGE | Min=0, Max=0x01ffffff | Plane | TBD | |
“brightness” | RANGE | Min=0, Max=1024 | Plane | TBD | ||
Display | “dithering mode” | ENUM | { “auto”, “off”, “on” } | Connector | TBD | |
“dithering depth” | ENUM | { “auto”, “off”, “on”, “static 2x2”, “dynamic 2x2”, “temporal” } | Connector | TBD | ||
“underscan” | ENUM | { “auto”, “6 bpc”, “8 bpc” } | Connector | TBD | ||
“underscan hborder” | RANGE | Min=0, Max=128 | Connector | TBD | ||
“underscan vborder” | RANGE | Min=0, Max=128 | Connector | TBD | ||
“vibrant hue” | RANGE | Min=0, Max=180 | Connector | TBD | ||
“color vibrance” | RANGE | Min=0, Max=200 | Connector | TBD | ||
omap | Generic | “zorder” | RANGE | Min=0, Max=3 | CRTC, Plane | TBD |
qxl | Generic | “hotplug_mode_update” | RANGE | Min=0, Max=1 | Connector | TBD |
radeon | DVI-I | “coherent” | RANGE | Min=0, Max=1 | Connector | TBD |
DAC enable load detect | “load detection” | RANGE | Min=0, Max=1 | Connector | TBD | |
TV Standard | “tv standard” | ENUM | { “ntsc”, “pal”, “pal-m”, “pal-60”, “ntsc-j” , “scart-pal”, “pal-cn”, “secam” } | Connector | TBD | |
legacy TMDS PLL detect | “tmds_pll” | ENUM | { “driver”, “bios” } | TBD | ||
Underscan | “underscan” | ENUM | { “off”, “on”, “auto” } | Connector | TBD | |
“underscan hborder” | RANGE | Min=0, Max=128 | Connector | TBD | ||
“underscan vborder” | RANGE | Min=0, Max=128 | Connector | TBD | ||
Audio | “audio” | ENUM | { “off”, “on”, “auto” } | Connector | TBD | |
FMT Dithering | “dither” | ENUM | { “off”, “on” } | Connector | TBD | |
rcar-du | Generic | “alpha” | RANGE | Min=0, Max=255 | Plane | TBD |
“colorkey” | RANGE | Min=0, Max=0x01ffffff | Plane | TBD |
Vertical blanking plays a major role in graphics rendering. To achieve tear-free display, users must synchronize page flips and/or rendering to vertical blanking. The DRM API offers ioctls to perform page flips synchronized to vertical blanking and wait for vertical blanking.
The DRM core handles most of the vertical blanking management logic, which involves filtering out spurious interrupts, keeping race-free blanking counters, coping with counter wrap-around and resets and keeping use counts. It relies on the driver to generate vertical blanking interrupts and optionally provide a hardware vertical blanking counter. Drivers must implement the following operations.
Drivers must initialize the vertical blanking handling core with a call to drm_vblank_init() in their load operation.
Vertical blanking interrupts can be enabled by the DRM core or by drivers themselves (for instance to handle page flipping operations). The DRM core maintains a vertical blanking use count to ensure that the interrupts are not disabled while a user still needs them. To increment the use count, drivers call drm_vblank_get(). Upon return vertical blanking interrupts are guaranteed to be enabled.
To decrement the use count drivers call drm_vblank_put(). Only when the use count drops to zero will the DRM core disable the vertical blanking interrupts after a delay by scheduling a timer. The delay is accessible through the vblankoffdelay module parameter or the drm_vblank_offdelay global variable and expressed in milliseconds. Its default value is 5000 ms. Zero means never disable, and a negative value means disable immediately. Drivers may override the behaviour by setting the struct drm_device vblank_disable_immediate flag, which when set causes vblank interrupts to be disabled immediately regardless of the drm_vblank_offdelay value. The flag should only be set if there’s a properly working hardware vblank counter present.
When a vertical blanking interrupt occurs drivers only need to call the drm_handle_vblank() function to account for the interrupt.
Resources allocated by drm_vblank_init() must be freed with a call to drm_vblank_cleanup() in the driver unload operation handler.
pending vblank event tracking
Definition
struct drm_pending_vblank_event {
struct drm_pending_event base;
unsigned int pipe;
struct drm_event_vblank event;
};
Members
vblank tracking for a CRTC
Definition
struct drm_vblank_crtc {
struct drm_device * dev;
wait_queue_head_t queue;
struct timer_list disable_timer;
seqlock_t seqlock;
u32 count;
struct timeval time;
atomic_t refcount;
u32 last;
unsigned int inmodeset;
unsigned int pipe;
int framedur_ns;
int linedur_ns;
bool enabled;
};
Members
Description
This structure tracks the vblank state for one CRTC.
Note that for historical reasons - the vblank handling code is still shared with legacy/non-kms drivers - this is a free-standing structure not directly connected to struct drm_crtc. But all public interface functions are taking a struct drm_crtc to hide this implementation detail.
get vblank waitqueue for the CRTC
Parameters
Description
This function returns a pointer to the vblank waitqueue for the CRTC. Drivers can use this to implement vblank waits using wait_event() and related functions.
Parameters
Description
This function is similar to drm_crtc_vblank_count but this function interpolates to handle a race with vblank irq’s.
This is mostly useful for hardware that can obtain the scanout position, but doesn’t have a frame counter.
cleanup vblank support
Parameters
Description
This function cleans up any resources allocated in drm_vblank_init.
initialize vblank support
Parameters
Description
This function initializes vblank support for num_crtcs display pipelines.
Return
Zero on success or a negative error code on failure.
install IRQ handler
Parameters
Description
Initializes the IRQ related data. Installs the handler, calling the driver irq_preinstall() and irq_postinstall() functions before and after the installation.
This is the simplified helper interface provided for drivers with no special needs. Drivers which need to install interrupt handlers for multiple interrupts must instead set drm_device.irq_enabled to signal the DRM core that vblank interrupts are available.
Return
Zero on success or a negative error code on failure.
uninstall the IRQ handler
Parameters
Description
Calls the driver’s irq_uninstall() function and unregisters the IRQ handler. This should only be called by drivers which used drm_irq_install() to set up their interrupt handler. Other drivers must only reset drm_device.irq_enabled to false.
Note that for kernel modesetting drivers it is a bug if this function fails. The sanity checks are only to catch buggy user modesetting drivers which call the same function through an ioctl.
Return
Zero on success or a negative error code on failure.
calculate vblank timestamp constants
Parameters
Description
Calculate and store various constants which are later needed by vblank and swap-completion timestamping, e.g, by drm_calc_vbltimestamp_from_scanoutpos(). They are derived from CRTC’s true scanout timing, so they take things like panel scaling or other adjustments into account.
precise vblank timestamp helper
Parameters
Description
Implements calculation of exact vblank timestamps from given drm_display_mode timings and current video scanout position of a CRTC. This can be called from within get_vblank_timestamp() implementation of a kms driver to implement the actual timestamping.
Should return timestamps conforming to the OML_sync_control OpenML extension specification. The timestamp corresponds to the end of the vblank interval, aka start of scanout of topmost-leftmost display pixel in the following video frame.
Requires support for optional dev->driver->:c:func:get_scanout_position() in kms driver, plus a bit of setup code to provide a drm_display_mode that corresponds to the true scanout timing.
The current implementation only handles standard video modes. It returns as no operation if a doublescan or interlaced video mode is active. Higher level code is expected to handle this.
Return
Negative value on error, failure or if not supported in current video mode:
-EINVAL | Invalid CRTC. |
-EAGAIN | Temporary unavailable, e.g., called before initial modeset. |
-ENOTSUPP | Function not supported in current display mode. |
-EIO | Failed, e.g., due to failed scanout position query. |
Returns or’ed positive status flags on success:
DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval.
Parameters
Description
Fetches the “cooked” vblank count value that represents the number of vblank events since the system was booted, including lost events due to modesetting activity.
Return
The software vblank counter.
retrieve “cooked” vblank counter value and the system timestamp corresponding to that vblank counter value
Parameters
Description
Fetches the “cooked” vblank count value that represents the number of vblank events since the system was booted, including lost events due to modesetting activity. Returns corresponding system timestamp of the time of the vblank interval that corresponds to the current vblank counter value.
arm vblank event after pageflip
Parameters
Description
A lot of drivers need to generate vblank events for the very next vblank interrupt. For example when the page flip interrupt happens when the page flip gets armed, but not when it actually executes within the next vblank period. This helper function implements exactly the required vblank arming behaviour.
NOTE
Drivers using this to send out the drm_crtc_state.event as part of an atomic commit must ensure that the next vblank happens at exactly the same time as the atomic commit is committed to the hardware. This function itself does not protect again the next vblank interrupt racing with either this function call or the atomic commit operation. A possible sequence could be:
An equivalent race can happen when the driver calls drm_crtc_arm_vblank_event() before writing out the new hardware state.
The only way to make this work safely is to prevent the vblank from firing (and the hardware from committing anything else) until the entire atomic commit sequence has run to completion. If the hardware does not have such a feature (e.g. using a “go” bit), then it is unsafe to use this functions. Instead drivers need to manually send out the event from their interrupt handler by calling drm_crtc_send_vblank_event() and make sure that there’s no possible race with the hardware committing the atomic update.
Caller must hold event lock. Caller must also hold a vblank reference for the event e, which will be dropped when the next vblank arrives.
helper to send vblank event after pageflip
Parameters
Description
Updates sequence # and timestamp on event for the most recently processed vblank, and sends it to userspace. Caller must hold event lock.
See drm_crtc_arm_vblank_event() for a helper which can be used in certain situation, especially to send out events for atomic commit operations.
Parameters
Description
Acquire a reference count on vblank events to avoid having them disabled while in use.
Return
Zero on success or a negative error code on failure.
Parameters
Description
Release ownership of a given vblank counter, turning off interrupts if possible. Disable interrupts after drm_vblank_offdelay milliseconds.
wait for one vblank
Parameters
Description
This waits for one vblank to pass on pipe, using the irq driver interfaces. It is a failure to call this when the vblank irq for pipe is disabled, e.g. due to lack of driver support or because the crtc is off.
Parameters
Description
This waits for one vblank to pass on crtc, using the irq driver interfaces. It is a failure to call this when the vblank irq for crtc is disabled, e.g. due to lack of driver support or because the crtc is off.
Parameters
Description
Drivers can use this function to shut down the vblank interrupt handling when disabling a crtc. This function ensures that the latest vblank frame count is stored so that drm_vblank_on can restore it again.
Drivers must use this function when the hardware vblank counter can get reset, e.g. when suspending.
Parameters
Description
Drivers can use this function to reset the vblank state to off at load time. Drivers should use this together with the drm_crtc_vblank_off() and drm_crtc_vblank_on() functions. The difference compared to drm_crtc_vblank_off() is that this function doesn’t save the vblank counter and hence doesn’t need to call any driver hooks.
Parameters
Description
This functions restores the vblank interrupt state captured with drm_crtc_vblank_off() again. Note that calls to drm_crtc_vblank_on() and drm_crtc_vblank_off() can be unbalanced and so can also be unconditionally called in driver load code to reflect the current hardware state of the crtc.
handle a vblank event
Parameters
Description
Drivers should call this routine in their vblank interrupt handlers to update the vblank counter and send any signals that may be pending.
This is the legacy version of drm_crtc_handle_vblank().
Parameters
Description
Drivers should call this routine in their vblank interrupt handlers to update the vblank counter and send any signals that may be pending.
This is the native KMS version of drm_handle_vblank().
Return
True if the event was successfully handled, false on failure.