Mode Setting Helper Functions

The DRM subsystem aims for a strong separation between core code and helper libraries. Core code takes care of general setup and teardown and decoding userspace requests to kernel internal objects. Everything else is handled by a large set of helper libraries, which can be combined freely to pick and choose for each driver what fits, and avoid shared code where special behaviour is needed.

This distinction between core code and helpers is especially strong in the modesetting code, where there’s a shared userspace ABI for all drivers. This is in contrast to the render side, where pretty much everything (with very few exceptions) can be considered optional helper code.

There are a few areas these helpers can grouped into:

  • Helpers to implement modesetting. The important ones here are the atomic helpers. Old drivers still often use the legacy CRTC helpers. They both share the same set of common helper vtables. For really simple drivers (anything that would have been a great fit in the deprecated fbdev subsystem) there’s also the simple display pipe helpers.

  • There’s a big pile of helpers for handling outputs. First the generic bridge helpers for handling encoder and transcoder IP blocks. Second the panel helpers for handling panel-related information and logic. Plus then a big set of helpers for the various sink standards (DisplayPort, HDMI, MIPI DSI). Finally there’s also generic helpers for handling output probing, and for dealing with EDIDs.

  • The last group of helpers concerns itself with the frontend side of a display pipeline: Planes, handling rectangles for visibility checking and scissoring, flip queues and assorted bits.

Modeset Helper Reference for Common Vtables

The DRM mode setting helper functions are common code for drivers to use if they wish. Drivers are not forced to use this code in their implementations but it would be useful if the code they do use at least provides a consistent interface and operation to userspace. Therefore it is highly recommended to use the provided helpers as much as possible.

Because there is only one pointer per modeset object to hold a vfunc table for helper libraries they are by necessity shared among the different helpers.

To make this clear all the helper vtables are pulled together in this location here.

struct drm_crtc_helper_funcs

helper operations for CRTCs

Definition:

struct drm_crtc_helper_funcs {
    void (*dpms)(struct drm_crtc *crtc, int mode);
    void (*prepare)(struct drm_crtc *crtc);
    void (*commit)(struct drm_crtc *crtc);
    enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc, const struct drm_display_mode *mode);
    bool (*mode_fixup)(struct drm_crtc *crtc,const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode);
    int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode,struct drm_display_mode *adjusted_mode, int x, int y, struct drm_framebuffer *old_fb);
    void (*mode_set_nofb)(struct drm_crtc *crtc);
    int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb);
    int (*mode_set_base_atomic)(struct drm_crtc *crtc,struct drm_framebuffer *fb, int x, int y, enum mode_set_atomic);
    void (*disable)(struct drm_crtc *crtc);
    int (*atomic_check)(struct drm_crtc *crtc, struct drm_atomic_state *state);
    void (*atomic_begin)(struct drm_crtc *crtc, struct drm_atomic_state *state);
    void (*atomic_flush)(struct drm_crtc *crtc, struct drm_atomic_state *state);
    void (*atomic_enable)(struct drm_crtc *crtc, struct drm_atomic_state *state);
    void (*atomic_disable)(struct drm_crtc *crtc, struct drm_atomic_state *state);
    bool (*get_scanout_position)(struct drm_crtc *crtc,bool in_vblank_irq, int *vpos, int *hpos,ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode);
};

Members

dpms

Callback to control power levels on the CRTC. If the mode passed in is unsupported, the provider must use the next lowest power level. This is used by the legacy CRTC helpers to implement DPMS functionality in drm_helper_connector_dpms().

This callback is also used to disable a CRTC by calling it with DRM_MODE_DPMS_OFF if the disable hook isn’t used.

This callback is used by the legacy CRTC helpers. Atomic helpers also support using this hook for enabling and disabling a CRTC to facilitate transitions to atomic, but it is deprecated. Instead atomic_enable and atomic_disable should be used.

prepare

This callback should prepare the CRTC for a subsequent modeset, which in practice means the driver should disable the CRTC if it is running. Most drivers ended up implementing this by calling their dpms hook with DRM_MODE_DPMS_OFF.

This callback is used by the legacy CRTC helpers. Atomic helpers also support using this hook for disabling a CRTC to facilitate transitions to atomic, but it is deprecated. Instead atomic_disable should be used.

commit

This callback should commit the new mode on the CRTC after a modeset, which in practice means the driver should enable the CRTC. Most drivers ended up implementing this by calling their dpms hook with DRM_MODE_DPMS_ON.

This callback is used by the legacy CRTC helpers. Atomic helpers also support using this hook for enabling a CRTC to facilitate transitions to atomic, but it is deprecated. Instead atomic_enable should be used.

mode_valid

This callback is used to check if a specific mode is valid in this crtc. This should be implemented if the crtc has some sort of restriction in the modes it can display. For example, a given crtc may be responsible to set a clock value. If the clock can not produce all the values for the available modes then this callback can be used to restrict the number of modes to only the ones that can be displayed.

This hook is used by the probe helpers to filter the mode list in drm_helper_probe_single_connector_modes(), and it is used by the atomic helpers to validate modes supplied by userspace in drm_atomic_helper_check_modeset().

This function is optional.

NOTE:

Since this function is both called from the check phase of an atomic commit, and the mode validation in the probe paths it is not allowed to look at anything else but the passed-in mode, and validate it against configuration-invariant hardware constraints. Any further limits which depend upon the configuration can only be checked in mode_fixup or atomic_check.

RETURNS:

drm_mode_status Enum

mode_fixup

This callback is used to validate a mode. The parameter mode is the display mode that userspace requested, adjusted_mode is the mode the encoders need to be fed with. Note that this is the inverse semantics of the meaning for the drm_encoder and drm_bridge_funcs.mode_fixup vfunc. If the CRTC cannot support the requested conversion from mode to adjusted_mode it should reject the modeset. See also drm_crtc_state.adjusted_mode for more details.

This function is used by both legacy CRTC helpers and atomic helpers. With atomic helpers it is optional.

NOTE:

This function is called in the check 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). Atomic drivers MUST NOT touch any persistent state (hardware or software) or data structures except the passed in adjusted_mode parameter.

This is in contrast to the legacy CRTC helpers where this was allowed.

Atomic drivers which need to inspect and adjust more state should instead use the atomic_check callback, but note that they’re not perfectly equivalent: mode_valid is called from drm_atomic_helper_check_modeset(), but atomic_check is called from drm_atomic_helper_check_planes(), because originally it was meant for plane update checks only.

Also beware that userspace can request its own custom modes, neither core nor helpers filter modes to the list of probe modes reported by the GETCONNECTOR IOCTL and stored in drm_connector.modes. To ensure that modes are filtered consistently put any CRTC constraints and limits checks into mode_valid.

RETURNS:

True if an acceptable configuration is possible, false if the modeset operation should be rejected.

mode_set

This callback is used by the legacy CRTC helpers to set a new mode, position and framebuffer. Since it ties the primary plane to every mode change it is incompatible with universal plane support. And since it can’t update other planes it’s incompatible with atomic modeset support.

This callback is only used by CRTC helpers and deprecated.

RETURNS:

0 on success or a negative error code on failure.

mode_set_nofb

This callback is used to update the display mode of a CRTC without changing anything of the primary plane configuration. This fits the requirement of atomic and hence is used by the atomic helpers.

Note that the display pipe is completely off when this function is called. Atomic drivers which need hardware to be running before they program the new display mode (e.g. because they implement runtime PM) should not use this hook. This is because the helper library calls this hook only once per mode change and not every time the display pipeline is suspended using either DPMS or the new “ACTIVE” property. Which means register values set in this callback might get reset when the CRTC is suspended, but not restored. Such drivers should instead move all their CRTC setup into the atomic_enable callback.

This callback is optional.

mode_set_base

This callback is used by the legacy CRTC helpers to set a new framebuffer and scanout position. It is optional and used as an optimized fast-path instead of a full mode set operation with all the resulting flickering. If it is not present drm_crtc_helper_set_config() will fall back to a full modeset, using the mode_set callback. Since it can’t update other planes it’s incompatible with atomic modeset support.

This callback is only used by the CRTC helpers and deprecated.

RETURNS:

0 on success or a negative error code on failure.

mode_set_base_atomic

This callback is used by the fbdev helpers to set a new framebuffer and scanout without sleeping, i.e. from an atomic calling context. It is only used to implement kgdb support.

This callback is optional and only needed for kgdb support in the fbdev helpers.

RETURNS:

0 on success or a negative error code on failure.

disable

This callback should be used to disable the CRTC. With the atomic drivers it is called after all encoders connected to this CRTC have been shut off already using their own drm_encoder_helper_funcs.disable hook. If that sequence is too simple drivers can just add their own hooks and call it from this CRTC callback here by looping over all encoders connected to it using for_each_encoder_on_crtc().

This hook is used both by legacy CRTC helpers and atomic helpers. Atomic drivers don’t need to implement it if there’s no need to disable anything at the CRTC level. To ensure that runtime PM handling (using either DPMS or the new “ACTIVE” property) works disable must be the inverse of atomic_enable for atomic drivers. Atomic drivers should consider to use atomic_disable instead of this one.

NOTE:

With legacy CRTC helpers there’s a big semantic difference between disable and other hooks (like prepare or dpms) used to shut down a CRTC: disable is only called when also logically disabling the display pipeline and needs to release any resources acquired in mode_set (like shared PLLs, or again release pinned framebuffers).

Therefore disable must be the inverse of mode_set plus commit for drivers still using legacy CRTC helpers, which is different from the rules under atomic.

atomic_check

Drivers should check plane-update related CRTC constraints in this hook. They can also check mode related limitations but need to be aware of the calling order, since this hook is used by drm_atomic_helper_check_planes() whereas the preparations needed to check output routing and the display mode is done in drm_atomic_helper_check_modeset(). Therefore drivers that want to check output routing and display mode constraints in this callback must ensure that drm_atomic_helper_check_modeset() has been called beforehand. This is calling order used by the default helper implementation in drm_atomic_helper_check().

When using drm_atomic_helper_check_planes() this hook is called after the drm_plane_helper_funcs.atomic_check hook for planes, which allows drivers to assign shared resources requested by planes in this callback here. For more complicated dependencies the driver can call the provided check helpers multiple times until the computed state has a final configuration and everything has been checked.

This function is also allowed to inspect any other object’s state and can add more state objects to the atomic commit if needed. Care must be taken though to ensure that state check and compute functions for these added states are all called, and derived state in other objects all updated. Again the recommendation is to just call check helpers until a maximal configuration is reached.

This callback is used by the atomic modeset helpers, but it is optional.

NOTE:

This function is called in the check phase of an atomic update. The driver is not allowed to change anything outside of the free-standing state object passed-in.

Also beware that userspace can request its own custom modes, neither core nor helpers filter modes to the list of probe modes reported by the GETCONNECTOR IOCTL and stored in drm_connector.modes. To ensure that modes are filtered consistently put any CRTC constraints and limits checks into mode_valid.

RETURNS:

0 on success, -EINVAL if the state or the transition can’t be supported, -ENOMEM on memory allocation failure and -EDEADLK if an attempt to obtain another state object ran into a drm_modeset_lock deadlock.

atomic_begin

Drivers should prepare for an atomic update of multiple planes on a CRTC in this hook. Depending upon hardware this might be vblank evasion, blocking updates by setting bits or doing preparatory work for e.g. manual update display.

This hook is called before any plane commit functions are called.

Note that the power state of the display pipe when this function is called depends upon the exact helpers and calling sequence the driver has picked. See drm_atomic_helper_commit_planes() for a discussion of the tradeoffs and variants of plane commit helpers.

This callback is used by the atomic modeset helpers, but it is optional.

atomic_flush

Drivers should finalize an atomic update of multiple planes on a CRTC in this hook. Depending upon hardware this might include checking that vblank evasion was successful, unblocking updates by setting bits or setting the GO bit to flush out all updates.

Simple hardware or hardware with special requirements can commit and flush out all updates for all planes from this hook and forgo all the other commit hooks for plane updates.

This hook is called after any plane commit functions are called.

Note that the power state of the display pipe when this function is called depends upon the exact helpers and calling sequence the driver has picked. See drm_atomic_helper_commit_planes() for a discussion of the tradeoffs and variants of plane commit helpers.

This callback is used by the atomic modeset helpers, but it is optional.

atomic_enable

This callback should be used to enable the CRTC. With the atomic drivers it is called before all encoders connected to this CRTC are enabled through the encoder’s own drm_encoder_helper_funcs.enable hook. If that sequence is too simple drivers can just add their own hooks and call it from this CRTC callback here by looping over all encoders connected to it using for_each_encoder_on_crtc().

This hook is used only by atomic helpers, for symmetry with atomic_disable. Atomic drivers don’t need to implement it if there’s no need to enable anything at the CRTC level. To ensure that runtime PM handling (using either DPMS or the new “ACTIVE” property) works atomic_enable must be the inverse of atomic_disable for atomic drivers.

This function is optional.

atomic_disable

This callback should be used to disable the CRTC. With the atomic drivers it is called after all encoders connected to this CRTC have been shut off already using their own drm_encoder_helper_funcs.disable hook. If that sequence is too simple drivers can just add their own hooks and call it from this CRTC callback here by looping over all encoders connected to it using for_each_encoder_on_crtc().

This hook is used only by atomic helpers. Atomic drivers don’t need to implement it if there’s no need to disable anything at the CRTC level.

This function is optional.

get_scanout_position

Called by vblank timestamping code.

Returns the current display scanout position from a CRTC and an optional accurate ktime_get() timestamp of when the position was measured. Note that this is a helper callback which is only used if a driver uses drm_crtc_vblank_helper_get_vblank_timestamp() for the drm_crtc_funcs.get_vblank_timestamp callback.

Parameters:

crtc:

The CRTC.

in_vblank_irq:

True when called from drm_crtc_handle_vblank(). Some drivers need to apply some workarounds for gpu-specific vblank irq quirks if the flag is set.

vpos:

Target location for current vertical scanout position.

hpos:

Target location for current horizontal scanout position.

stime:

Target location for timestamp taken immediately before scanout position query. Can be NULL to skip timestamp.

etime:

Target location for timestamp taken immediately after scanout position query. Can be NULL to skip timestamp.

mode:

Current display timings.

Returns vpos as a positive number while in active scanout area. Returns vpos as a negative number inside vblank, counting the number of scanlines to go until end of vblank, e.g., -1 means “one scanline until start of active scanout / end of vblank.”

Returns:

True on success, false if a reliable scanout position counter could not be read out.

Description

These hooks are used by the legacy CRTC helpers and the new atomic modesetting helpers.

void drm_crtc_helper_add(struct drm_crtc *crtc, const struct drm_crtc_helper_funcs *funcs)

sets the helper vtable for a crtc

Parameters

struct drm_crtc *crtc

DRM CRTC

const struct drm_crtc_helper_funcs *funcs

helper vtable to set for crtc

struct drm_encoder_helper_funcs

helper operations for encoders

Definition:

struct drm_encoder_helper_funcs {
    void (*dpms)(struct drm_encoder *encoder, int mode);
    enum drm_mode_status (*mode_valid)(struct drm_encoder *crtc, const struct drm_display_mode *mode);
    bool (*mode_fixup)(struct drm_encoder *encoder,const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode);
    void (*prepare)(struct drm_encoder *encoder);
    void (*commit)(struct drm_encoder *encoder);
    void (*mode_set)(struct drm_encoder *encoder,struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode);
    void (*atomic_mode_set)(struct drm_encoder *encoder,struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state);
    enum drm_connector_status (*detect)(struct drm_encoder *encoder, struct drm_connector *connector);
    void (*atomic_disable)(struct drm_encoder *encoder, struct drm_atomic_state *state);
    void (*atomic_enable)(struct drm_encoder *encoder, struct drm_atomic_state *state);
    void (*disable)(struct drm_encoder *encoder);
    void (*enable)(struct drm_encoder *encoder);
    int (*atomic_check)(struct drm_encoder *encoder,struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state);
};

Members

dpms

Callback to control power levels on the encoder. If the mode passed in is unsupported, the provider must use the next lowest power level. This is used by the legacy encoder helpers to implement DPMS functionality in drm_helper_connector_dpms().

This callback is also used to disable an encoder by calling it with DRM_MODE_DPMS_OFF if the disable hook isn’t used.

This callback is used by the legacy CRTC helpers. Atomic helpers also support using this hook for enabling and disabling an encoder to facilitate transitions to atomic, but it is deprecated. Instead enable and disable should be used.

mode_valid

This callback is used to check if a specific mode is valid in this encoder. This should be implemented if the encoder has some sort of restriction in the modes it can display. For example, a given encoder may be responsible to set a clock value. If the clock can not produce all the values for the available modes then this callback can be used to restrict the number of modes to only the ones that can be displayed.

This hook is used by the probe helpers to filter the mode list in drm_helper_probe_single_connector_modes(), and it is used by the atomic helpers to validate modes supplied by userspace in drm_atomic_helper_check_modeset().

This function is optional.

NOTE:

Since this function is both called from the check phase of an atomic commit, and the mode validation in the probe paths it is not allowed to look at anything else but the passed-in mode, and validate it against configuration-invariant hardware constraints. Any further limits which depend upon the configuration can only be checked in mode_fixup or atomic_check.

RETURNS:

drm_mode_status Enum

mode_fixup

This callback is used to validate and adjust a mode. The parameter mode is the display mode that should be fed to the next element in the display chain, either the final drm_connector or a drm_bridge. The parameter adjusted_mode is the input mode the encoder requires. It can be modified by this callback and does not need to match mode. See also drm_crtc_state.adjusted_mode for more details.

This function is used by both legacy CRTC helpers and atomic helpers. This hook is optional.

NOTE:

This function is called in the check 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). Atomic drivers MUST NOT touch any persistent state (hardware or software) or data structures except the passed in adjusted_mode parameter.

This is in contrast to the legacy CRTC helpers where this was allowed.

Atomic drivers which need to inspect and adjust more state should instead use the atomic_check callback. If atomic_check is used, this hook isn’t called since atomic_check allows a strict superset of the functionality of mode_fixup.

Also beware that userspace can request its own custom modes, neither core nor helpers filter modes to the list of probe modes reported by the GETCONNECTOR IOCTL and stored in drm_connector.modes. To ensure that modes are filtered consistently put any encoder constraints and limits checks into mode_valid.

RETURNS:

True if an acceptable configuration is possible, false if the modeset operation should be rejected.

prepare

This callback should prepare the encoder for a subsequent modeset, which in practice means the driver should disable the encoder if it is running. Most drivers ended up implementing this by calling their dpms hook with DRM_MODE_DPMS_OFF.

This callback is used by the legacy CRTC helpers. Atomic helpers also support using this hook for disabling an encoder to facilitate transitions to atomic, but it is deprecated. Instead disable should be used.

commit

This callback should commit the new mode on the encoder after a modeset, which in practice means the driver should enable the encoder. Most drivers ended up implementing this by calling their dpms hook with DRM_MODE_DPMS_ON.

This callback is used by the legacy CRTC helpers. Atomic helpers also support using this hook for enabling an encoder to facilitate transitions to atomic, but it is deprecated. Instead enable should be used.

mode_set

This callback is used to update the display mode of an encoder.

Note that the display pipe is completely off when this function is called. Drivers which need hardware to be running before they program the new display mode (because they implement runtime PM) should not use this hook, because the helper library calls it only once and not every time the display pipeline is suspend using either DPMS or the new “ACTIVE” property. Such drivers should instead move all their encoder setup into the enable callback.

This callback is used both by the legacy CRTC helpers and the atomic modeset helpers. It is optional in the atomic helpers.

NOTE:

If the driver uses the atomic modeset helpers and needs to inspect the connector state or connector display info during mode setting, atomic_mode_set can be used instead.

atomic_mode_set

This callback is used to update the display mode of an encoder.

Note that the display pipe is completely off when this function is called. Drivers which need hardware to be running before they program the new display mode (because they implement runtime PM) should not use this hook, because the helper library calls it only once and not every time the display pipeline is suspended using either DPMS or the new “ACTIVE” property. Such drivers should instead move all their encoder setup into the enable callback.

This callback is used by the atomic modeset helpers in place of the mode_set callback, if set by the driver. It is optional and should be used instead of mode_set if the driver needs to inspect the connector state or display info, since there is no direct way to go from the encoder to the current connector.

detect

This callback can be used by drivers who want to do detection on the encoder object instead of in connector functions.

It is not used by any helper and therefore has purely driver-specific semantics. New drivers shouldn’t use this and instead just implement their own private callbacks.

FIXME:

This should just be converted into a pile of driver vfuncs. Currently radeon, amdgpu and nouveau are using it.

atomic_disable

This callback should be used to disable the encoder. With the atomic drivers it is called before this encoder’s CRTC has been shut off using their own drm_crtc_helper_funcs.atomic_disable hook. If that sequence is too simple drivers can just add their own driver private encoder hooks and call them from CRTC’s callback by looping over all encoders connected to it using for_each_encoder_on_crtc().

This callback is a variant of disable that provides the atomic state to the driver. If atomic_disable is implemented, disable is not called by the helpers.

This hook is only used by atomic helpers. Atomic drivers don’t need to implement it if there’s no need to disable anything at the encoder level. To ensure that runtime PM handling (using either DPMS or the new “ACTIVE” property) works atomic_disable must be the inverse of atomic_enable.

atomic_enable

This callback should be used to enable the encoder. It is called after this encoder’s CRTC has been enabled using their own drm_crtc_helper_funcs.atomic_enable hook. If that sequence is too simple drivers can just add their own driver private encoder hooks and call them from CRTC’s callback by looping over all encoders connected to it using for_each_encoder_on_crtc().

This callback is a variant of enable that provides the atomic state to the driver. If atomic_enable is implemented, enable is not called by the helpers.

This hook is only used by atomic helpers, it is the opposite of atomic_disable. Atomic drivers don’t need to implement it if there’s no need to enable anything at the encoder level. To ensure that runtime PM handling works atomic_enable must be the inverse of atomic_disable.

disable

This callback should be used to disable the encoder. With the atomic drivers it is called before this encoder’s CRTC has been shut off using their own drm_crtc_helper_funcs.disable hook. If that sequence is too simple drivers can just add their own driver private encoder hooks and call them from CRTC’s callback by looping over all encoders connected to it using for_each_encoder_on_crtc().

This hook is used both by legacy CRTC helpers and atomic helpers. Atomic drivers don’t need to implement it if there’s no need to disable anything at the encoder level. To ensure that runtime PM handling (using either DPMS or the new “ACTIVE” property) works disable must be the inverse of enable for atomic drivers.

For atomic drivers also consider atomic_disable and save yourself from having to read the NOTE below!

NOTE:

With legacy CRTC helpers there’s a big semantic difference between disable and other hooks (like prepare or dpms) used to shut down a encoder: disable is only called when also logically disabling the display pipeline and needs to release any resources acquired in mode_set (like shared PLLs, or again release pinned framebuffers).

Therefore disable must be the inverse of mode_set plus commit for drivers still using legacy CRTC helpers, which is different from the rules under atomic.

enable

This callback should be used to enable the encoder. With the atomic drivers it is called after this encoder’s CRTC has been enabled using their own drm_crtc_helper_funcs.enable hook. If that sequence is too simple drivers can just add their own driver private encoder hooks and call them from CRTC’s callback by looping over all encoders connected to it using for_each_encoder_on_crtc().

This hook is only used by atomic helpers, it is the opposite of disable. Atomic drivers don’t need to implement it if there’s no need to enable anything at the encoder level. To ensure that runtime PM handling (using either DPMS or the new “ACTIVE” property) works enable must be the inverse of disable for atomic drivers.

atomic_check

This callback is used to validate encoder state for atomic drivers. Since the encoder is the object connecting the CRTC and connector it gets passed both states, to be able to validate interactions and update the CRTC to match what the encoder needs for the requested connector.

Since this provides a strict superset of the functionality of mode_fixup (the requested and adjusted modes are both available through the passed in struct drm_crtc_state) mode_fixup is not called when atomic_check is implemented.

This function is used by the atomic helpers, but it is optional.

NOTE:

This function is called in the check phase of an atomic update. The driver is not allowed to change anything outside of the free-standing state objects passed-in or assembled in the overall drm_atomic_state update tracking structure.

Also beware that userspace can request its own custom modes, neither core nor helpers filter modes to the list of probe modes reported by the GETCONNECTOR IOCTL and stored in drm_connector.modes. To ensure that modes are filtered consistently put any encoder constraints and limits checks into mode_valid.

RETURNS:

0 on success, -EINVAL if the state or the transition can’t be supported, -ENOMEM on memory allocation failure and -EDEADLK if an attempt to obtain another state object ran into a drm_modeset_lock deadlock.

Description

These hooks are used by the legacy CRTC helpers and the new atomic modesetting helpers.

void drm_encoder_helper_add(struct drm_encoder *encoder, const struct drm_encoder_helper_funcs *funcs)

sets the helper vtable for an encoder

Parameters

struct drm_encoder *encoder

DRM encoder

const struct drm_encoder_helper_funcs *funcs

helper vtable to set for encoder

struct drm_connector_helper_funcs

helper operations for connectors

Definition:

struct drm_connector_helper_funcs {
    int (*get_modes)(struct drm_connector *connector);
    int (*detect_ctx)(struct drm_connector *connector,struct drm_modeset_acquire_ctx *ctx, bool force);
    enum drm_mode_status (*mode_valid)(struct drm_connector *connector, struct drm_display_mode *mode);
    int (*mode_valid_ctx)(struct drm_connector *connector,struct drm_display_mode *mode,struct drm_modeset_acquire_ctx *ctx, enum drm_mode_status *status);
    struct drm_encoder *(*best_encoder)(struct drm_connector *connector);
    struct drm_encoder *(*atomic_best_encoder)(struct drm_connector *connector, struct drm_atomic_state *state);
    int (*atomic_check)(struct drm_connector *connector, struct drm_atomic_state *state);
    void (*atomic_commit)(struct drm_connector *connector, struct drm_atomic_state *state);
    int (*prepare_writeback_job)(struct drm_writeback_connector *connector, struct drm_writeback_job *job);
    void (*cleanup_writeback_job)(struct drm_writeback_connector *connector, struct drm_writeback_job *job);
    void (*enable_hpd)(struct drm_connector *connector);
    void (*disable_hpd)(struct drm_connector *connector);
};

Members

get_modes

This function should fill in all modes currently valid for the sink into the drm_connector.probed_modes list. It should also update the EDID property by calling drm_connector_update_edid_property().

The usual way to implement this is to cache the EDID retrieved in the probe callback somewhere in the driver-private connector structure. In this function drivers then parse the modes in the EDID and add them by calling drm_add_edid_modes(). But connectors that drive a fixed panel can also manually add specific modes using drm_mode_probed_add(). Drivers which manually add modes should also make sure that the drm_connector.display_info, drm_connector.width_mm and drm_connector.height_mm fields are filled in.

Note that the caller function will automatically add standard VESA DMT modes up to 1024x768 if the .get_modes() helper operation returns no mode and if the connector status is connector_status_connected or connector_status_unknown. There is no need to call drm_add_modes_noedid() manually in that case.

Virtual drivers that just want some standard VESA mode with a given resolution can call drm_add_modes_noedid(), and mark the preferred one using drm_set_preferred_mode().

This function is only called after the detect hook has indicated that a sink is connected and when the EDID isn’t overridden through sysfs or the kernel commandline.

This callback is used by the probe helpers in e.g. drm_helper_probe_single_connector_modes().

To avoid races with concurrent connector state updates, the helper libraries always call this with the drm_mode_config.connection_mutex held. Because of this it’s safe to inspect drm_connector->state.

RETURNS:

The number of modes added by calling drm_mode_probed_add(). Return 0 on failures (no modes) instead of negative error codes.

detect_ctx

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.

This is the atomic version of drm_connector_funcs.detect.

To avoid races against concurrent connector state updates, the helper libraries always call this with ctx set to a valid context, and drm_mode_config.connection_mutex will always be locked with the ctx parameter set to this ctx. This allows taking additional locks as required.

RETURNS:

drm_connector_status indicating the connector’s status, or the error code returned by drm_modeset_lock(), -EDEADLK.

mode_valid

Callback to validate a mode for a connector, irrespective of the specific display configuration.

This callback is used by the probe helpers to filter the mode list (which is usually derived from the EDID data block from the sink). See e.g. drm_helper_probe_single_connector_modes().

This function is optional.

NOTE:

This only filters the mode list supplied to userspace in the GETCONNECTOR IOCTL. Compared to drm_encoder_helper_funcs.mode_valid, drm_crtc_helper_funcs.mode_valid and drm_bridge_funcs.mode_valid, which are also called by the atomic helpers from drm_atomic_helper_check_modeset(). This allows userspace to force and ignore sink constraint (like the pixel clock limits in the screen’s EDID), which is useful for e.g. testing, or working around a broken EDID. Any source hardware constraint (which always need to be enforced) therefore should be checked in one of the above callbacks, and not this one here.

To avoid races with concurrent connector state updates, the helper libraries always call this with the drm_mode_config.connection_mutex held. Because of this it’s safe to inspect drm_connector->state.

RETURNS:

Either drm_mode_status.MODE_OK or one of the failure reasons in enum drm_mode_status.

mode_valid_ctx

Callback to validate a mode for a connector, irrespective of the specific display configuration.

This callback is used by the probe helpers to filter the mode list (which is usually derived from the EDID data block from the sink). See e.g. drm_helper_probe_single_connector_modes().

This function is optional, and is the atomic version of drm_connector_helper_funcs.mode_valid.

To allow for accessing the atomic state of modesetting objects, the helper libraries always call this with ctx set to a valid context, and drm_mode_config.connection_mutex will always be locked with the ctx parameter set to ctx. This allows for taking additional locks as required.

Even though additional locks may be acquired, this callback is still expected not to take any constraints into account which would be influenced by the currently set display state - such constraints should be handled in the driver’s atomic check. For example, if a connector shares display bandwidth with other connectors then it would be ok to validate the minimum bandwidth requirement of a mode against the maximum possible bandwidth of the connector. But it wouldn’t be ok to take the current bandwidth usage of other connectors into account, as this would change depending on the display state.

Returns: 0 if drm_connector_helper_funcs.mode_valid_ctx succeeded and wrote the enum drm_mode_status value to status, or a negative error code otherwise.

best_encoder

This function should select the best encoder for the given connector.

This function is used by both the atomic helpers (in the drm_atomic_helper_check_modeset() function) and in the legacy CRTC helpers.

NOTE:

In atomic drivers this function is called in the check phase of an atomic update. The driver is not allowed to change or inspect anything outside of arguments passed-in. Atomic drivers which need to inspect dynamic configuration state should instead use atomic_best_encoder.

You can leave this function to NULL if the connector is only attached to a single encoder. In this case, the core will call drm_connector_get_single_encoder() for you.

RETURNS:

Encoder that should be used for the given connector and connector state, or NULL if no suitable encoder exists. Note that the helpers will ensure that encoders aren’t used twice, drivers should not check for this.

atomic_best_encoder

This is the atomic version of best_encoder for atomic drivers which need to select the best encoder depending upon the desired configuration and can’t select it statically.

This function is used by drm_atomic_helper_check_modeset(). If it is not implemented, the core will fallback to best_encoder (or drm_connector_get_single_encoder() if best_encoder is NULL).

NOTE:

This function is called in the check phase of an atomic update. The driver is not allowed to change anything outside of the drm_atomic_state update tracking structure passed in.

RETURNS:

Encoder that should be used for the given connector and connector state, or NULL if no suitable encoder exists. Note that the helpers will ensure that encoders aren’t used twice, drivers should not check for this.

atomic_check

This hook is used to validate connector state. This function is called from drm_atomic_helper_check_modeset, and is called when a connector property is set, or a modeset on the crtc is forced.

Because drm_atomic_helper_check_modeset may be called multiple times, this function should handle being called multiple times as well.

This function is also allowed to inspect any other object’s state and can add more state objects to the atomic commit if needed. Care must be taken though to ensure that state check and compute functions for these added states are all called, and derived state in other objects all updated. Again the recommendation is to just call check helpers until a maximal configuration is reached.

NOTE:

This function is called in the check phase of an atomic update. The driver is not allowed to change anything outside of the free-standing state objects passed-in or assembled in the overall drm_atomic_state update tracking structure.

RETURNS:

0 on success, -EINVAL if the state or the transition can’t be supported, -ENOMEM on memory allocation failure and -EDEADLK if an attempt to obtain another state object ran into a drm_modeset_lock deadlock.

atomic_commit

This hook is to be used by drivers implementing writeback connectors that need a point when to commit the writeback job to the hardware. The writeback_job to commit is available in the new connector state, in drm_connector_state.writeback_job.

This hook is optional.

This callback is used by the atomic modeset helpers.

prepare_writeback_job

As writeback jobs contain a framebuffer, drivers may need to prepare and clean them up the same way they can prepare and clean up framebuffers for planes. This optional connector operation is used to support the preparation of writeback jobs. The job prepare operation is called from drm_atomic_helper_prepare_planes() for struct drm_writeback_connector connectors only.

This operation is optional.

This callback is used by the atomic modeset helpers.

cleanup_writeback_job

This optional connector operation is used to support the cleanup of writeback jobs. The job cleanup operation is called from the existing drm_writeback_cleanup_job() function, invoked both when destroying the job as part of an aborted commit, or when the job completes.

This operation is optional.

This callback is used by the atomic modeset helpers.

enable_hpd

Enable hot-plug detection for the connector.

This operation is optional.

This callback is used by the drm_kms_helper_poll_enable() helpers.

This operation does not need to perform any hpd state tracking as the DRM core handles that maintenance and ensures the calls to enable and disable hpd are balanced.

disable_hpd

Disable hot-plug detection for the connector.

This operation is optional.

This callback is used by the drm_kms_helper_poll_disable() helpers.

This operation does not need to perform any hpd state tracking as the DRM core handles that maintenance and ensures the calls to enable and disable hpd are balanced.

Description

These functions are used by the atomic and legacy modeset helpers and by the probe helpers.

void drm_connector_helper_add(struct drm_connector *connector, const struct drm_connector_helper_funcs *funcs)

sets the helper vtable for a connector

Parameters

struct drm_connector *connector

DRM connector

const struct drm_connector_helper_funcs *funcs

helper vtable to set for connector

struct drm_plane_helper_funcs

helper operations for planes

Definition:

struct drm_plane_helper_funcs {
    int (*prepare_fb)(struct drm_plane *plane, struct drm_plane_state *new_state);
    void (*cleanup_fb)(struct drm_plane *plane, struct drm_plane_state *old_state);
    int (*begin_fb_access)(struct drm_plane *plane, struct drm_plane_state *new_plane_state);
    void (*end_fb_access)(struct drm_plane *plane, struct drm_plane_state *new_plane_state);
    int (*atomic_check)(struct drm_plane *plane, struct drm_atomic_state *state);
    void (*atomic_update)(struct drm_plane *plane, struct drm_atomic_state *state);
    void (*atomic_enable)(struct drm_plane *plane, struct drm_atomic_state *state);
    void (*atomic_disable)(struct drm_plane *plane, struct drm_atomic_state *state);
    int (*atomic_async_check)(struct drm_plane *plane, struct drm_atomic_state *state);
    void (*atomic_async_update)(struct drm_plane *plane, struct drm_atomic_state *state);
    int (*get_scanout_buffer)(struct drm_plane *plane, struct drm_scanout_buffer *sb);
    void (*panic_flush)(struct drm_plane *plane);
};

Members

prepare_fb

This hook is to prepare a framebuffer for scanout by e.g. pinning its backing storage or relocating it into a contiguous block of VRAM. Other possible preparatory work includes flushing caches.

This function must not block for outstanding rendering, since it is called in the context of the atomic IOCTL even for async commits to be able to return any errors to userspace. Instead the recommended way is to fill out the drm_plane_state.fence of the passed-in drm_plane_state. If the driver doesn’t support native fences then equivalent functionality should be implemented through private members in the plane structure.

For GEM drivers who neither have a prepare_fb nor cleanup_fb hook set drm_gem_plane_helper_prepare_fb() is called automatically to implement this. Other drivers which need additional plane processing can call drm_gem_plane_helper_prepare_fb() from their prepare_fb hook.

The resources acquired in prepare_fb persist after the end of the atomic commit. Resources that can be release at the commit’s end should be acquired in begin_fb_access and released in end_fb_access. For example, a GEM buffer’s pin operation belongs into prepare_fb to keep the buffer pinned after the commit. But a vmap operation for shadow-plane helpers belongs into begin_fb_access, so that atomic helpers remove the mapping at the end of the commit.

The helpers will call cleanup_fb with matching arguments for every successful call to this hook.

This callback is used by the atomic modeset helpers, but it is optional. See begin_fb_access for preparing per-commit resources.

RETURNS:

0 on success or one of the following negative error codes allowed by the drm_mode_config_funcs.atomic_commit vfunc. When using helpers this callback is the only one which can fail an atomic commit, everything else must complete successfully.

cleanup_fb

This hook is called to clean up any resources allocated for the given framebuffer and plane configuration in prepare_fb.

This callback is used by the atomic modeset helpers, but it is optional.

begin_fb_access

This hook prepares the plane for access during an atomic commit. In contrast to prepare_fb, resources acquired in begin_fb_access, are released at the end of the atomic commit in end_fb_access.

For example, with shadow-plane helpers, the GEM buffer’s vmap operation belongs into begin_fb_access, so that the buffer’s memory will be unmapped at the end of the commit in end_fb_access. But a GEM buffer’s pin operation belongs into prepare_fb to keep the buffer pinned after the commit.

The callback is used by the atomic modeset helpers, but it is optional. See end_fb_cleanup for undoing the effects of begin_fb_access and prepare_fb for acquiring resources until the next pageflip.

Returns: 0 on success, or a negative errno code otherwise.

end_fb_access

This hook cleans up resources allocated by begin_fb_access. It it called at the end of a commit for the new plane state.

atomic_check

Drivers should check plane specific constraints in this hook.

When using drm_atomic_helper_check_planes() plane’s atomic_check hooks are called before the ones for CRTCs, which allows drivers to request shared resources that the CRTC controls here. For more complicated dependencies the driver can call the provided check helpers multiple times until the computed state has a final configuration and everything has been checked.

This function is also allowed to inspect any other object’s state and can add more state objects to the atomic commit if needed. Care must be taken though to ensure that state check and compute functions for these added states are all called, and derived state in other objects all updated. Again the recommendation is to just call check helpers until a maximal configuration is reached.

This callback is used by the atomic modeset helpers, but it is optional.

NOTE:

This function is called in the check phase of an atomic update. The driver is not allowed to change anything outside of the drm_atomic_state update tracking structure.

RETURNS:

0 on success, -EINVAL if the state or the transition can’t be supported, -ENOMEM on memory allocation failure and -EDEADLK if an attempt to obtain another state object ran into a drm_modeset_lock deadlock.

atomic_update

Drivers should use this function to update the plane state. This hook is called in-between the drm_crtc_helper_funcs.atomic_begin and drm_crtc_helper_funcs.atomic_flush callbacks.

Note that the power state of the display pipe when this function is called depends upon the exact helpers and calling sequence the driver has picked. See drm_atomic_helper_commit_planes() for a discussion of the tradeoffs and variants of plane commit helpers.

This callback is used by the atomic modeset helpers, but it is optional.

atomic_enable

Drivers should use this function to unconditionally enable a plane. This hook is called in-between the drm_crtc_helper_funcs.atomic_begin and drm_crtc_helper_funcs.atomic_flush callbacks. It is called after atomic_update, which will be called for all enabled planes. Drivers that use atomic_enable should set up a plane in atomic_update and afterwards enable the plane in atomic_enable. If a plane needs to be enabled before installing the scanout buffer, drivers can still do so in atomic_update.

Note that the power state of the display pipe when this function is called depends upon the exact helpers and calling sequence the driver has picked. See drm_atomic_helper_commit_planes() for a discussion of the tradeoffs and variants of plane commit helpers.

This callback is used by the atomic modeset helpers, but it is optional. If implemented, atomic_enable should be the inverse of atomic_disable. Drivers that don’t want to use either can still implement the complete plane update in atomic_update.

atomic_disable

Drivers should use this function to unconditionally disable a plane. This hook is called in-between the drm_crtc_helper_funcs.atomic_begin and drm_crtc_helper_funcs.atomic_flush callbacks. It is an alternative to atomic_update, which will be called for disabling planes, too, if the atomic_disable hook isn’t implemented.

This hook is also useful to disable planes in preparation of a modeset, by calling drm_atomic_helper_disable_planes_on_crtc() from the drm_crtc_helper_funcs.disable hook.

Note that the power state of the display pipe when this function is called depends upon the exact helpers and calling sequence the driver has picked. See drm_atomic_helper_commit_planes() for a discussion of the tradeoffs and variants of plane commit helpers.

This callback is used by the atomic modeset helpers, but it is optional. It’s intended to reverse the effects of atomic_enable.

atomic_async_check

Drivers should set this function pointer to check if the plane’s atomic state can be updated in a async fashion. Here async means “not vblank synchronized”.

This hook is called by drm_atomic_async_check() to establish if a given update can be committed asynchronously, that is, if it can jump ahead of the state currently queued for update.

RETURNS:

Return 0 on success and any error returned indicates that the update can not be applied in asynchronous manner.

atomic_async_update

Drivers should set this function pointer to perform asynchronous updates of planes, that is, jump ahead of the currently queued state and update the plane. Here async means “not vblank synchronized”.

This hook is called by drm_atomic_helper_async_commit().

An async update will happen on legacy cursor updates. An async update won’t happen if there is an outstanding commit modifying the same plane.

When doing async_update drivers shouldn’t replace the drm_plane_state but update the current one with the new plane configurations in the new plane_state.

Drivers should also swap the framebuffers between current plane state (drm_plane.state) and new_state. This is required since cleanup for async commits is performed on the new state, rather than old state like for traditional commits. Since we want to give up the reference on the current (old) fb instead of our brand new one, swap them in the driver during the async commit.

FIXME:
  • It only works for single plane updates

  • Async Pageflips are not supported yet

  • Some hw might still scan out the old buffer until the next vblank, however we let go of the fb references as soon as we run this hook. For now drivers must implement their own workers for deferring if needed, until a common solution is created.

get_scanout_buffer

Get the current scanout buffer, to display a message with drm_panic. The driver should do the minimum changes to provide a buffer, that can be used to display the panic screen. Currently only linear buffers are supported. Non-linear buffer support is on the TODO list. The device dev.mode_config.panic_lock is taken before calling this function, so you can safely access the plane.state It is called from a panic callback, and must follow its restrictions. Please look the documentation at drm_panic_trylock() for an in-depth discussions of what’s safe and what is not allowed. It’s a best effort mode, so it’s expected that in some complex cases the panic screen won’t be displayed. The returned drm_scanout_buffer.map must be valid if no error code is returned.

Return: 0 on success, negative errno on failure.

panic_flush

It is used by drm_panic, and is called after the panic screen is drawn to the scanout buffer. In this function, the driver can send additional commands to the hardware, to make the scanout buffer visible. It is only called if get_scanout_buffer() returned successfully, and the dev.mode_config.panic_lock is held during the entire sequence. It is called from a panic callback, and must follow its restrictions. Please look the documentation at drm_panic_trylock() for an in-depth discussions of what’s safe and what is not allowed.

Description

These functions are used by the atomic helpers.

void drm_plane_helper_add(struct drm_plane *plane, const struct drm_plane_helper_funcs *funcs)

sets the helper vtable for a plane

Parameters

struct drm_plane *plane

DRM plane

const struct drm_plane_helper_funcs *funcs

helper vtable to set for plane

struct drm_mode_config_helper_funcs

global modeset helper operations

Definition:

struct drm_mode_config_helper_funcs {
    void (*atomic_commit_tail)(struct drm_atomic_state *state);
    int (*atomic_commit_setup)(struct drm_atomic_state *state);
};

Members

atomic_commit_tail

This hook is used by the default atomic_commit() hook implemented in drm_atomic_helper_commit() together with the nonblocking commit helpers (see drm_atomic_helper_setup_commit() for a starting point) to implement blocking and nonblocking commits easily. It is not used by the atomic helpers

This function is called when the new atomic state has already been swapped into the various state pointers. The passed in state therefore contains copies of the old/previous state. This hook should commit the new state into hardware. Note that the helpers have already waited for preceding atomic commits and fences, but drivers can add more waiting calls at the start of their implementation, e.g. to wait for driver-internal request for implicit syncing, before starting to commit the update to the hardware.

After the atomic update is committed to the hardware this hook needs to call drm_atomic_helper_commit_hw_done(). Then wait for the update to be executed by the hardware, for example using drm_atomic_helper_wait_for_vblanks() or drm_atomic_helper_wait_for_flip_done(), and then clean up the old framebuffers using drm_atomic_helper_cleanup_planes().

When disabling a CRTC this hook _must_ stall for the commit to complete. Vblank waits don’t work on disabled CRTC, hence the core can’t take care of this. And it also can’t rely on the vblank event, since that can be signalled already when the screen shows black, which can happen much earlier than the last hardware access needed to shut off the display pipeline completely.

This hook is optional, the default implementation is drm_atomic_helper_commit_tail().

atomic_commit_setup

This hook is used by the default atomic_commit() hook implemented in drm_atomic_helper_commit() together with the nonblocking helpers (see drm_atomic_helper_setup_commit()) to extend the DRM commit setup. It is not used by the atomic helpers.

This function is called at the end of drm_atomic_helper_setup_commit(), so once the commit has been properly setup across the generic DRM object states. It allows drivers to do some additional commit tracking that isn’t related to a CRTC, plane or connector, tracked in a drm_private_obj structure.

Note that the documentation of drm_private_obj has more details on how one should implement this.

This hook is optional.

Description

These helper functions are used by the atomic helpers.

Atomic Modeset Helper Functions Reference

Overview

This helper library provides implementations of check and commit functions on top of the CRTC modeset helper callbacks and the plane helper callbacks. It also provides convenience implementations for the atomic state handling callbacks for drivers which don’t need to subclass the drm core structures to add their own additional internal state.

This library also provides default implementations for the check callback in drm_atomic_helper_check() and for the commit callback with drm_atomic_helper_commit(). But the individual stages and callbacks are exposed to allow drivers to mix and match and e.g. use the plane helpers only together with a driver private modeset implementation.

This library also provides implementations for all the legacy driver interfaces on top of the atomic interface. See drm_atomic_helper_set_config(), drm_atomic_helper_disable_plane(), and the various functions to implement set_property callbacks. New drivers must not implement these functions themselves but must use the provided helpers.

The atomic helper uses the same function table structures as all other modesetting helpers. See the documentation for struct drm_crtc_helper_funcs, struct drm_encoder_helper_funcs and struct drm_connector_helper_funcs. It also shares the struct drm_plane_helper_funcs function table with the plane helpers.

Implementing Asynchronous Atomic Commit

Nonblocking atomic commits should use struct drm_crtc_commit to sequence different operations against each another. Locks, especially struct drm_modeset_lock, should not be held in worker threads or any other asynchronous context used to commit the hardware state.

drm_atomic_helper_commit() implements the recommended sequence for nonblocking commits, using drm_atomic_helper_setup_commit() internally:

1. Run drm_atomic_helper_prepare_planes(). Since this can fail and we need to propagate out of memory/VRAM errors to userspace, it must be called synchronously.

2. Synchronize with any outstanding nonblocking commit worker threads which might be affected by the new state update. This is handled by drm_atomic_helper_setup_commit().

Asynchronous workers need to have sufficient parallelism to be able to run different atomic commits on different CRTCs in parallel. The simplest way to achieve this is by running them on the system_unbound_wq work queue. Note that drivers are not required to split up atomic commits and run an individual commit in parallel - userspace is supposed to do that if it cares. But it might be beneficial to do that for modesets, since those necessarily must be done as one global operation, and enabling or disabling a CRTC can take a long time. But even that is not required.

IMPORTANT: A drm_atomic_state update for multiple CRTCs is sequenced against all CRTCs therein. Therefore for atomic state updates which only flip planes the driver must not get the struct drm_crtc_state of unrelated CRTCs in its atomic check code: This would prevent committing of atomic updates to multiple CRTCs in parallel. In general, adding additional state structures should be avoided as much as possible, because this reduces parallelism in (nonblocking) commits, both due to locking and due to commit sequencing requirements.

3. The software state is updated synchronously with drm_atomic_helper_swap_state(). Doing this under the protection of all modeset locks means concurrent callers never see inconsistent state. Note that commit workers do not hold any locks; their access is only coordinated through ordering. If workers would access state only through the pointers in the free-standing state objects (currently not the case for any driver) then even multiple pending commits could be in-flight at the same time.

4. Schedule a work item to do all subsequent steps, using the split-out commit helpers: a) pre-plane commit b) plane commit c) post-plane commit and then cleaning up the framebuffers after the old framebuffer is no longer being displayed. The scheduled work should synchronize against other workers using the drm_crtc_commit infrastructure as needed. See drm_atomic_helper_setup_commit() for more details.

Helper Functions Reference

drm_atomic_crtc_for_each_plane

drm_atomic_crtc_for_each_plane (plane, crtc)

iterate over planes currently attached to CRTC

Parameters

plane

the loop cursor

crtc

the CRTC whose planes are iterated

Description

This iterates over the current state, useful (for example) when applying atomic state after it has been checked and swapped. To iterate over the planes which will be attached (more useful in code called from drm_mode_config_funcs.atomic_check) see drm_atomic_crtc_state_for_each_plane().

drm_atomic_crtc_state_for_each_plane

drm_atomic_crtc_state_for_each_plane (plane, crtc_state)

iterate over attached planes in new state

Parameters

plane

the loop cursor

crtc_state

the incoming CRTC state

Description

Similar to drm_crtc_for_each_plane(), but iterates the planes that will be attached if the specified state is applied. Useful during for example in code called from drm_mode_config_funcs.atomic_check operations, to validate the incoming state.

drm_atomic_crtc_state_for_each_plane_state

drm_atomic_crtc_state_for_each_plane_state (plane, plane_state, crtc_state)

iterate over attached planes in new state

Parameters

plane

the loop cursor

plane_state

loop cursor for the plane’s state, must be const

crtc_state

the incoming CRTC state

Description

Similar to drm_crtc_for_each_plane(), but iterates the planes that will be attached if the specified state is applied. Useful during for example in code called from drm_mode_config_funcs.atomic_check operations, to validate the incoming state.

Compared to just drm_atomic_crtc_state_for_each_plane() this also fills in a const plane_state. This is useful when a driver just wants to peek at other active planes on this CRTC, but does not need to change it.

bool drm_atomic_plane_enabling(struct drm_plane_state *old_plane_state, struct drm_plane_state *new_plane_state)

check whether a plane is being enabled

Parameters

struct drm_plane_state *old_plane_state

old atomic plane state

struct drm_plane_state *new_plane_state

new atomic plane state

Description

Checks the atomic state of a plane to determine whether it’s being enabled or not. This also WARNs if it detects an invalid state (both CRTC and FB need to either both be NULL or both be non-NULL).

Return

True if the plane is being enabled, false otherwise.

bool drm_atomic_plane_disabling(struct drm_plane_state *old_plane_state, struct drm_plane_state *new_plane_state)

check whether a plane is being disabled

Parameters

struct drm_plane_state *old_plane_state

old atomic plane state

struct drm_plane_state *new_plane_state

new atomic plane state

Description

Checks the atomic state of a plane to determine whether it’s being disabled or not. This also WARNs if it detects an invalid state (both CRTC and FB need to either both be NULL or both be non-NULL).

Return

True if the plane is being disabled, false otherwise.

int drm_atomic_helper_check_modeset(struct drm_device *dev, struct drm_atomic_state *state)

validate state object for modeset changes

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *state

the driver state object

Description

Check the state object to see if the requested state is physically possible. This does all the CRTC and connector related computations for an atomic update and adds any additional connectors needed for full modesets. It calls the various per-object callbacks in the follow order:

  1. drm_connector_helper_funcs.atomic_best_encoder for determining the new encoder.

  2. drm_connector_helper_funcs.atomic_check to validate the connector state.

  3. If it’s determined a modeset is needed then all connectors on the affected CRTC are added and drm_connector_helper_funcs.atomic_check is run on them.

  4. drm_encoder_helper_funcs.mode_valid, drm_bridge_funcs.mode_valid and drm_crtc_helper_funcs.mode_valid are called on the affected components.

  5. drm_bridge_funcs.mode_fixup is called on all encoder bridges.

  6. drm_encoder_helper_funcs.atomic_check is called to validate any encoder state. This function is only called when the encoder will be part of a configured CRTC, it must not be used for implementing connector property validation. If this function is NULL, drm_atomic_encoder_helper_funcs.mode_fixup is called instead.

  7. drm_crtc_helper_funcs.mode_fixup is called last, to fix up the mode with CRTC constraints.

drm_crtc_state.mode_changed is set when the input mode is changed. drm_crtc_state.connectors_changed is set when a connector is added or removed from the CRTC. drm_crtc_state.active_changed is set when drm_crtc_state.active changes, which is used for DPMS. drm_crtc_state.no_vblank is set from the result of drm_dev_has_vblank(). See also: drm_atomic_crtc_needs_modeset()

IMPORTANT:

Drivers which set drm_crtc_state.mode_changed (e.g. in their drm_plane_helper_funcs.atomic_check hooks if a plane update can’t be done without a full modeset) _must_ call this function after that change. It is permitted to call this function multiple times for the same update, e.g. when the drm_crtc_helper_funcs.atomic_check functions depend upon the adjusted dotclock for fifo space allocation and watermark computation.

Return

Zero for success or -errno

int drm_atomic_helper_check_wb_connector_state(struct drm_connector *connector, struct drm_atomic_state *state)

Check writeback connector state

Parameters

struct drm_connector *connector

corresponding connector

struct drm_atomic_state *state

the driver state object

Description

Checks if the writeback connector state is valid, and returns an error if it isn’t.

Return

Zero for success or -errno

int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, const struct drm_crtc_state *crtc_state, int min_scale, int max_scale, bool can_position, bool can_update_disabled)

Check plane state for validity

Parameters

struct drm_plane_state *plane_state

plane state to check

const struct drm_crtc_state *crtc_state

CRTC state to check

int min_scale

minimum src:dest scaling factor in 16.16 fixed point

int max_scale

maximum src:dest scaling factor in 16.16 fixed point

bool can_position

is it legal to position the plane such that it doesn’t cover the entire CRTC? This will generally only be false for primary planes.

bool can_update_disabled

can the plane be updated while the CRTC is disabled?

Description

Checks that a desired plane update is valid, and updates various bits of derived state (clipped coordinates etc.). Drivers that provide their own plane handling rather than helper-provided implementations may still wish to call this function to avoid duplication of error checking code.

Return

Zero if update appears valid, error code on failure

int drm_atomic_helper_check_crtc_primary_plane(struct drm_crtc_state *crtc_state)

Check CRTC state for primary plane

Parameters

struct drm_crtc_state *crtc_state

CRTC state to check

Description

Checks that a CRTC has at least one primary plane attached to it, which is a requirement on some hardware. Note that this only involves the CRTC side of the test. To test if the primary plane is visible or if it can be updated without the CRTC being enabled, use drm_atomic_helper_check_plane_state() in the plane’s atomic check.

Return

0 if a primary plane is attached to the CRTC, or an error code otherwise

int drm_atomic_helper_check_planes(struct drm_device *dev, struct drm_atomic_state *state)

validate state object for planes changes

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *state

the driver state object

Description

Check the state object to see if the requested state is physically possible. This does all the plane update related checks using by calling into the drm_crtc_helper_funcs.atomic_check and drm_plane_helper_funcs.atomic_check hooks provided by the driver.

It also sets drm_crtc_state.planes_changed to indicate that a CRTC has updated planes.

Return

Zero for success or -errno

int drm_atomic_helper_check(struct drm_device *dev, struct drm_atomic_state *state)

validate state object

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *state

the driver state object

Description

Check the state object to see if the requested state is physically possible. Only CRTCs and planes have check callbacks, so for any additional (global) checking that a driver needs it can simply wrap that around this function. Drivers without such needs can directly use this as their drm_mode_config_funcs.atomic_check callback.

This just wraps the two parts of the state checking for planes and modeset state in the default order: First it calls drm_atomic_helper_check_modeset() and then drm_atomic_helper_check_planes(). The assumption is that the drm_plane_helper_funcs.atomic_check and drm_crtc_helper_funcs.atomic_check functions depend upon an updated adjusted_mode.clock to e.g. properly compute watermarks.

Note that zpos normalization will add all enable planes to the state which might not desired for some drivers. For example enable/disable of a cursor plane which have fixed zpos value would trigger all other enabled planes to be forced to the state change.

Return

Zero for success or -errno

void drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev, struct drm_atomic_state *old_state)

update legacy modeset state

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *old_state

atomic state object with old state structures

Description

This function updates all the various legacy modeset state pointers in connectors, encoders and CRTCs.

Drivers can use this for building their own atomic commit if they don’t have a pure helper-based modeset implementation.

Since these updates are not synchronized with lockings, only code paths called from drm_mode_config_helper_funcs.atomic_commit_tail can look at the legacy state filled out by this helper. Defacto this means this helper and the legacy state pointers are only really useful for transitioning an existing driver to the atomic world.

void drm_atomic_helper_calc_timestamping_constants(struct drm_atomic_state *state)

update vblank timestamping constants

Parameters

struct drm_atomic_state *state

atomic state object

Description

Updates the timestamping constants used for precise vblank timestamps by calling drm_calc_timestamping_constants() for all enabled crtcs in state.

void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev, struct drm_atomic_state *old_state)

modeset commit to disable outputs

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *old_state

atomic state object with old state structures

Description

This function shuts down all the outputs that need to be shut down and prepares them (if required) with the new mode.

For compatibility with legacy CRTC helpers this should be called before drm_atomic_helper_commit_planes(), which is what the default commit function does. But drivers with different needs can group the modeset commits together and do the plane commits at the end. This is useful for drivers doing runtime PM since planes updates then only happen when the CRTC is actually enabled.

void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, struct drm_atomic_state *old_state)

modeset commit to enable outputs

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *old_state

atomic state object with old state structures

Description

This function enables all the outputs with the new configuration which had to be turned off for the update.

For compatibility with legacy CRTC helpers this should be called after drm_atomic_helper_commit_planes(), which is what the default commit function does. But drivers with different needs can group the modeset commits together and do the plane commits at the end. This is useful for drivers doing runtime PM since planes updates then only happen when the CRTC is actually enabled.

int drm_atomic_helper_wait_for_fences(struct drm_device *dev, struct drm_atomic_state *state, bool pre_swap)

wait for fences stashed in plane state

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *state

atomic state object with old state structures

bool pre_swap

If true, do an interruptible wait, and state is the new state. Otherwise state is the old state.

Description

For implicit sync, driver should fish the exclusive fence out from the incoming fb’s and stash it in the drm_plane_state. This is called after drm_atomic_helper_swap_state() so it uses the current plane state (and just uses the atomic state to find the changed planes)

Note that pre_swap is needed since the point where we block for fences moves around depending upon whether an atomic commit is blocking or non-blocking. For non-blocking commit all waiting needs to happen after drm_atomic_helper_swap_state() is called, but for blocking commits we want to wait before we do anything that can’t be easily rolled back. That is before we call drm_atomic_helper_swap_state().

Returns zero if success or < 0 if dma_fence_wait() fails.

void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, struct drm_atomic_state *old_state)

wait for vblank on CRTCs

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *old_state

atomic state object with old state structures

Description

Helper to, after atomic commit, wait for vblanks on all affected CRTCs (ie. before cleaning up old framebuffers using drm_atomic_helper_cleanup_planes()). It will only wait on CRTCs where the framebuffers have actually changed to optimize for the legacy cursor and plane update use-case.

Drivers using the nonblocking commit tracking support initialized by calling drm_atomic_helper_setup_commit() should look at drm_atomic_helper_wait_for_flip_done() as an alternative.

void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev, struct drm_atomic_state *old_state)

wait for all page flips to be done

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *old_state

atomic state object with old state structures

Description

Helper to, after atomic commit, wait for page flips on all affected crtcs (ie. before cleaning up old framebuffers using drm_atomic_helper_cleanup_planes()). Compared to drm_atomic_helper_wait_for_vblanks() this waits for the completion on all CRTCs, assuming that cursors-only updates are signalling their completion immediately (or using a different path).

This requires that drivers use the nonblocking commit tracking support initialized using drm_atomic_helper_setup_commit().

void drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state)

commit atomic update to hardware

Parameters

struct drm_atomic_state *old_state

atomic state object with old state structures

Description

This is the default implementation for the drm_mode_config_helper_funcs.atomic_commit_tail hook, for drivers that do not support runtime_pm or do not need the CRTC to be enabled to perform a commit. Otherwise, see drm_atomic_helper_commit_tail_rpm().

Note that the default ordering of how the various stages are called is to match the legacy modeset helper library closest.

void drm_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state)

commit atomic update to hardware

Parameters

struct drm_atomic_state *old_state

new modeset state to be committed

Description

This is an alternative implementation for the drm_mode_config_helper_funcs.atomic_commit_tail hook, for drivers that support runtime_pm or need the CRTC to be enabled to perform a commit. Otherwise, one should use the default implementation drm_atomic_helper_commit_tail().

int drm_atomic_helper_async_check(struct drm_device *dev, struct drm_atomic_state *state)

check if state can be committed asynchronously

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *state

the driver state object

Description

This helper will check if it is possible to commit the state asynchronously. Async commits are not supposed to swap the states like normal sync commits but just do in-place changes on the current state.

It will return 0 if the commit can happen in an asynchronous fashion or error if not. Note that error just mean it can’t be committed asynchronously, if it fails the commit should be treated like a normal synchronous commit.

void drm_atomic_helper_async_commit(struct drm_device *dev, struct drm_atomic_state *state)

commit state asynchronously

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *state

the driver state object

Description

This function commits a state asynchronously, i.e., not vblank synchronized. It should be used on a state only when drm_atomic_async_check() succeeds. Async commits are not supposed to swap the states like normal sync commits, but just do in-place changes on the current state.

TODO: Implement full swap instead of doing in-place changes.

int drm_atomic_helper_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock)

commit validated state object

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *state

the driver state object

bool nonblock

whether nonblocking behavior is requested.

Description

This function commits a with drm_atomic_helper_check() pre-validated state object. This can still fail when e.g. the framebuffer reservation fails. This function implements nonblocking commits, using drm_atomic_helper_setup_commit() and related functions.

Committing the actual hardware state is done through the drm_mode_config_helper_funcs.atomic_commit_tail callback, or its default implementation drm_atomic_helper_commit_tail().

Return

Zero for success or -errno.

int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, bool nonblock)

setup possibly nonblocking commit

Parameters

struct drm_atomic_state *state

new modeset state to be committed

bool nonblock

whether nonblocking behavior is requested.

Description

This function prepares state to be used by the atomic helper’s support for nonblocking commits. Drivers using the nonblocking commit infrastructure should always call this function from their drm_mode_config_funcs.atomic_commit hook.

Drivers that need to extend the commit setup to private objects can use the drm_mode_config_helper_funcs.atomic_commit_setup hook.

To be able to use this support drivers need to use a few more helper functions. drm_atomic_helper_wait_for_dependencies() must be called before actually committing the hardware state, and for nonblocking commits this call must be placed in the async worker. See also drm_atomic_helper_swap_state() and its stall parameter, for when a driver’s commit hooks look at the drm_crtc.state, drm_plane.state or drm_connector.state pointer directly.

Completion of the hardware commit step must be signalled using drm_atomic_helper_commit_hw_done(). After this step the driver is not allowed to read or change any permanent software or hardware modeset state. The only exception is state protected by other means than drm_modeset_lock locks. Only the free standing state with pointers to the old state structures can be inspected, e.g. to clean up old buffers using drm_atomic_helper_cleanup_planes().

At the very end, before cleaning up state drivers must call drm_atomic_helper_commit_cleanup_done().

This is all implemented by in drm_atomic_helper_commit(), giving drivers a complete and easy-to-use default implementation of the atomic_commit() hook.

The tracking of asynchronously executed and still pending commits is done using the core structure drm_crtc_commit.

By default there’s no need to clean up resources allocated by this function explicitly: drm_atomic_state_default_clear() will take care of that automatically.

Return

0 on success. -EBUSY when userspace schedules nonblocking commits too fast, -ENOMEM on allocation failures and -EINTR when a signal is pending.

void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state)

wait for required preceding commits

Parameters

struct drm_atomic_state *old_state

atomic state object with old state structures

Description

This function waits for all preceding commits that touch the same CRTC as old_state to both be committed to the hardware (as signalled by drm_atomic_helper_commit_hw_done()) and executed by the hardware (as signalled by calling drm_crtc_send_vblank_event() on the drm_crtc_state.event).

This is part of the atomic helper support for nonblocking commits, see drm_atomic_helper_setup_commit() for an overview.

void drm_atomic_helper_fake_vblank(struct drm_atomic_state *old_state)

fake VBLANK events if needed

Parameters

struct drm_atomic_state *old_state

atomic state object with old state structures

Description

This function walks all CRTCs and fakes VBLANK events on those with drm_crtc_state.no_vblank set to true and drm_crtc_state.event != NULL. The primary use of this function is writeback connectors working in oneshot mode and faking VBLANK events. In this case they only fake the VBLANK event when a job is queued, and any change to the pipeline that does not touch the connector is leading to timeouts when calling drm_atomic_helper_wait_for_vblanks() or drm_atomic_helper_wait_for_flip_done(). In addition to writeback connectors, this function can also fake VBLANK events for CRTCs without VBLANK interrupt.

This is part of the atomic helper support for nonblocking commits, see drm_atomic_helper_setup_commit() for an overview.

void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *old_state)

setup possible nonblocking commit

Parameters

struct drm_atomic_state *old_state

atomic state object with old state structures

Description

This function is used to signal completion of the hardware commit step. After this step the driver is not allowed to read or change any permanent software or hardware modeset state. The only exception is state protected by other means than drm_modeset_lock locks.

Drivers should try to postpone any expensive or delayed cleanup work after this function is called.

This is part of the atomic helper support for nonblocking commits, see drm_atomic_helper_setup_commit() for an overview.

void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state)

signal completion of commit

Parameters

struct drm_atomic_state *old_state

atomic state object with old state structures

Description

This signals completion of the atomic update old_state, including any cleanup work. If used, it must be called right before calling drm_atomic_state_put().

This is part of the atomic helper support for nonblocking commits, see drm_atomic_helper_setup_commit() for an overview.

int drm_atomic_helper_prepare_planes(struct drm_device *dev, struct drm_atomic_state *state)

prepare plane resources before commit

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *state

atomic state object with new state structures

Description

This function prepares plane state, specifically framebuffers, for the new configuration, by calling drm_plane_helper_funcs.prepare_fb. If any failure is encountered this function will call drm_plane_helper_funcs.cleanup_fb on any already successfully prepared framebuffer.

Return

0 on success, negative error code on failure.

void drm_atomic_helper_unprepare_planes(struct drm_device *dev, struct drm_atomic_state *state)

release plane resources on aborts

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *state

atomic state object with old state structures

Description

This function cleans up plane state, specifically framebuffers, from the atomic state. It undoes the effects of drm_atomic_helper_prepare_planes() when aborting an atomic commit. For cleaning up after a successful commit use drm_atomic_helper_cleanup_planes().

void drm_atomic_helper_commit_planes(struct drm_device *dev, struct drm_atomic_state *old_state, uint32_t flags)

commit plane state

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *old_state

atomic state object with old state structures

uint32_t flags

flags for committing plane state

Description

This function commits the new plane state using the plane and atomic helper functions for planes and CRTCs. It assumes that the atomic state has already been pushed into the relevant object state pointers, since this step can no longer fail.

It still requires the global state object old_state to know which planes and crtcs need to be updated though.

Note that this function does all plane updates across all CRTCs in one step. If the hardware can’t support this approach look at drm_atomic_helper_commit_planes_on_crtc() instead.

Plane parameters can be updated by applications while the associated CRTC is disabled. The DRM/KMS core will store the parameters in the plane state, which will be available to the driver when the CRTC is turned on. As a result most drivers don’t need to be immediately notified of plane updates for a disabled CRTC.

Unless otherwise needed, drivers are advised to set the ACTIVE_ONLY flag in flags in order not to receive plane update notifications related to a disabled CRTC. This avoids the need to manually ignore plane updates in driver code when the driver and/or hardware can’t or just don’t need to deal with updates on disabled CRTCs, for example when supporting runtime PM.

Drivers may set the NO_DISABLE_AFTER_MODESET flag in flags if the relevant display controllers require to disable a CRTC’s planes when the CRTC is disabled. This function would skip the drm_plane_helper_funcs.atomic_disable call for a plane if the CRTC of the old plane state needs a modesetting operation. Of course, the drivers need to disable the planes in their CRTC disable callbacks since no one else would do that.

The drm_atomic_helper_commit() default implementation doesn’t set the ACTIVE_ONLY flag to most closely match the behaviour of the legacy helpers. This should not be copied blindly by drivers.

void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state)

commit plane state for a CRTC

Parameters

struct drm_crtc_state *old_crtc_state

atomic state object with the old CRTC state

Description

This function commits the new plane state using the plane and atomic helper functions for planes on the specific CRTC. It assumes that the atomic state has already been pushed into the relevant object state pointers, since this step can no longer fail.

This function is useful when plane updates should be done CRTC-by-CRTC instead of one global step like drm_atomic_helper_commit_planes() does.

This function can only be savely used when planes are not allowed to move between different CRTCs because this function doesn’t handle inter-CRTC dependencies. Callers need to ensure that either no such dependencies exist, resolve them through ordering of commit calls or through some other means.

void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state, bool atomic)

helper to disable CRTC’s planes

Parameters

struct drm_crtc_state *old_crtc_state

atomic state object with the old CRTC state

bool atomic

if set, synchronize with CRTC’s atomic_begin/flush hooks

Description

Disables all planes associated with the given CRTC. This can be used for instance in the CRTC helper atomic_disable callback to disable all planes.

If the atomic-parameter is set the function calls the CRTC’s atomic_begin hook before and atomic_flush hook after disabling the planes.

It is a bug to call this function without having implemented the drm_plane_helper_funcs.atomic_disable plane hook.

void drm_atomic_helper_cleanup_planes(struct drm_device *dev, struct drm_atomic_state *old_state)

cleanup plane resources after commit

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *old_state

atomic state object with old state structures

Description

This function cleans up plane state, specifically framebuffers, from the old configuration. Hence the old configuration must be perserved in old_state to be able to call this function.

This function may not be called on the new state when the atomic update fails at any point after calling drm_atomic_helper_prepare_planes(). Use drm_atomic_helper_unprepare_planes() in this case.

int drm_atomic_helper_swap_state(struct drm_atomic_state *state, bool stall)

store atomic state into current sw state

Parameters

struct drm_atomic_state *state

atomic state

bool stall

stall for preceding commits

Description

This function stores the atomic state into the current state pointers in all driver objects. It should be called after all failing steps have been done and succeeded, but before the actual hardware state is committed.

For cleanup and error recovery the current state for all changed objects will be swapped into state.

With that sequence it fits perfectly into the plane prepare/cleanup sequence:

  1. Call drm_atomic_helper_prepare_planes() with the staged atomic state.

  2. Do any other steps that might fail.

  3. Put the staged state into the current state pointers with this function.

  4. Actually commit the hardware state.

5. Call drm_atomic_helper_cleanup_planes() with state, which since step 3 contains the old state. Also do any other cleanup required with that state.

stall must be set when nonblocking commits for this driver directly access the drm_plane.state, drm_crtc.state or drm_connector.state pointer. With the current atomic helpers this is almost always the case, since the helpers don’t pass the right state structures to the callbacks.

Return

Returns 0 on success. Can return -ERESTARTSYS when stall is true and the waiting for the previous commits has been interrupted.

int drm_atomic_helper_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)

Helper for primary plane update using atomic

Parameters

struct drm_plane *plane

plane object to update

struct drm_crtc *crtc

owning CRTC of owning plane

struct drm_framebuffer *fb

framebuffer to flip onto plane

int crtc_x

x offset of primary plane on crtc

int crtc_y

y offset of primary plane on crtc

unsigned int crtc_w

width of primary plane rectangle on crtc

unsigned int crtc_h

height of primary plane rectangle on crtc

uint32_t src_x

x offset of fb for panning

uint32_t src_y

y offset of fb for panning

uint32_t src_w

width of source rectangle in fb

uint32_t src_h

height of source rectangle in fb

struct drm_modeset_acquire_ctx *ctx

lock acquire context

Description

Provides a default plane update handler using the atomic driver interface.

Return

Zero on success, error code on failure

int drm_atomic_helper_disable_plane(struct drm_plane *plane, struct drm_modeset_acquire_ctx *ctx)

Helper for primary plane disable using atomic

Parameters

struct drm_plane *plane

plane to disable

struct drm_modeset_acquire_ctx *ctx

lock acquire context

Description

Provides a default plane disable handler using the atomic driver interface.

Return

Zero on success, error code on failure

int drm_atomic_helper_set_config(struct drm_mode_set *set, struct drm_modeset_acquire_ctx *ctx)

set a new config from userspace

Parameters

struct drm_mode_set *set

mode set configuration

struct drm_modeset_acquire_ctx *ctx

lock acquisition context

Description

Provides a default CRTC set_config handler using the atomic driver interface.

NOTE

For backwards compatibility with old userspace this automatically resets the “link-status” property to GOOD, to force any link re-training. The SETCRTC ioctl does not define whether an update does need a full modeset or just a plane update, hence we’re allowed to do that. See also drm_connector_set_link_status_property().

Return

Returns 0 on success, negative errno numbers on failure.

int drm_atomic_helper_disable_all(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx)

disable all currently active outputs

Parameters

struct drm_device *dev

DRM device

struct drm_modeset_acquire_ctx *ctx

lock acquisition context

Description

Loops through all connectors, finding those that aren’t turned off and then turns them off by setting their DPMS mode to OFF and deactivating the CRTC that they are connected to.

This is used for example in suspend/resume to disable all currently active functions when suspending. If you just want to shut down everything at e.g. driver unload, look at drm_atomic_helper_shutdown().

Note that if callers haven’t already acquired all modeset locks this might return -EDEADLK, which must be handled by calling drm_modeset_backoff().

See also: drm_atomic_helper_suspend(), drm_atomic_helper_resume() and drm_atomic_helper_shutdown().

Return

0 on success or a negative error code on failure.

void drm_atomic_helper_shutdown(struct drm_device *dev)

shutdown all CRTC

Parameters

struct drm_device *dev

DRM device

Description

This shuts down all CRTC, which is useful for driver unloading. Shutdown on suspend should instead be handled with drm_atomic_helper_suspend(), since that also takes a snapshot of the modeset state to be restored on resume.

This is just a convenience wrapper around drm_atomic_helper_disable_all(), and it is the atomic version of drm_helper_force_disable_all().

struct drm_atomic_state *drm_atomic_helper_duplicate_state(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx)

duplicate an atomic state object

Parameters

struct drm_device *dev

DRM device

struct drm_modeset_acquire_ctx *ctx

lock acquisition context

Description

Makes a copy of the current atomic state by looping over all objects and duplicating their respective states. This is used for example by suspend/ resume support code to save the state prior to suspend such that it can be restored upon resume.

Note that this treats atomic state as persistent between save and restore. Drivers must make sure that this is possible and won’t result in confusion or erroneous behaviour.

Note that if callers haven’t already acquired all modeset locks this might return -EDEADLK, which must be handled by calling drm_modeset_backoff().

See also: drm_atomic_helper_suspend(), drm_atomic_helper_resume()

Return

A pointer to the copy of the atomic state object on success or an ERR_PTR()-encoded error code on failure.

struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev)

subsystem-level suspend helper

Parameters

struct drm_device *dev

DRM device

Description

Duplicates the current atomic state, disables all active outputs and then returns a pointer to the original atomic state to the caller. Drivers can pass this pointer to the drm_atomic_helper_resume() helper upon resume to restore the output configuration that was active at the time the system entered suspend.

Note that it is potentially unsafe to use this. The atomic state object returned by this function is assumed to be persistent. Drivers must ensure that this holds true. Before calling this function, drivers must make sure to suspend fbdev emulation so that nothing can be using the device.

See also: drm_atomic_helper_duplicate_state(), drm_atomic_helper_disable_all(), drm_atomic_helper_resume(), drm_atomic_helper_commit_duplicated_state()

Return

A pointer to a copy of the state before suspend on success or an ERR_PTR()- encoded error code on failure. Drivers should store the returned atomic state object and pass it to the drm_atomic_helper_resume() helper upon resume.

int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state, struct drm_modeset_acquire_ctx *ctx)

commit duplicated state

Parameters

struct drm_atomic_state *state

duplicated atomic state to commit

struct drm_modeset_acquire_ctx *ctx

pointer to acquire_ctx to use for commit.

Description

The state returned by drm_atomic_helper_duplicate_state() and drm_atomic_helper_suspend() is partially invalid, and needs to be fixed up before commit.

See also: drm_atomic_helper_suspend()

Return

0 on success or a negative error code on failure.

int drm_atomic_helper_resume(struct drm_device *dev, struct drm_atomic_state *state)

subsystem-level resume helper

Parameters

struct drm_device *dev

DRM device

struct drm_atomic_state *state

atomic state to resume to

Description

Calls drm_mode_config_reset() to synchronize hardware and software states, grabs all modeset locks and commits the atomic state object. This can be used in conjunction with the drm_atomic_helper_suspend() helper to implement suspend/resume for drivers that support atomic mode-setting.

See also: drm_atomic_helper_suspend()

Return

0 on success or a negative error code on failure.

int drm_atomic_helper_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)

execute a legacy page flip

Parameters

struct drm_crtc *crtc

DRM CRTC

struct drm_framebuffer *fb

DRM framebuffer

struct drm_pending_vblank_event *event

optional DRM event to signal upon completion

uint32_t flags

flip flags for non-vblank sync’ed updates

struct drm_modeset_acquire_ctx *ctx

lock acquisition context

Description

Provides a default drm_crtc_funcs.page_flip implementation using the atomic driver interface.

See also: drm_atomic_helper_page_flip_target()

Return

Returns 0 on success, negative errno numbers on failure.

int drm_atomic_helper_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)

do page flip on target vblank period.

Parameters

struct drm_crtc *crtc

DRM CRTC

struct drm_framebuffer *fb

DRM framebuffer

struct drm_pending_vblank_event *event

optional DRM event to signal upon completion

uint32_t flags

flip flags for non-vblank sync’ed updates

uint32_t target

specifying the target vblank period when the flip to take effect

struct drm_modeset_acquire_ctx *ctx

lock acquisition context

Description

Provides a default drm_crtc_funcs.page_flip_target implementation. Similar to drm_atomic_helper_page_flip() with extra parameter to specify target vblank period to flip.

Return

Returns 0 on success, negative errno numbers on failure.

u32 *drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge, struct drm_bridge_state *bridge_state, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state, u32 output_fmt, unsigned int *num_input_fmts)

Propagate output format to the input end of a bridge

Parameters

struct drm_bridge *bridge

bridge control structure

struct drm_bridge_state *bridge_state

new bridge state

struct drm_crtc_state *crtc_state

new CRTC state

struct drm_connector_state *conn_state

new connector state

u32 output_fmt

tested output bus format

unsigned int *num_input_fmts

will contain the size of the returned array

Description

This helper is a pluggable implementation of the drm_bridge_funcs.atomic_get_input_bus_fmts operation for bridges that don’t modify the bus configuration between their input and their output. It returns an array of input formats with a single element set to output_fmt.

Return

a valid format array of size num_input_fmts, or NULL if the allocation failed

Atomic State Reset and Initialization

Both the drm core and the atomic helpers assume that there is always the full and correct atomic software state for all connectors, CRTCs and planes available. Which is a bit a problem on driver load and also after system suspend. One way to solve this is to have a hardware state read-out infrastructure which reconstructs the full software state (e.g. the i915 driver).

The simpler solution is to just reset the software state to everything off, which is easiest to do by calling drm_mode_config_reset(). To facilitate this the atomic helpers provide default reset implementations for all hooks.

On the upside the precise state tracking of atomic simplifies system suspend and resume a lot. For drivers using drm_mode_config_reset() a complete recipe is implemented in drm_atomic_helper_suspend() and drm_atomic_helper_resume(). For other drivers the building blocks are split out, see the documentation for these functions.

Atomic State Helper Reference

void __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state, struct drm_crtc *crtc)

reset the CRTC state

Parameters

struct drm_crtc_state *crtc_state

atomic CRTC state, must not be NULL

struct drm_crtc *crtc

CRTC object, must not be NULL

Description

Initializes the newly allocated crtc_state with default values. This is useful for drivers that subclass the CRTC state.

void __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state)

reset state on CRTC

Parameters

struct drm_crtc *crtc

drm CRTC

struct drm_crtc_state *crtc_state

CRTC state to assign

Description

Initializes the newly allocated crtc_state and assigns it to the drm_crtc->state pointer of crtc, usually required when initializing the drivers or when called from the drm_crtc_funcs.reset hook.

This is useful for drivers that subclass the CRTC state.

void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)

default drm_crtc_funcs.reset hook for CRTCs

Parameters

struct drm_crtc *crtc

drm CRTC

Description

Resets the atomic state for crtc by freeing the state pointer (which might be NULL, e.g. at driver load time) and allocating a new empty state object.

void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc, struct drm_crtc_state *state)

copy atomic CRTC state

Parameters

struct drm_crtc *crtc

CRTC object

struct drm_crtc_state *state

atomic CRTC state

Description

Copies atomic state from a CRTC’s current state and resets inferred values. This is useful for drivers that subclass the CRTC state.

struct drm_crtc_state *drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)

default state duplicate hook

Parameters

struct drm_crtc *crtc

drm CRTC

Description

Default CRTC state duplicate hook for drivers which don’t have their own subclassed CRTC state structure.

void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)

release CRTC state

Parameters

struct drm_crtc_state *state

CRTC state object to release

Description

Releases all resources stored in the CRTC state without actually freeing the memory of the CRTC state. This is useful for drivers that subclass the CRTC state.

void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *state)

default state destroy hook

Parameters

struct drm_crtc *crtc

drm CRTC

struct drm_crtc_state *state

CRTC state object to release

Description

Default CRTC state destroy hook for drivers which don’t have their own subclassed CRTC state structure.

void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state, struct drm_plane *plane)

resets plane state to default values

Parameters

struct drm_plane_state *plane_state

atomic plane state, must not be NULL

struct drm_plane *plane

plane object, must not be NULL

Description

Initializes the newly allocated plane_state with default values. This is useful for drivers that subclass the CRTC state.

void __drm_atomic_helper_plane_reset(struct drm_plane *plane, struct drm_plane_state *plane_state)

reset state on plane

Parameters

struct drm_plane *plane

drm plane

struct drm_plane_state *plane_state

plane state to assign

Description

Initializes the newly allocated plane_state and assigns it to the drm_crtc->state pointer of plane, usually required when initializing the drivers or when called from the drm_plane_funcs.reset hook.

This is useful for drivers that subclass the plane state.

void drm_atomic_helper_plane_reset(struct drm_plane *plane)

default drm_plane_funcs.reset hook for planes

Parameters

struct drm_plane *plane

drm plane

Description

Resets the atomic state for plane by freeing the state pointer (which might be NULL, e.g. at driver load time) and allocating a new empty state object.

void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, struct drm_plane_state *state)

copy atomic plane state

Parameters

struct drm_plane *plane

plane object

struct drm_plane_state *state

atomic plane state

Description

Copies atomic state from a plane’s current state. This is useful for drivers that subclass the plane state.

struct drm_plane_state *drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)

default state duplicate hook

Parameters

struct drm_plane *plane

drm plane

Description

Default plane state duplicate hook for drivers which don’t have their own subclassed plane state structure.

void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)

release plane state

Parameters

struct drm_plane_state *state

plane state object to release

Description

Releases all resources stored in the plane state without actually freeing the memory of the plane state. This is useful for drivers that subclass the plane state.

void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state)

default state destroy hook

Parameters

struct drm_plane *plane

drm plane

struct drm_plane_state *state

plane state object to release

Description

Default plane state destroy hook for drivers which don’t have their own subclassed plane state structure.

void __drm_atomic_helper_connector_state_reset(struct drm_connector_state *conn_state, struct drm_connector *connector)

reset the connector state

Parameters

struct drm_connector_state *conn_state

atomic connector state, must not be NULL

struct drm_connector *connector

connectotr object, must not be NULL

Description

Initializes the newly allocated conn_state with default values. This is useful for drivers that subclass the connector state.

void __drm_atomic_helper_connector_reset(struct drm_connector *connector, struct drm_connector_state *conn_state)

reset state on connector

Parameters

struct drm_connector *connector

drm connector

struct drm_connector_state *conn_state

connector state to assign

Description

Initializes the newly allocated conn_state and assigns it to the drm_connector->state pointer of connector, usually required when initializing the drivers or when called from the drm_connector_funcs.reset hook.

This is useful for drivers that subclass the connector state.

void drm_atomic_helper_connector_reset(struct drm_connector *connector)

default drm_connector_funcs.reset hook for connectors

Parameters

struct drm_connector *connector

drm connector

Description

Resets the atomic state for connector by freeing the state pointer (which might be NULL, e.g. at driver load time) and allocating a new empty state object.

void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector)

Resets TV connector properties

Parameters

struct drm_connector *connector

DRM connector

Description

Resets the TV-related properties attached to a connector.

void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)

Resets Analog TV connector properties

Parameters

struct drm_connector *connector

DRM connector

Description

Resets the analog TV properties attached to a connector

int drm_atomic_helper_connector_tv_check(struct drm_connector *connector, struct drm_atomic_state *state)

Validate an analog TV connector state

Parameters

struct drm_connector *connector

DRM Connector

struct drm_atomic_state *state

the DRM State object

Description

Checks the state object to see if the requested state is valid for an analog TV connector.

Return

0 for success, a negative error code on error.

void __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, struct drm_connector_state *state)

copy atomic connector state

Parameters

struct drm_connector *connector

connector object

struct drm_connector_state *state

atomic connector state

Description

Copies atomic state from a connector’s current state. This is useful for drivers that subclass the connector state.

struct drm_connector_state *drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)

default state duplicate hook

Parameters

struct drm_connector *connector

drm connector

Description

Default connector state duplicate hook for drivers which don’t have their own subclassed connector state structure.

void __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)

release connector state

Parameters

struct drm_connector_state *state

connector state object to release

Description

Releases all resources stored in the connector state without actually freeing the memory of the connector state. This is useful for drivers that subclass the connector state.

void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, struct drm_connector_state *state)

default state destroy hook

Parameters

struct drm_connector *connector

drm connector

struct drm_connector_state *state

connector state object to release

Description

Default connector state destroy hook for drivers which don’t have their own subclassed connector state structure.

void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj, struct drm_private_state *state)

copy atomic private state

Parameters

struct drm_private_obj *obj

CRTC object

struct drm_private_state *state

new private object state

Description

Copies atomic state from a private objects’s current state and resets inferred values. This is useful for drivers that subclass the private state.

void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge, struct drm_bridge_state *state)

Copy atomic bridge state

Parameters

struct drm_bridge *bridge

bridge object

struct drm_bridge_state *state

atomic bridge state

Description

Copies atomic state from a bridge’s current state and resets inferred values. This is useful for drivers that subclass the bridge state.

struct drm_bridge_state *drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge)

Duplicate a bridge state object

Parameters

struct drm_bridge *bridge

bridge object

Description

Allocates a new bridge state and initializes it with the current bridge state values. This helper is meant to be used as a bridge drm_bridge_funcs.atomic_duplicate_state hook for bridges that don’t subclass the bridge state.

void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge, struct drm_bridge_state *state)

Destroy a bridge state object

Parameters

struct drm_bridge *bridge

the bridge this state refers to

struct drm_bridge_state *state

bridge state to destroy

Description

Destroys a bridge state previously created by drm_atomic_helper_bridge_reset`() or :c:type:`drm_atomic_helper_bridge_duplicate_state`(). This helper is meant to be used as a bridge :c:type:`drm_bridge_funcs.atomic_destroy_state hook for bridges that don’t subclass the bridge state.

void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge, struct drm_bridge_state *state)

Initialize a bridge state to its default

Parameters

struct drm_bridge *bridge

the bridge this state refers to

struct drm_bridge_state *state

bridge state to initialize

Description

Initializes the bridge state to default values. This is meant to be called by the bridge drm_bridge_funcs.atomic_reset hook for bridges that subclass the bridge state.

struct drm_bridge_state *drm_atomic_helper_bridge_reset(struct drm_bridge *bridge)

Allocate and initialize a bridge state to its default

Parameters

struct drm_bridge *bridge

the bridge this state refers to

Description

Allocates the bridge state and initializes it to default values. This helper is meant to be used as a bridge drm_bridge_funcs.atomic_reset hook for bridges that don’t subclass the bridge state.

GEM Atomic Helper Reference

The GEM atomic helpers library implements generic atomic-commit functions for drivers that use GEM objects. Currently, it provides synchronization helpers, and plane state and framebuffer BO mappings for planes with shadow buffers.

Before scanout, a plane’s framebuffer needs to be synchronized with possible writers that draw into the framebuffer. All drivers should call drm_gem_plane_helper_prepare_fb() from their implementation of struct drm_plane_helper.prepare_fb . It sets the plane’s fence from the framebuffer so that the DRM core can synchronize access automatically. drm_gem_plane_helper_prepare_fb() can also be used directly as implementation of prepare_fb.

#include <drm/drm_gem_atomic_helper.h>

struct drm_plane_helper_funcs driver_plane_helper_funcs = {
        ...,
        . prepare_fb = drm_gem_plane_helper_prepare_fb,
};

A driver using a shadow buffer copies the content of the shadow buffers into the HW’s framebuffer memory during an atomic update. This requires a mapping of the shadow buffer into kernel address space. The mappings cannot be established by commit-tail functions, such as atomic_update, as this would violate locking rules around dma_buf_vmap().

The helpers for shadow-buffered planes establish and release mappings, and provide struct drm_shadow_plane_state, which stores the plane’s mapping for commit-tail functions.

Shadow-buffered planes can easily be enabled by using the provided macros DRM_GEM_SHADOW_PLANE_FUNCS and DRM_GEM_SHADOW_PLANE_HELPER_FUNCS. These macros set up the plane and plane-helper callbacks to point to the shadow-buffer helpers.

#include <drm/drm_gem_atomic_helper.h>

struct drm_plane_funcs driver_plane_funcs = {
        ...,
        DRM_GEM_SHADOW_PLANE_FUNCS,
};

struct drm_plane_helper_funcs driver_plane_helper_funcs = {
        ...,
        DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
};

In the driver’s atomic-update function, shadow-buffer mappings are available from the plane state. Use to_drm_shadow_plane_state() to upcast from struct drm_plane_state.

void driver_plane_atomic_update(struct drm_plane *plane,
                                struct drm_plane_state *old_plane_state)
{
        struct drm_plane_state *plane_state = plane->state;
        struct drm_shadow_plane_state *shadow_plane_state =
                to_drm_shadow_plane_state(plane_state);

        // access shadow buffer via shadow_plane_state->map
}

A mapping address for each of the framebuffer’s buffer object is stored in struct drm_shadow_plane_state.map. The mappings are valid while the state is being used.

Drivers that use struct drm_simple_display_pipe can use DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS to initialize the rsp callbacks. Access to shadow-buffer mappings is similar to regular atomic_update.

struct drm_simple_display_pipe_funcs driver_pipe_funcs = {
        ...,
        DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS,
};

void driver_pipe_enable(struct drm_simple_display_pipe *pipe,
                        struct drm_crtc_state *crtc_state,
                        struct drm_plane_state *plane_state)
{
        struct drm_shadow_plane_state *shadow_plane_state =
                to_drm_shadow_plane_state(plane_state);

        // access shadow buffer via shadow_plane_state->map
}
DRM_SHADOW_PLANE_MAX_WIDTH

DRM_SHADOW_PLANE_MAX_WIDTH ()

Maximum width of a plane’s shadow buffer in pixels

Parameters

Description

For drivers with shadow planes, the maximum width of the framebuffer is usually independent from hardware limitations. Drivers can initialize struct drm_mode_config.max_width from DRM_SHADOW_PLANE_MAX_WIDTH.

DRM_SHADOW_PLANE_MAX_HEIGHT

DRM_SHADOW_PLANE_MAX_HEIGHT ()

Maximum height of a plane’s shadow buffer in scanlines

Parameters

Description

For drivers with shadow planes, the maximum height of the framebuffer is usually independent from hardware limitations. Drivers can initialize struct drm_mode_config.max_height from DRM_SHADOW_PLANE_MAX_HEIGHT.

struct drm_shadow_plane_state

plane state for planes with shadow buffers

Definition:

struct drm_shadow_plane_state {
    struct drm_plane_state base;
    struct drm_format_conv_state fmtcnv_state;
    struct iosys_map map[DRM_FORMAT_MAX_PLANES];
    struct iosys_map data[DRM_FORMAT_MAX_PLANES];
};

Members

base

plane state

fmtcnv_state

Format-conversion state

Per-plane state for format conversion. Flags for copying shadow buffers into backend storage. Also holds temporary storage for format conversion.

map

Mappings of the plane’s framebuffer BOs in to kernel address space

The memory mappings stored in map should be established in the plane’s prepare_fb callback and removed in the cleanup_fb callback.

data

Address of each framebuffer BO’s data

The address of the data stored in each mapping. This is different for framebuffers with non-zero offset fields.

Description

For planes that use a shadow buffer, struct drm_shadow_plane_state provides the regular plane state plus mappings of the shadow buffer into kernel address space.

struct drm_shadow_plane_state *to_drm_shadow_plane_state(struct drm_plane_state *state)

upcasts from struct drm_plane_state

Parameters

struct drm_plane_state *state

the plane state

DRM_GEM_SHADOW_PLANE_FUNCS

DRM_GEM_SHADOW_PLANE_FUNCS ()

Initializes struct drm_plane_funcs for shadow-buffered planes

Parameters

Description

Drivers may use GEM BOs as shadow buffers over the framebuffer memory. This macro initializes struct drm_plane_funcs to use the rsp helper functions.

DRM_GEM_SHADOW_PLANE_HELPER_FUNCS

DRM_GEM_SHADOW_PLANE_HELPER_FUNCS ()

Initializes struct drm_plane_helper_funcs for shadow-buffered planes

Parameters

Description

Drivers may use GEM BOs as shadow buffers over the framebuffer memory. This macro initializes struct drm_plane_helper_funcs to use the rsp helper functions.

DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS

DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS ()

Initializes struct drm_simple_display_pipe_funcs for shadow-buffered planes

Parameters

Description

Drivers may use GEM BOs as shadow buffers over the framebuffer memory. This macro initializes struct drm_simple_display_pipe_funcs to use the rsp helper functions.

int drm_gem_plane_helper_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state)

Prepare a GEM backed framebuffer

Parameters

struct drm_plane *plane

Plane

struct drm_plane_state *state

Plane state the fence will be attached to

Description

This function extracts the exclusive fence from drm_gem_object.resv and attaches it to plane state for the atomic helper to wait on. This is necessary to correctly implement implicit synchronization for any buffers shared as a struct dma_buf. This function can be used as the drm_plane_helper_funcs.prepare_fb callback.

There is no need for drm_plane_helper_funcs.cleanup_fb hook for simple GEM based framebuffer drivers which have their buffers always pinned in memory.

This function is the default implementation for GEM drivers of drm_plane_helper_funcs.prepare_fb if no callback is provided.

void __drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane, struct drm_shadow_plane_state *new_shadow_plane_state)

duplicates shadow-buffered plane state

Parameters

struct drm_plane *plane

the plane

struct drm_shadow_plane_state *new_shadow_plane_state

the new shadow-buffered plane state

Description

This function duplicates shadow-buffered plane state. This is helpful for drivers that subclass struct drm_shadow_plane_state.

The function does not duplicate existing mappings of the shadow buffers. Mappings are maintained during the atomic commit by the plane’s prepare_fb and cleanup_fb helpers. See drm_gem_prepare_shadow_fb() and drm_gem_cleanup_shadow_fb() for corresponding helpers.

struct drm_plane_state *drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane)

duplicates shadow-buffered plane state

Parameters

struct drm_plane *plane

the plane

Description

This function implements struct drm_plane_funcs.atomic_duplicate_state for shadow-buffered planes. It assumes the existing state to be of type struct drm_shadow_plane_state and it allocates the new state to be of this type.

The function does not duplicate existing mappings of the shadow buffers. Mappings are maintained during the atomic commit by the plane’s prepare_fb and cleanup_fb helpers. See drm_gem_prepare_shadow_fb() and drm_gem_cleanup_shadow_fb() for corresponding helpers.

Return

A pointer to a new plane state on success, or NULL otherwise.

void __drm_gem_destroy_shadow_plane_state(struct drm_shadow_plane_state *shadow_plane_state)

cleans up shadow-buffered plane state

Parameters

struct drm_shadow_plane_state *shadow_plane_state

the shadow-buffered plane state

Description

This function cleans up shadow-buffered plane state. Helpful for drivers that subclass struct drm_shadow_plane_state.

void drm_gem_destroy_shadow_plane_state(struct drm_plane *plane, struct drm_plane_state *plane_state)

deletes shadow-buffered plane state

Parameters

struct drm_plane *plane

the plane

struct drm_plane_state *plane_state

the plane state of type struct drm_shadow_plane_state

Description

This function implements struct drm_plane_funcs.atomic_destroy_state for shadow-buffered planes. It expects that mappings of shadow buffers have been released already.

void __drm_gem_reset_shadow_plane(struct drm_plane *plane, struct drm_shadow_plane_state *shadow_plane_state)

resets a shadow-buffered plane

Parameters

struct drm_plane *plane

the plane

struct drm_shadow_plane_state *shadow_plane_state

the shadow-buffered plane state

Description

This function resets state for shadow-buffered planes. Helpful for drivers that subclass struct drm_shadow_plane_state.

void drm_gem_reset_shadow_plane(struct drm_plane *plane)

resets a shadow-buffered plane

Parameters

struct drm_plane *plane

the plane

Description

This function implements struct drm_plane_funcs.reset_plane for shadow-buffered planes. It assumes the current plane state to be of type struct drm_shadow_plane and it allocates the new state of this type.

int drm_gem_begin_shadow_fb_access(struct drm_plane *plane, struct drm_plane_state *plane_state)

prepares shadow framebuffers for CPU access

Parameters

struct drm_plane *plane

the plane

struct drm_plane_state *plane_state

the plane state of type struct drm_shadow_plane_state

Description

This function implements struct drm_plane_helper_funcs.begin_fb_access. It maps all buffer objects of the plane’s framebuffer into kernel address space and stores them in struct drm_shadow_plane_state.map. The first data bytes are available in struct drm_shadow_plane_state.data.

See drm_gem_end_shadow_fb_access() for cleanup.

Return

0 on success, or a negative errno code otherwise.

void drm_gem_end_shadow_fb_access(struct drm_plane *plane, struct drm_plane_state *plane_state)

releases shadow framebuffers from CPU access

Parameters

struct drm_plane *plane

the plane

struct drm_plane_state *plane_state

the plane state of type struct drm_shadow_plane_state

Description

This function implements struct drm_plane_helper_funcs.end_fb_access. It undoes all effects of drm_gem_begin_shadow_fb_access() in reverse order.

See drm_gem_begin_shadow_fb_access() for more information.

int drm_gem_simple_kms_begin_shadow_fb_access(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state)

prepares shadow framebuffers for CPU access

Parameters

struct drm_simple_display_pipe *pipe

the simple display pipe

struct drm_plane_state *plane_state

the plane state of type struct drm_shadow_plane_state

Description

This function implements struct drm_simple_display_funcs.begin_fb_access.

See drm_gem_begin_shadow_fb_access() for details and drm_gem_simple_kms_cleanup_shadow_fb() for cleanup.

Return

0 on success, or a negative errno code otherwise.

void drm_gem_simple_kms_end_shadow_fb_access(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state)

releases shadow framebuffers from CPU access

Parameters

struct drm_simple_display_pipe *pipe

the simple display pipe

struct drm_plane_state *plane_state

the plane state of type struct drm_shadow_plane_state

Description

This function implements struct drm_simple_display_funcs.end_fb_access. It undoes all effects of drm_gem_simple_kms_begin_shadow_fb_access() in reverse order.

See drm_gem_simple_kms_begin_shadow_fb_access().

void drm_gem_simple_kms_reset_shadow_plane(struct drm_simple_display_pipe *pipe)

resets a shadow-buffered plane

Parameters

struct drm_simple_display_pipe *pipe

the simple display pipe

Description

This function implements struct drm_simple_display_funcs.reset_plane for shadow-buffered planes.

struct drm_plane_state *drm_gem_simple_kms_duplicate_shadow_plane_state(struct drm_simple_display_pipe *pipe)

duplicates shadow-buffered plane state

Parameters

struct drm_simple_display_pipe *pipe

the simple display pipe

Description

This function implements struct drm_simple_display_funcs.duplicate_plane_state for shadow-buffered planes. It does not duplicate existing mappings of the shadow buffers. Mappings are maintained during the atomic commit by the plane’s prepare_fb and cleanup_fb helpers.

Return

A pointer to a new plane state on success, or NULL otherwise.

void drm_gem_simple_kms_destroy_shadow_plane_state(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state)

resets shadow-buffered plane state

Parameters

struct drm_simple_display_pipe *pipe

the simple display pipe

struct drm_plane_state *plane_state

the plane state of type struct drm_shadow_plane_state

Description

This function implements struct drm_simple_display_funcs.destroy_plane_state for shadow-buffered planes. It expects that mappings of shadow buffers have been released already.

Simple KMS Helper Reference

This helper library provides helpers for drivers for simple display hardware.

drm_simple_display_pipe_init() initializes a simple display pipeline which has only one full-screen scanout buffer feeding one output. The pipeline is represented by struct drm_simple_display_pipe and binds together drm_plane, drm_crtc and drm_encoder structures into one fixed entity. Some flexibility for code reuse is provided through a separately allocated drm_connector object and supporting optional drm_bridge encoder drivers.

Many drivers require only a very simple encoder that fulfills the minimum requirements of the display pipeline and does not add additional functionality. The function drm_simple_encoder_init() provides an implementation of such an encoder.

struct drm_simple_display_pipe_funcs

helper operations for a simple display pipeline

Definition:

struct drm_simple_display_pipe_funcs {
    enum drm_mode_status (*mode_valid)(struct drm_simple_display_pipe *pipe, const struct drm_display_mode *mode);
    void (*enable)(struct drm_simple_display_pipe *pipe,struct drm_crtc_state *crtc_state, struct drm_plane_state *plane_state);
    void (*disable)(struct drm_simple_display_pipe *pipe);
    int (*check)(struct drm_simple_display_pipe *pipe,struct drm_plane_state *plane_state, struct drm_crtc_state *crtc_state);
    void (*update)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *old_plane_state);
    int (*prepare_fb)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state);
    void (*cleanup_fb)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state);
    int (*begin_fb_access)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *new_plane_state);
    void (*end_fb_access)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state);
    int (*enable_vblank)(struct drm_simple_display_pipe *pipe);
    void (*disable_vblank)(struct drm_simple_display_pipe *pipe);
    void (*reset_crtc)(struct drm_simple_display_pipe *pipe);
    struct drm_crtc_state * (*duplicate_crtc_state)(struct drm_simple_display_pipe *pipe);
    void (*destroy_crtc_state)(struct drm_simple_display_pipe *pipe, struct drm_crtc_state *crtc_state);
    void (*reset_plane)(struct drm_simple_display_pipe *pipe);
    struct drm_plane_state * (*duplicate_plane_state)(struct drm_simple_display_pipe *pipe);
    void (*destroy_plane_state)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state);
};

Members

mode_valid

This callback is used to check if a specific mode is valid in the crtc used in this simple display pipe. This should be implemented if the display pipe has some sort of restriction in the modes it can display. For example, a given display pipe may be responsible to set a clock value. If the clock can not produce all the values for the available modes then this callback can be used to restrict the number of modes to only the ones that can be displayed. Another reason can be bandwidth mitigation: the memory port on the display controller can have bandwidth limitations not allowing pixel data to be fetched at any rate.

This hook is used by the probe helpers to filter the mode list in drm_helper_probe_single_connector_modes(), and it is used by the atomic helpers to validate modes supplied by userspace in drm_atomic_helper_check_modeset().

This function is optional.

NOTE:

Since this function is both called from the check phase of an atomic commit, and the mode validation in the probe paths it is not allowed to look at anything else but the passed-in mode, and validate it against configuration-invariant hardware constraints.

RETURNS:

drm_mode_status Enum

enable

This function should be used to enable the pipeline. It is called when the underlying crtc is enabled. This hook is optional.

disable

This function should be used to disable the pipeline. It is called when the underlying crtc is disabled. This hook is optional.

check

This function is called in the check phase of an atomic update, specifically when the underlying plane is checked. The simple display pipeline helpers already check that the plane is not scaled, fills the entire visible area and is always enabled when the crtc is also enabled. This hook is optional.

RETURNS:

0 on success, -EINVAL if the state or the transition can’t be supported, -ENOMEM on memory allocation failure and -EDEADLK if an attempt to obtain another state object ran into a drm_modeset_lock deadlock.

update

This function is called when the underlying plane state is updated. This hook is optional.

This is the function drivers should submit the drm_pending_vblank_event from. Using either drm_crtc_arm_vblank_event(), when the driver supports vblank interrupt handling, or drm_crtc_send_vblank_event() for more complex case. In case the hardware lacks vblank support entirely, drivers can set struct drm_crtc_state.no_vblank in struct drm_simple_display_pipe_funcs.check and let DRM’s atomic helper fake a vblank event.

prepare_fb

Optional, called by drm_plane_helper_funcs.prepare_fb. Please read the documentation for the drm_plane_helper_funcs.prepare_fb hook for more details.

For GEM drivers who neither have a prepare_fb nor cleanup_fb hook set, drm_gem_plane_helper_prepare_fb() is called automatically to implement this. Other drivers which need additional plane processing can call drm_gem_plane_helper_prepare_fb() from their prepare_fb hook.

cleanup_fb

Optional, called by drm_plane_helper_funcs.cleanup_fb. Please read the documentation for the drm_plane_helper_funcs.cleanup_fb hook for more details.

begin_fb_access

Optional, called by drm_plane_helper_funcs.begin_fb_access. Please read the documentation for the drm_plane_helper_funcs.begin_fb_access hook for more details.

end_fb_access

Optional, called by drm_plane_helper_funcs.end_fb_access. Please read the documentation for the drm_plane_helper_funcs.end_fb_access hook for more details.

enable_vblank

Optional, called by drm_crtc_funcs.enable_vblank. Please read the documentation for the drm_crtc_funcs.enable_vblank hook for more details.

disable_vblank

Optional, called by drm_crtc_funcs.disable_vblank. Please read the documentation for the drm_crtc_funcs.disable_vblank hook for more details.

reset_crtc

Optional, called by drm_crtc_funcs.reset. Please read the documentation for the drm_crtc_funcs.reset hook for more details.

duplicate_crtc_state

Optional, called by drm_crtc_funcs.atomic_duplicate_state. Please read the documentation for the drm_crtc_funcs.atomic_duplicate_state hook for more details.

destroy_crtc_state

Optional, called by drm_crtc_funcs.atomic_destroy_state. Please read the documentation for the drm_crtc_funcs.atomic_destroy_state hook for more details.

reset_plane

Optional, called by drm_plane_funcs.reset. Please read the documentation for the drm_plane_funcs.reset hook for more details.

duplicate_plane_state

Optional, called by drm_plane_funcs.atomic_duplicate_state. Please read the documentation for the drm_plane_funcs.atomic_duplicate_state hook for more details.

destroy_plane_state

Optional, called by drm_plane_funcs.atomic_destroy_state. Please read the documentation for the drm_plane_funcs.atomic_destroy_state hook for more details.

struct drm_simple_display_pipe

simple display pipeline

Definition:

struct drm_simple_display_pipe {
    struct drm_crtc crtc;
    struct drm_plane plane;
    struct drm_encoder encoder;
    struct drm_connector *connector;
    const struct drm_simple_display_pipe_funcs *funcs;
};

Members

crtc

CRTC control structure

plane

Plane control structure

encoder

Encoder control structure

connector

Connector control structure

funcs

Pipeline control functions (optional)

Description

Simple display pipeline with plane, crtc and encoder collapsed into one entity. It should be initialized by calling drm_simple_display_pipe_init().

drmm_simple_encoder_alloc

drmm_simple_encoder_alloc (dev, type, member, encoder_type)

Allocate and initialize an encoder with basic functionality.

Parameters

dev

drm device

type

the type of the struct which contains struct drm_encoder

member

the name of the drm_encoder within type.

encoder_type

user visible type of the encoder

Description

Allocates and initializes an encoder that has no further functionality. Settings for possible CRTC and clones are left to their initial values. Cleanup is automatically handled through registering drm_encoder_cleanup() with drmm_add_action().

Return

Pointer to new encoder, or ERR_PTR on failure.

int drm_simple_encoder_init(struct drm_device *dev, struct drm_encoder *encoder, int encoder_type)

Initialize a preallocated encoder with basic functionality.

Parameters

struct drm_device *dev

drm device

struct drm_encoder *encoder

the encoder to initialize

int encoder_type

user visible type of the encoder

Description

Initialises a preallocated encoder that has no further functionality. Settings for possible CRTC and clones are left to their initial values. The encoder will be cleaned up automatically as part of the mode-setting cleanup.

The caller of drm_simple_encoder_init() is responsible for freeing the encoder’s memory after the encoder has been cleaned up. At the moment this only works reliably if the encoder data structure is stored in the device structure. Free the encoder’s memory as part of the device release function.

Note

consider using drmm_simple_encoder_alloc() instead of drm_simple_encoder_init() to let the DRM managed resource infrastructure take care of cleanup and deallocation.

Return

Zero on success, error code on failure.

int drm_simple_display_pipe_attach_bridge(struct drm_simple_display_pipe *pipe, struct drm_bridge *bridge)

Attach a bridge to the display pipe

Parameters

struct drm_simple_display_pipe *pipe

simple display pipe object

struct drm_bridge *bridge

bridge to attach

Description

Makes it possible to still use the drm_simple_display_pipe helpers when a DRM bridge has to be used.

Note that you probably want to initialize the pipe by passing a NULL connector to drm_simple_display_pipe_init().

Return

Zero on success, negative error code on failure.

int drm_simple_display_pipe_init(struct drm_device *dev, struct drm_simple_display_pipe *pipe, const struct drm_simple_display_pipe_funcs *funcs, const uint32_t *formats, unsigned int format_count, const uint64_t *format_modifiers, struct drm_connector *connector)

Initialize a simple display pipeline

Parameters

struct drm_device *dev

DRM device

struct drm_simple_display_pipe *pipe

simple display pipe object to initialize

const struct drm_simple_display_pipe_funcs *funcs

callbacks for the display pipe (optional)

const uint32_t *formats

array of supported formats (DRM_FORMAT_*)

unsigned int format_count

number of elements in formats

const uint64_t *format_modifiers

array of formats modifiers

struct drm_connector *connector

connector to attach and register (optional)

Description

Sets up a display pipeline which consist of a really simple plane-crtc-encoder pipe.

If a connector is supplied, the pipe will be coupled with the provided connector. You may supply a NULL connector when using drm bridges, that handle connectors themselves (see drm_simple_display_pipe_attach_bridge()).

Teardown of a simple display pipe is all handled automatically by the drm core through calling drm_mode_config_cleanup(). Drivers afterwards need to release the memory for the structure themselves.

Return

Zero on success, negative error code on failure.

fbdev Helper Functions Reference

The fb helper functions are useful to provide an fbdev on top of a drm kernel mode setting driver. They can be used mostly independently from the crtc helper functions used by many drivers to implement the kernel mode setting interfaces. Drivers that use one of the shared memory managers, TTM, SHMEM, DMA, should instead use the corresponding fbdev emulation.

For suspend/resume consider using drm_mode_config_helper_suspend() and drm_mode_config_helper_resume() which takes care of fbdev as well.

All other functions exported by the fb helper library can be used to implement the fbdev driver interface by the driver.

It is possible, though perhaps somewhat tricky, to implement race-free hotplug detection using the fbdev helpers. The drm_fb_helper_prepare() helper must be called first to initialize the minimum required to make hotplug detection work. Drivers also need to make sure to properly set up the drm_mode_config.funcs member. After calling drm_kms_helper_poll_init() it is safe to enable interrupts and start processing hotplug events. At the same time, drivers should initialize all modeset objects such as CRTCs, encoders and connectors. To finish up the fbdev helper initialization, the drm_fb_helper_init() function is called. To probe for all attached displays and set up an initial configuration using the detected hardware, drivers should call drm_fb_helper_initial_config().

If drm_framebuffer_funcs.dirty is set, the drm_fb_helper_{cfb,sys}_{write,fillrect,copyarea,imageblit} functions will accumulate changes and schedule drm_fb_helper.dirty_work to run right away. This worker then calls the dirty() function ensuring that it will always run in process context since the fb_*() function could be running in atomic context. If drm_fb_helper_deferred_io() is used as the deferred_io callback it will also schedule dirty_work with the damage collected from the mmap page writes.

void drm_fbdev_dma_setup(struct drm_device *dev, unsigned int preferred_bpp)

Setup fbdev emulation for GEM DMA helpers

Parameters

struct drm_device *dev

DRM device

unsigned int preferred_bpp

Preferred bits per pixel for the device. 32 is used if this is zero.

Description

This function sets up fbdev emulation for GEM DMA drivers that support dumb buffers with a virtual address and that can be mmap’ed. drm_fbdev_dma_setup() shall be called after the DRM driver registered the new DRM device with drm_dev_register().

Restore, hotplug events and teardown are all taken care of. Drivers that do suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves. Simple drivers might use drm_mode_config_helper_suspend().

This function is safe to call even when there are no connectors present. Setup will be retried on the next hotplug event.

The fbdev is destroyed by drm_dev_unregister().

void drm_fbdev_shmem_setup(struct drm_device *dev, unsigned int preferred_bpp)

Setup fbdev emulation for GEM SHMEM helpers

Parameters

struct drm_device *dev

DRM device

unsigned int preferred_bpp

Preferred bits per pixel for the device. 32 is used if this is zero.

Description

This function sets up fbdev emulation for GEM DMA drivers that support dumb buffers with a virtual address and that can be mmap’ed. drm_fbdev_shmem_setup() shall be called after the DRM driver registered the new DRM device with drm_dev_register().

Restore, hotplug events and teardown are all taken care of. Drivers that do suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves. Simple drivers might use drm_mode_config_helper_suspend().

This function is safe to call even when there are no connectors present. Setup will be retried on the next hotplug event.

The fbdev is destroyed by drm_dev_unregister().

void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp)

Setup fbdev emulation for TTM-based drivers

Parameters

struct drm_device *dev

DRM device

unsigned int preferred_bpp

Preferred bits per pixel for the device.

Description

This function sets up fbdev emulation for TTM-based drivers that support dumb buffers with a virtual address and that can be mmap’ed. drm_fbdev_ttm_setup() shall be called after the DRM driver registered the new DRM device with drm_dev_register().

Restore, hotplug events and teardown are all taken care of. Drivers that do suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves. Simple drivers might use drm_mode_config_helper_suspend().

In order to provide fixed mmap-able memory ranges, fbdev emulation uses a shadow buffer in system memory. The implementation blits the shadow fbdev buffer onto the real buffer in regular intervals.

This function is safe to call even when there are no connectors present. Setup will be retried on the next hotplug event.

The fbdev is destroyed by drm_dev_unregister().

struct drm_fb_helper_surface_size

describes fbdev size and scanout surface size

Definition:

struct drm_fb_helper_surface_size {
    u32 fb_width;
    u32 fb_height;
    u32 surface_width;
    u32 surface_height;
    u32 surface_bpp;
    u32 surface_depth;
};

Members

fb_width

fbdev width

fb_height

fbdev height

surface_width

scanout buffer width

surface_height

scanout buffer height

surface_bpp

scanout buffer bpp

surface_depth

scanout buffer depth

Description

Note that the scanout surface width/height may be larger than the fbdev width/height. In case of multiple displays, the scanout surface is sized according to the largest width/height (so it is large enough for all CRTCs to scanout). But the fbdev width/height is sized to the minimum width/ height of all the displays. This ensures that fbcon fits on the smallest of the attached displays. fb_width/fb_height is used by drm_fb_helper_fill_info() to fill out the fb_info.var structure.

struct drm_fb_helper_funcs

driver callbacks for the fbdev emulation library

Definition:

struct drm_fb_helper_funcs {
    int (*fb_probe)(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes);
    int (*fb_dirty)(struct drm_fb_helper *helper, struct drm_clip_rect *clip);
};

Members

fb_probe

Driver callback to allocate and initialize the fbdev info structure. Furthermore it also needs to allocate the DRM framebuffer used to back the fbdev.

This callback is mandatory.

RETURNS:

The driver should return 0 on success and a negative error code on failure.

fb_dirty

Driver callback to update the framebuffer memory. If set, fbdev emulation will invoke this callback in regular intervals after the framebuffer has been written.

This callback is optional.

Returns: 0 on success, or an error code otherwise.

Description

Driver callbacks used by the fbdev emulation helper library.

struct drm_fb_helper

main structure to emulate fbdev on top of KMS

Definition:

struct drm_fb_helper {
    struct drm_client_dev client;
    struct drm_client_buffer *buffer;
    struct drm_framebuffer *fb;
    struct drm_device *dev;
    const struct drm_fb_helper_funcs *funcs;
    struct fb_info *info;
    u32 pseudo_palette[17];
    struct drm_clip_rect damage_clip;
    spinlock_t damage_lock;
    struct work_struct damage_work;
    struct work_struct resume_work;
    struct mutex lock;
    struct list_head kernel_fb_list;
    bool delayed_hotplug;
    bool deferred_setup;
    int preferred_bpp;
#ifdef CONFIG_FB_DEFERRED_IO;
    struct fb_deferred_io fbdefio;
#endif;
};

Members

client

DRM client used by the generic fbdev emulation.

buffer

Framebuffer used by the generic fbdev emulation.

fb

Scanout framebuffer object

dev

DRM device

funcs

driver callbacks for fb helper

info

emulated fbdev device info struct

pseudo_palette

fake palette of 16 colors

damage_clip

clip rectangle used with deferred_io to accumulate damage to the screen buffer

damage_lock

spinlock protecting damage_clip

damage_work

worker used to flush the framebuffer

resume_work

worker used during resume if the console lock is already taken

lock

Top-level FBDEV helper lock. This protects all internal data structures and lists, such as connector_info and crtc_info.

FIXME: fbdev emulation locking is a mess and long term we want to protect all helper internal state with this lock as well as reduce core KMS locking as much as possible.

kernel_fb_list

Entry on the global kernel_fb_helper_list, used for kgdb entry/exit.

delayed_hotplug

A hotplug was received while fbdev wasn’t in control of the DRM device, i.e. another KMS master was active. The output configuration needs to be reprobe when fbdev is in control again.

deferred_setup

If no outputs are connected (disconnected or unknown) the FB helper code will defer setup until at least one of the outputs shows up. This field keeps track of the status so that setup can be retried at every hotplug event until it succeeds eventually.

Protected by lock.

preferred_bpp

Temporary storage for the driver’s preferred BPP setting passed to FB helper initialization. This needs to be tracked so that deferred FB helper setup can pass this on.

See also: deferred_setup

fbdefio

Temporary storage for the driver’s FB deferred I/O handler. If the driver uses the DRM fbdev emulation layer, this is set by the core to a generic deferred I/O handler if a driver is preferring to use a shadow buffer.

Description

This is the main structure used by the fbdev helpers. Drivers supporting fbdev emulation should embedded this into their overall driver structure. Drivers must also fill out a struct drm_fb_helper_funcs with a few operations.

DRM_FB_HELPER_DEFAULT_OPS

DRM_FB_HELPER_DEFAULT_OPS ()

helper define for drm drivers

Parameters

Description

Helper define to register default implementations of drm_fb_helper functions. To be used in struct fb_ops of drm drivers.

int drm_fb_helper_debug_enter(struct fb_info *info)

implementation for fb_ops.fb_debug_enter

Parameters

struct fb_info *info

fbdev registered by the helper

int drm_fb_helper_debug_leave(struct fb_info *info)

implementation for fb_ops.fb_debug_leave

Parameters

struct fb_info *info

fbdev registered by the helper

int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)

restore fbdev configuration

Parameters

struct drm_fb_helper *fb_helper

driver-allocated fbdev helper, can be NULL

Description

This helper should be called from fbdev emulation’s drm_client_funcs.restore callback. It ensures that the user isn’t greeted with a black screen when the userspace compositor releases the display device.

Return

0 on success, or a negative errno code otherwise.

int drm_fb_helper_blank(int blank, struct fb_info *info)

implementation for fb_ops.fb_blank

Parameters

int blank

desired blanking state

struct fb_info *info

fbdev registered by the helper

void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, unsigned int preferred_bpp, const struct drm_fb_helper_funcs *funcs)

setup a drm_fb_helper structure

Parameters

struct drm_device *dev

DRM device

struct drm_fb_helper *helper

driver-allocated fbdev helper structure to set up

unsigned int preferred_bpp

Preferred bits per pixel for the device.

const struct drm_fb_helper_funcs *funcs

pointer to structure of functions associate with this helper

Description

Sets up the bare minimum to make the framebuffer helper usable. This is useful to implement race-free initialization of the polling helpers.

void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper)

clean up a drm_fb_helper structure

Parameters

struct drm_fb_helper *fb_helper

driver-allocated fbdev helper structure to set up

Description

Cleans up the framebuffer helper. Inverse of drm_fb_helper_prepare().

int drm_fb_helper_init(struct drm_device *dev, struct drm_fb_helper *fb_helper)

initialize a struct drm_fb_helper

Parameters

struct drm_device *dev

drm device

struct drm_fb_helper *fb_helper

driver-allocated fbdev helper structure to initialize

Description

This allocates the structures for the fbdev helper with the given limits. Note that this won’t yet touch the hardware (through the driver interfaces) nor register the fbdev. This is only done in drm_fb_helper_initial_config() to allow driver writes more control over the exact init sequence.

Drivers must call drm_fb_helper_prepare() before calling this function.

Return

Zero if everything went ok, nonzero otherwise.

struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper)

allocate fb_info and some of its members

Parameters

struct drm_fb_helper *fb_helper

driver-allocated fbdev helper

Description

A helper to alloc fb_info and the member cmap. Called by the driver within the fb_probe fb_helper callback function. Drivers do not need to release the allocated fb_info structure themselves, this is automatically done when calling drm_fb_helper_fini().

Return

fb_info pointer if things went okay, pointer containing error code otherwise

void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper)

release fb_info and its members

Parameters

struct drm_fb_helper *fb_helper

driver-allocated fbdev helper

Description

A helper to release fb_info and the member cmap. Drivers do not need to release the allocated fb_info structure themselves, this is automatically done when calling drm_fb_helper_fini().

void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper)

unregister fb_info framebuffer device

Parameters

struct drm_fb_helper *fb_helper

driver-allocated fbdev helper, can be NULL

Description

A wrapper around unregister_framebuffer, to release the fb_info framebuffer device. This must be called before releasing all resources for fb_helper by calling drm_fb_helper_fini().

void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)

finialize a struct drm_fb_helper

Parameters

struct drm_fb_helper *fb_helper

driver-allocated fbdev helper, can be NULL

Description

This cleans up all remaining resources associated with fb_helper.

void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagereflist)

fbdev deferred_io callback function

Parameters

struct fb_info *info

fb_info struct pointer

struct list_head *pagereflist

list of mmap framebuffer pages that have to be flushed

Description

This function is used as the fb_deferred_io.deferred_io callback function for flushing the fbdev mmap writes.

void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend)

wrapper around fb_set_suspend

Parameters

struct drm_fb_helper *fb_helper

driver-allocated fbdev helper, can be NULL

bool suspend

whether to suspend or resume

Description

A wrapper around fb_set_suspend implemented by fbdev core. Use drm_fb_helper_set_suspend_unlocked() if you don’t need to take the lock yourself

void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, bool suspend)

wrapper around fb_set_suspend that also takes the console lock

Parameters

struct drm_fb_helper *fb_helper

driver-allocated fbdev helper, can be NULL

bool suspend

whether to suspend or resume

Description

A wrapper around fb_set_suspend() that takes the console lock. If the lock isn’t available on resume, a worker is tasked with waiting for the lock to become available. The console lock can be pretty contented on resume due to all the printk activity.

This function can be called multiple times with the same state since fb_info.state is checked to see if fbdev is running or not before locking.

Use drm_fb_helper_set_suspend() if you need to take the lock yourself.

int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)

implementation for fb_ops.fb_setcmap

Parameters

struct fb_cmap *cmap

cmap to set

struct fb_info *info

fbdev registered by the helper

int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)

legacy ioctl implementation

Parameters

struct fb_info *info

fbdev registered by the helper

unsigned int cmd

ioctl command

unsigned long arg

ioctl argument

Description

A helper to implement the standard fbdev ioctl. Only FBIO_WAITFORVSYNC is implemented for now.

int drm_fb_helper_check_var(struct fb_var_screeninfo *var, struct fb_info *info)

implementation for fb_ops.fb_check_var

Parameters

struct fb_var_screeninfo *var

screeninfo to check

struct fb_info *info

fbdev registered by the helper

int drm_fb_helper_set_par(struct fb_info *info)

implementation for fb_ops.fb_set_par

Parameters

struct fb_info *info

fbdev registered by the helper

Description

This will let fbcon do the mode init and is called at initialization time by the fbdev core when registering the driver, and later on through the hotplug callback.

int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)

implementation for fb_ops.fb_pan_display

Parameters

struct fb_var_screeninfo *var

updated screen information

struct fb_info *info

fbdev registered by the helper

void drm_fb_helper_fill_info(struct fb_info *info, struct drm_fb_helper *fb_helper, struct drm_fb_helper_surface_size *sizes)

initializes fbdev information

Parameters

struct fb_info *info

fbdev instance to set up

struct drm_fb_helper *fb_helper

fb helper instance to use as template

struct drm_fb_helper_surface_size *sizes

describes fbdev size and scanout surface size

Description

Sets up the variable and fixed fbdev metainformation from the given fb helper instance and the drm framebuffer allocated in drm_fb_helper.fb.

Drivers should call this (or their equivalent setup code) from their drm_fb_helper_funcs.fb_probe callback after having allocated the fbdev backing storage framebuffer.

int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper)

setup a sane initial connector configuration

Parameters

struct drm_fb_helper *fb_helper

fb_helper device struct

Description

Scans the CRTCs and connectors and tries to put together an initial setup. At the moment, this is a cloned configuration across all heads with a new framebuffer object as the backing store.

Note that this also registers the fbdev and so allows userspace to call into the driver through the fbdev interfaces.

This function will call down into the drm_fb_helper_funcs.fb_probe callback to let the driver allocate and initialize the fbdev info structure and the drm framebuffer used to back the fbdev. drm_fb_helper_fill_info() is provided as a helper to setup simple default values for the fbdev info structure.

HANG DEBUGGING:

When you have fbcon support built-in or already loaded, this function will do a full modeset to setup the fbdev console. Due to locking misdesign in the VT/fbdev subsystem that entire modeset sequence has to be done while holding console_lock. Until console_unlock is called no dmesg lines will be sent out to consoles, not even serial console. This means when your driver crashes, you will see absolutely nothing else but a system stuck in this function, with no further output. Any kind of printk() you place within your own driver or in the drm core modeset code will also never show up.

Standard debug practice is to run the fbcon setup without taking the console_lock as a hack, to be able to see backtraces and crashes on the serial line. This can be done by setting the fb.lockless_register_fb=1 kernel cmdline option.

The other option is to just disable fbdev emulation since very likely the first modeset from userspace will crash in the same way, and is even easier to debug. This can be done by setting the drm_kms_helper.fbdev_emulation=0 kernel cmdline option.

Return

Zero if everything went ok, nonzero otherwise.

int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)

respond to a hotplug notification by probing all the outputs attached to the fb

Parameters

struct drm_fb_helper *fb_helper

driver-allocated fbdev helper, can be NULL

Description

Scan the connectors attached to the fb_helper and try to put together a setup after notification of a change in output configuration.

Called at runtime, takes the mode config locks to be able to check/change the modeset configuration. Must be run from process context (which usually means either the output polling work or a work item launched from the driver’s hotplug interrupt).

Note that drivers may call this even before calling drm_fb_helper_initial_config but only after drm_fb_helper_init. This allows for a race-free fbcon setup and will make sure that the fbdev emulation will not miss any hotplug events.

Return

0 on success and a non-zero error code otherwise.

void drm_fb_helper_lastclose(struct drm_device *dev)

DRM driver lastclose helper for fbdev emulation

Parameters

struct drm_device *dev

DRM device

Description

This function is obsolete. Call drm_fb_helper_restore_fbdev_mode_unlocked() instead.

format Helper Functions Reference

void drm_format_conv_state_init(struct drm_format_conv_state *state)

Initialize format-conversion state

Parameters

struct drm_format_conv_state *state

The state to initialize

Description

Clears all fields in struct drm_format_conv_state. The state will be empty with no preallocated resources.

void drm_format_conv_state_copy(struct drm_format_conv_state *state, const struct drm_format_conv_state *old_state)

Copy format-conversion state

Parameters

struct drm_format_conv_state *state

Destination state

const struct drm_format_conv_state *old_state

Source state

Description

Copies format-conversion state from old_state to state; except for temporary storage.

void *drm_format_conv_state_reserve(struct drm_format_conv_state *state, size_t new_size, gfp_t flags)

Allocates storage for format conversion

Parameters

struct drm_format_conv_state *state

The format-conversion state

size_t new_size

The minimum allocation size

gfp_t flags

Flags for kmalloc()

Description

Allocates at least new_size bytes and returns a pointer to the memory range. After calling this function, previously returned memory blocks are invalid. It’s best to collect all memory requirements of a format conversion and call this function once to allocate the range.

Return

A pointer to the allocated memory range, or NULL otherwise.

void drm_format_conv_state_release(struct drm_format_conv_state *state)

Releases an format-conversion storage

Parameters

struct drm_format_conv_state *state

The format-conversion state

Description

Releases the memory range references by the format-conversion state. After this call, all pointers to the memory are invalid. Prefer drm_format_conv_state_init() for cleaning up and unloading a driver.

unsigned int drm_fb_clip_offset(unsigned int pitch, const struct drm_format_info *format, const struct drm_rect *clip)

Returns the clipping rectangles byte-offset in a framebuffer

Parameters

unsigned int pitch

Framebuffer line pitch in byte

const struct drm_format_info *format

Framebuffer format

const struct drm_rect *clip

Clip rectangle

Return

The byte offset of the clip rectangle’s top-left corner within the framebuffer.

void drm_fb_memcpy(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip)

Copy clip buffer

Parameters

struct iosys_map *dst

Array of destination buffers

const unsigned int *dst_pitch

Array of numbers of bytes between the start of two consecutive scanlines within dst; can be NULL if scanlines are stored next to each other.

const struct iosys_map *src

Array of source buffers

const struct drm_framebuffer *fb

DRM framebuffer

const struct drm_rect *clip

Clip rectangle area to copy

Description

This function copies parts of a framebuffer to display memory. Destination and framebuffer formats must match. No conversion takes place. The parameters dst, dst_pitch and src refer to arrays. Each array must have at least as many entries as there are planes in fb’s format. Each entry stores the value for the format’s respective color plane at the same index.

This function does not apply clipping on dst (i.e. the destination is at the top-left corner).

void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, bool cached, struct drm_format_conv_state *state)

Swap bytes into clip buffer

Parameters

struct iosys_map *dst

Array of destination buffers

const unsigned int *dst_pitch

Array of numbers of bytes between the start of two consecutive scanlines within dst; can be NULL if scanlines are stored next to each other.

const struct iosys_map *src

Array of source buffers

const struct drm_framebuffer *fb

DRM framebuffer

const struct drm_rect *clip

Clip rectangle area to copy

bool cached

Source buffer is mapped cached (eg. not write-combined)

struct drm_format_conv_state *state

Transform and conversion state

Description

This function copies parts of a framebuffer to display memory and swaps per-pixel bytes during the process. Destination and framebuffer formats must match. The parameters dst, dst_pitch and src refer to arrays. Each array must have at least as many entries as there are planes in fb’s format. Each entry stores the value for the format’s respective color plane at the same index. If cached is false a temporary buffer is used to cache one pixel line at a time to speed up slow uncached reads.

This function does not apply clipping on dst (i.e. the destination is at the top-left corner).

void drm_fb_xrgb8888_to_rgb332(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

Convert XRGB8888 to RGB332 clip buffer

Parameters

struct iosys_map *dst

Array of RGB332 destination buffers

const unsigned int *dst_pitch

Array of numbers of bytes between the start of two consecutive scanlines within dst; can be NULL if scanlines are stored next to each other.

const struct iosys_map *src

Array of XRGB8888 source buffers

const struct drm_framebuffer *fb

DRM framebuffer

const struct drm_rect *clip

Clip rectangle area to copy

struct drm_format_conv_state *state

Transform and conversion state

Description

This function copies parts of a framebuffer to display memory and converts the color format during the process. Destination and framebuffer formats must match. The parameters dst, dst_pitch and src refer to arrays. Each array must have at least as many entries as there are planes in fb’s format. Each entry stores the value for the format’s respective color plane at the same index.

This function does not apply clipping on dst (i.e. the destination is at the top-left corner).

Drivers can use this function for RGB332 devices that don’t support XRGB8888 natively.

void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state, bool swab)

Convert XRGB8888 to RGB565 clip buffer

Parameters

struct iosys_map *dst

Array of RGB565 destination buffers

const unsigned int *dst_pitch

Array of numbers of bytes between the start of two consecutive scanlines within dst; can be NULL if scanlines are stored next to each other.

const struct iosys_map *src

Array of XRGB8888 source buffer

const struct drm_framebuffer *fb

DRM framebuffer

const struct drm_rect *clip

Clip rectangle area to copy

struct drm_format_conv_state *state

Transform and conversion state

bool swab

Swap bytes

Description

This function copies parts of a framebuffer to display memory and converts the color format during the process. Destination and framebuffer formats must match. The parameters dst, dst_pitch and src refer to arrays. Each array must have at least as many entries as there are planes in fb’s format. Each entry stores the value for the format’s respective color plane at the same index.

This function does not apply clipping on dst (i.e. the destination is at the top-left corner).

Drivers can use this function for RGB565 devices that don’t support XRGB8888 natively.

void drm_fb_xrgb8888_to_xrgb1555(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

Convert XRGB8888 to XRGB1555 clip buffer

Parameters

struct iosys_map *dst

Array of XRGB1555 destination buffers

const unsigned int *dst_pitch

Array of numbers of bytes between the start of two consecutive scanlines within dst; can be NULL if scanlines are stored next to each other.

const struct iosys_map *src

Array of XRGB8888 source buffer

const struct drm_framebuffer *fb

DRM framebuffer

const struct drm_rect *clip

Clip rectangle area to copy

struct drm_format_conv_state *state

Transform and conversion state

Description

This function copies parts of a framebuffer to display memory and converts the color format during the process. The parameters dst, dst_pitch and src refer to arrays. Each array must have at least as many entries as there are planes in fb’s format. Each entry stores the value for the format’s respective color plane at the same index.

This function does not apply clipping on dst (i.e. the destination is at the top-left corner).

Drivers can use this function for XRGB1555 devices that don’t support XRGB8888 natively.

void drm_fb_xrgb8888_to_argb1555(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

Convert XRGB8888 to ARGB1555 clip buffer

Parameters

struct iosys_map *dst

Array of ARGB1555 destination buffers

const unsigned int *dst_pitch

Array of numbers of bytes between the start of two consecutive scanlines within dst; can be NULL if scanlines are stored next to each other.

const struct iosys_map *src

Array of XRGB8888 source buffer

const struct drm_framebuffer *fb

DRM framebuffer

const struct drm_rect *clip

Clip rectangle area to copy

struct drm_format_conv_state *state

Transform and conversion state

Description

This function copies parts of a framebuffer to display memory and converts the color format during the process. The parameters dst, dst_pitch and src refer to arrays. Each array must have at least as many entries as there are planes in fb’s format. Each entry stores the value for the format’s respective color plane at the same index.

This function does not apply clipping on dst (i.e. the destination is at the top-left corner).

Drivers can use this function for ARGB1555 devices that don’t support XRGB8888 natively. It sets an opaque alpha channel as part of the conversion.

void drm_fb_xrgb8888_to_rgba5551(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

Convert XRGB8888 to RGBA5551 clip buffer

Parameters

struct iosys_map *dst

Array of RGBA5551 destination buffers

const unsigned int *dst_pitch

Array of numbers of bytes between the start of two consecutive scanlines within dst; can be NULL if scanlines are stored next to each other.

const struct iosys_map *src

Array of XRGB8888 source buffer

const struct drm_framebuffer *fb

DRM framebuffer

const struct drm_rect *clip

Clip rectangle area to copy

struct drm_format_conv_state *state

Transform and conversion state

Description

This function copies parts of a framebuffer to display memory and converts the color format during the process. The parameters dst, dst_pitch and src refer to arrays. Each array must have at least as many entries as there are planes in fb’s format. Each entry stores the value for the format’s respective color plane at the same index.

This function does not apply clipping on dst (i.e. the destination is at the top-left corner).

Drivers can use this function for RGBA5551 devices that don’t support XRGB8888 natively. It sets an opaque alpha channel as part of the conversion.

void drm_fb_xrgb8888_to_rgb888(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

Convert XRGB8888 to RGB888 clip buffer

Parameters

struct iosys_map *dst

Array of RGB888 destination buffers

const unsigned int *dst_pitch

Array of numbers of bytes between the start of two consecutive scanlines within dst; can be NULL if scanlines are stored next to each other.

const struct iosys_map *src

Array of XRGB8888 source buffers

const struct drm_framebuffer *fb

DRM framebuffer

const struct drm_rect *clip

Clip rectangle area to copy

struct drm_format_conv_state *state

Transform and conversion state

Description

This function copies parts of a framebuffer to display memory and converts the color format during the process. Destination and framebuffer formats must match. The parameters dst, dst_pitch and src refer to arrays. Each array must have at least as many entries as there are planes in fb’s format. Each entry stores the value for the format’s respective color plane at the same index.

This function does not apply clipping on dst (i.e. the destination is at the top-left corner).

Drivers can use this function for RGB888 devices that don’t natively support XRGB8888.

void drm_fb_xrgb8888_to_argb8888(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

Convert XRGB8888 to ARGB8888 clip buffer

Parameters

struct iosys_map *dst

Array of ARGB8888 destination buffers

const unsigned int *dst_pitch

Array of numbers of bytes between the start of two consecutive scanlines within dst; can be NULL if scanlines are stored next to each other.

const struct iosys_map *src

Array of XRGB8888 source buffer

const struct drm_framebuffer *fb

DRM framebuffer

const struct drm_rect *clip

Clip rectangle area to copy

struct drm_format_conv_state *state

Transform and conversion state

Description

This function copies parts of a framebuffer to display memory and converts the color format during the process. The parameters dst, dst_pitch and src refer to arrays. Each array must have at least as many entries as there are planes in fb’s format. Each entry stores the value for the format’s respective color plane at the same index.

This function does not apply clipping on dst (i.e. the destination is at the top-left corner).

Drivers can use this function for ARGB8888 devices that don’t support XRGB8888 natively. It sets an opaque alpha channel as part of the conversion.

void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

Convert XRGB8888 to XRGB2101010 clip buffer

Parameters

struct iosys_map *dst

Array of XRGB2101010 destination buffers

const unsigned int *dst_pitch

Array of numbers of bytes between the start of two consecutive scanlines within dst; can be NULL if scanlines are stored next to each other.

const struct iosys_map *src

Array of XRGB8888 source buffers

const struct drm_framebuffer *fb

DRM framebuffer

const struct drm_rect *clip

Clip rectangle area to copy

struct drm_format_conv_state *state

Transform and conversion state

Description

This function copies parts of a framebuffer to display memory and converts the color format during the process. Destination and framebuffer formats must match. The parameters dst, dst_pitch and src refer to arrays. Each array must have at least as many entries as there are planes in fb’s format. Each entry stores the value for the format’s respective color plane at the same index.

This function does not apply clipping on dst (i.e. the destination is at the top-left corner).

Drivers can use this function for XRGB2101010 devices that don’t support XRGB8888 natively.

void drm_fb_xrgb8888_to_argb2101010(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

Convert XRGB8888 to ARGB2101010 clip buffer

Parameters

struct iosys_map *dst

Array of ARGB2101010 destination buffers

const unsigned int *dst_pitch

Array of numbers of bytes between the start of two consecutive scanlines within dst; can be NULL if scanlines are stored next to each other.

const struct iosys_map *src

Array of XRGB8888 source buffers

const struct drm_framebuffer *fb

DRM framebuffer

const struct drm_rect *clip

Clip rectangle area to copy

struct drm_format_conv_state *state

Transform and conversion state

Description

This function copies parts of a framebuffer to display memory and converts the color format during the process. The parameters dst, dst_pitch and src refer to arrays. Each array must have at least as many entries as there are planes in fb’s format. Each entry stores the value for the format’s respective color plane at the same index.

This function does not apply clipping on dst (i.e. the destination is at the top-left corner).

Drivers can use this function for ARGB2101010 devices that don’t support XRGB8888 natively.

void drm_fb_xrgb8888_to_gray8(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

Convert XRGB8888 to grayscale

Parameters

struct iosys_map *dst

Array of 8-bit grayscale destination buffers

const unsigned int *dst_pitch

Array of numbers of bytes between the start of two consecutive scanlines within dst; can be NULL if scanlines are stored next to each other.

const struct iosys_map *src

Array of XRGB8888 source buffers

const struct drm_framebuffer *fb

DRM framebuffer

const struct drm_rect *clip

Clip rectangle area to copy

struct drm_format_conv_state *state

Transform and conversion state

Description

This function copies parts of a framebuffer to display memory and converts the color format during the process. Destination and framebuffer formats must match. The parameters dst, dst_pitch and src refer to arrays. Each array must have at least as many entries as there are planes in fb’s format. Each entry stores the value for the format’s respective color plane at the same index.

This function does not apply clipping on dst (i.e. the destination is at the top-left corner).

DRM doesn’t have native monochrome or grayscale support. Drivers can use this function for grayscale devices that don’t support XRGB8888 natively.Such drivers can announce the commonly supported XR24 format to userspace and use this function to convert to the native format. Monochrome drivers will use the most significant bit, where 1 means foreground color and 0 background color. ITU BT.601 is being used for the RGB -> luma (brightness) conversion.

int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t dst_format, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

Copy parts of a framebuffer to display memory

Parameters

struct iosys_map *dst

Array of display-memory addresses to copy to

const unsigned int *dst_pitch

Array of numbers of bytes between the start of two consecutive scanlines within dst; can be NULL if scanlines are stored next to each other.

uint32_t dst_format

FOURCC code of the display’s color format

const struct iosys_map *src

The framebuffer memory to copy from

const struct drm_framebuffer *fb

The framebuffer to copy from

const struct drm_rect *clip

Clip rectangle area to copy

struct drm_format_conv_state *state

Transform and conversion state

Description

This function copies parts of a framebuffer to display memory. If the formats of the display and the framebuffer mismatch, the blit function will attempt to convert between them during the process. The parameters dst, dst_pitch and src refer to arrays. Each array must have at least as many entries as there are planes in dst_format’s format. Each entry stores the value for the format’s respective color plane at the same index.

This function does not apply clipping on dst (i.e. the destination is at the top-left corner).

Return

0 on success, or -EINVAL if the color-format conversion failed, or a negative error code otherwise.

void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state)

Convert XRGB8888 to monochrome

Parameters

struct iosys_map *dst

Array of monochrome destination buffers (0=black, 1=white)

const unsigned int *dst_pitch

Array of numbers of bytes between the start of two consecutive scanlines within dst; can be NULL if scanlines are stored next to each other.

const struct iosys_map *src

Array of XRGB8888 source buffers

const struct drm_framebuffer *fb

DRM framebuffer

const struct drm_rect *clip

Clip rectangle area to copy

struct drm_format_conv_state *state

Transform and conversion state

Description

This function copies parts of a framebuffer to display memory and converts the color format during the process. Destination and framebuffer formats must match. The parameters dst, dst_pitch and src refer to arrays. Each array must have at least as many entries as there are planes in fb’s format. Each entry stores the value for the format’s respective color plane at the same index.

This function does not apply clipping on dst (i.e. the destination is at the top-left corner). The first pixel (upper left corner of the clip rectangle) will be converted and copied to the first bit (LSB) in the first byte of the monochrome destination buffer. If the caller requires that the first pixel in a byte must be located at an x-coordinate that is a multiple of 8, then the caller must take care itself of supplying a suitable clip rectangle.

DRM doesn’t have native monochrome support. Drivers can use this function for monochrome devices that don’t support XRGB8888 natively. Such drivers can announce the commonly supported XR24 format to userspace and use this function to convert to the native format.

This function uses drm_fb_xrgb8888_to_gray8() to convert to grayscale and then the result is converted from grayscale to monochrome.

size_t drm_fb_build_fourcc_list(struct drm_device *dev, const u32 *native_fourccs, size_t native_nfourccs, u32 *fourccs_out, size_t nfourccs_out)

Filters a list of supported color formats against the device’s native formats

Parameters

struct drm_device *dev

DRM device

const u32 *native_fourccs

4CC codes of natively supported color formats

size_t native_nfourccs

The number of entries in native_fourccs

u32 *fourccs_out

Returns 4CC codes of supported color formats

size_t nfourccs_out

The number of available entries in fourccs_out

Description

This function create a list of supported color format from natively supported formats and additional emulated formats. At a minimum, most userspace programs expect at least support for XRGB8888 on the primary plane. Devices that have to emulate the format, and possibly others, can use drm_fb_build_fourcc_list() to create a list of supported color formats. The returned list can be handed over to drm_universal_plane_init() et al. Native formats will go before emulated formats. Native formats with alpha channel will be replaced by such without, as primary planes usually don’t support alpha. Other heuristics might be applied to optimize the order. Formats near the beginning of the list are usually preferred over formats near the end of the list.

Return

The number of color-formats 4CC codes returned in fourccs_out.

Framebuffer DMA Helper Functions Reference

Provides helper functions for creating a DMA-contiguous framebuffer.

Depending on the platform, the buffers may be physically non-contiguous and mapped through an IOMMU or a similar mechanism, or allocated from physically-contiguous memory (using, for instance, CMA or a pool of memory reserved at early boot). This is handled behind the scenes by the DMA mapping API.

drm_gem_fb_create() is used in the drm_mode_config_funcs.fb_create callback function to create a DMA-contiguous framebuffer.

struct drm_gem_dma_object *drm_fb_dma_get_gem_obj(struct drm_framebuffer *fb, unsigned int plane)

Get DMA GEM object for framebuffer

Parameters

struct drm_framebuffer *fb

The framebuffer

unsigned int plane

Which plane

Description

Return the DMA GEM object for given framebuffer.

This function will usually be called from the CRTC callback functions.

dma_addr_t drm_fb_dma_get_gem_addr(struct drm_framebuffer *fb, struct drm_plane_state *state, unsigned int plane)

Get DMA (bus) address for framebuffer, for pixel formats where values are grouped in blocks this will get you the beginning of the block

Parameters

struct drm_framebuffer *fb

The framebuffer

struct drm_plane_state *state

Which state of drm plane

unsigned int plane

Which plane Return the DMA GEM address for given framebuffer.

Description

This function will usually be called from the PLANE callback functions.

void drm_fb_dma_sync_non_coherent(struct drm_device *drm, struct drm_plane_state *old_state, struct drm_plane_state *state)

Sync GEM object to non-coherent backing memory

Parameters

struct drm_device *drm

DRM device

struct drm_plane_state *old_state

Old plane state

struct drm_plane_state *state

New plane state

Description

This function can be used by drivers that use damage clips and have DMA GEM objects backed by non-coherent memory. Calling this function in a plane’s .atomic_update ensures that all the data in the backing memory have been written to RAM.

int drm_fb_dma_get_scanout_buffer(struct drm_plane *plane, struct drm_scanout_buffer *sb)

Provide a scanout buffer in case of panic

Parameters

struct drm_plane *plane

DRM primary plane

struct drm_scanout_buffer *sb

scanout buffer for the panic handler

Return

0 or negative error code

Description

Generic get_scanout_buffer() implementation, for drivers that uses the drm_fb_dma_helper. It won’t call vmap in the panic context, so the driver should make sure the primary plane is vmapped, otherwise the panic screen won’t get displayed.

Framebuffer GEM Helper Reference

This library provides helpers for drivers that don’t subclass drm_framebuffer and use drm_gem_object for their backing storage.

Drivers without additional needs to validate framebuffers can simply use drm_gem_fb_create() and everything is wired up automatically. Other drivers can use all parts independently.

struct drm_gem_object *drm_gem_fb_get_obj(struct drm_framebuffer *fb, unsigned int plane)

Get GEM object backing the framebuffer

Parameters

struct drm_framebuffer *fb

Framebuffer

unsigned int plane

Plane index

Description

No additional reference is taken beyond the one that the drm_frambuffer already holds.

Return

Pointer to drm_gem_object for the given framebuffer and plane index or NULL if it does not exist.

void drm_gem_fb_destroy(struct drm_framebuffer *fb)

Free GEM backed framebuffer

Parameters

struct drm_framebuffer *fb

Framebuffer

Description

Frees a GEM backed framebuffer with its backing buffer(s) and the structure itself. Drivers can use this as their drm_framebuffer_funcs->destroy callback.

int drm_gem_fb_create_handle(struct drm_framebuffer *fb, struct drm_file *file, unsigned int *handle)

Create handle for GEM backed framebuffer

Parameters

struct drm_framebuffer *fb

Framebuffer

struct drm_file *file

DRM file to register the handle for

unsigned int *handle

Pointer to return the created handle

Description

This function creates a handle for the GEM object backing the framebuffer. Drivers can use this as their drm_framebuffer_funcs->create_handle callback. The GETFB IOCTL calls into this callback.

Return

0 on success or a negative error code on failure.

int drm_gem_fb_init_with_funcs(struct drm_device *dev, struct drm_framebuffer *fb, struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd, const struct drm_framebuffer_funcs *funcs)

Helper function for implementing drm_mode_config_funcs.fb_create callback in cases when the driver allocates a subclass of struct drm_framebuffer

Parameters

struct drm_device *dev

DRM device

struct drm_framebuffer *fb

framebuffer object

struct drm_file *file

DRM file that holds the GEM handle(s) backing the framebuffer

const struct drm_mode_fb_cmd2 *mode_cmd

Metadata from the userspace framebuffer creation request

const struct drm_framebuffer_funcs *funcs

vtable to be used for the new framebuffer object

Description

This function can be used to set drm_framebuffer_funcs for drivers that need custom framebuffer callbacks. Use drm_gem_fb_create() if you don’t need to change drm_framebuffer_funcs. The function does buffer size validation. The buffer size validation is for a general case, though, so users should pay attention to the checks being appropriate for them or, at least, non-conflicting.

Return

Zero or a negative error code.

struct drm_framebuffer *drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd, const struct drm_framebuffer_funcs *funcs)

Helper function for the drm_mode_config_funcs.fb_create callback

Parameters

struct drm_device *dev

DRM device

struct drm_file *file

DRM file that holds the GEM handle(s) backing the framebuffer

const struct drm_mode_fb_cmd2 *mode_cmd

Metadata from the userspace framebuffer creation request

const struct drm_framebuffer_funcs *funcs

vtable to be used for the new framebuffer object

Description

This function can be used to set drm_framebuffer_funcs for drivers that need custom framebuffer callbacks. Use drm_gem_fb_create() if you don’t need to change drm_framebuffer_funcs. The function does buffer size validation.

Return

Pointer to a drm_framebuffer on success or an error pointer on failure.

struct drm_framebuffer *drm_gem_fb_create(struct drm_device *dev, struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd)

Helper function for the drm_mode_config_funcs.fb_create callback

Parameters

struct drm_device *dev

DRM device

struct drm_file *file

DRM file that holds the GEM handle(s) backing the framebuffer

const struct drm_mode_fb_cmd2 *mode_cmd

Metadata from the userspace framebuffer creation request

Description

This function creates a new framebuffer object described by drm_mode_fb_cmd2. This description includes handles for the buffer(s) backing the framebuffer.

If your hardware has special alignment or pitch requirements these should be checked before calling this function. The function does buffer size validation. Use drm_gem_fb_create_with_dirty() if you need framebuffer flushing.

Drivers can use this as their drm_mode_config_funcs.fb_create callback. The ADDFB2 IOCTL calls into this callback.

Return

Pointer to a drm_framebuffer on success or an error pointer on failure.

struct drm_framebuffer *drm_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd)

Helper function for the drm_mode_config_funcs.fb_create callback

Parameters

struct drm_device *dev

DRM device

struct drm_file *file

DRM file that holds the GEM handle(s) backing the framebuffer

const struct drm_mode_fb_cmd2 *mode_cmd

Metadata from the userspace framebuffer creation request

Description

This function creates a new framebuffer object described by drm_mode_fb_cmd2. This description includes handles for the buffer(s) backing the framebuffer. drm_atomic_helper_dirtyfb() is used for the dirty callback giving framebuffer flushing through the atomic machinery. Use drm_gem_fb_create() if you don’t need the dirty callback. The function does buffer size validation.

Drivers should also call drm_plane_enable_fb_damage_clips() on all planes to enable userspace to use damage clips also with the ATOMIC IOCTL.

Drivers can use this as their drm_mode_config_funcs.fb_create callback. The ADDFB2 IOCTL calls into this callback.

Return

Pointer to a drm_framebuffer on success or an error pointer on failure.

int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct iosys_map *map, struct iosys_map *data)

maps all framebuffer BOs into kernel address space

Parameters

struct drm_framebuffer *fb

the framebuffer

struct iosys_map *map

returns the mapping’s address for each BO

struct iosys_map *data

returns the data address for each BO, can be NULL

Description

This function maps all buffer objects of the given framebuffer into kernel address space and stores them in struct iosys_map. If the mapping operation fails for one of the BOs, the function unmaps the already established mappings automatically.

Callers that want to access a BO’s stored data should pass data. The argument returns the addresses of the data stored in each BO. This is different from map if the framebuffer’s offsets field is non-zero.

Both, map and data, must each refer to arrays with at least fb->format->num_planes elements.

See drm_gem_fb_vunmap() for unmapping.

Return

0 on success, or a negative errno code otherwise.

void drm_gem_fb_vunmap(struct drm_framebuffer *fb, struct iosys_map *map)

unmaps framebuffer BOs from kernel address space

Parameters

struct drm_framebuffer *fb

the framebuffer

struct iosys_map *map

mapping addresses as returned by drm_gem_fb_vmap()

Description

This function unmaps all buffer objects of the given framebuffer.

See drm_gem_fb_vmap() for more information.

int drm_gem_fb_begin_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir)

prepares GEM buffer objects for CPU access

Parameters

struct drm_framebuffer *fb

the framebuffer

enum dma_data_direction dir

access mode

Description

Prepares a framebuffer’s GEM buffer objects for CPU access. This function must be called before accessing the BO data within the kernel. For imported BOs, the function calls dma_buf_begin_cpu_access().

See drm_gem_fb_end_cpu_access() for signalling the end of CPU access.

Return

0 on success, or a negative errno code otherwise.

void drm_gem_fb_end_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir)

signals end of CPU access to GEM buffer objects

Parameters

struct drm_framebuffer *fb

the framebuffer

enum dma_data_direction dir

access mode

Description

Signals the end of CPU access to the given framebuffer’s GEM buffer objects. This function must be paired with a corresponding call to drm_gem_fb_begin_cpu_access(). For imported BOs, the function calls dma_buf_end_cpu_access().

See also drm_gem_fb_begin_cpu_access().

int drm_gem_fb_afbc_init(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_afbc_framebuffer *afbc_fb)

Helper function for drivers using afbc to fill and validate all the afbc-specific struct drm_afbc_framebuffer members

Parameters

struct drm_device *dev

DRM device

const struct drm_mode_fb_cmd2 *mode_cmd

Metadata from the userspace framebuffer creation request

struct drm_afbc_framebuffer *afbc_fb

afbc framebuffer

Description

This function can be used by drivers which support afbc to complete the preparation of struct drm_afbc_framebuffer. It must be called after allocating the said struct and calling drm_gem_fb_init_with_funcs(). It is caller’s responsibility to put afbc_fb->base.obj objects in case the call is unsuccessful.

Return

Zero on success or a negative error value on failure.

Bridges

Overview

struct drm_bridge represents a device that hangs on to an encoder. These are handy when a regular drm_encoder entity isn’t enough to represent the entire encoder chain.

A bridge is always attached to a single drm_encoder at a time, but can be either connected to it directly, or through a chain of bridges:

[ CRTC ---> ] Encoder ---> Bridge A ---> Bridge B

Here, the output of the encoder feeds to bridge A, and that furthers feeds to bridge B. Bridge chains can be arbitrarily long, and shall be fully linear: Chaining multiple bridges to the output of a bridge, or the same bridge to the output of different bridges, is not supported.

drm_bridge, like drm_panel, aren’t drm_mode_object entities like planes, CRTCs, encoders or connectors and hence are not visible to userspace. They just provide additional hooks to get the desired output at the end of the encoder chain.

Display Driver Integration

Display drivers are responsible for linking encoders with the first bridge in the chains. This is done by acquiring the appropriate bridge with devm_drm_of_get_bridge(). Once acquired, the bridge shall be attached to the encoder with a call to drm_bridge_attach().

Bridges are responsible for linking themselves with the next bridge in the chain, if any. This is done the same way as for encoders, with the call to drm_bridge_attach() occurring in the drm_bridge_funcs.attach operation.

Once these links are created, the bridges can participate along with encoder functions to perform mode validation and fixup (through drm_bridge_chain_mode_valid() and drm_atomic_bridge_chain_check()), mode setting (through drm_bridge_chain_mode_set()), enable (through drm_atomic_bridge_chain_pre_enable() and drm_atomic_bridge_chain_enable()) and disable (through drm_atomic_bridge_chain_disable() and drm_atomic_bridge_chain_post_disable()). Those functions call the corresponding operations provided in drm_bridge_funcs in sequence for all bridges in the chain.

For display drivers that use the atomic helpers drm_atomic_helper_check_modeset(), drm_atomic_helper_commit_modeset_enables() and drm_atomic_helper_commit_modeset_disables() (either directly in hand-rolled commit check and commit tail handlers, or through the higher-level drm_atomic_helper_check() and drm_atomic_helper_commit_tail() or drm_atomic_helper_commit_tail_rpm() helpers), this is done transparently and requires no intervention from the driver. For other drivers, the relevant DRM bridge chain functions shall be called manually.

Bridges also participate in implementing the drm_connector at the end of the bridge chain. Display drivers may use the drm_bridge_connector_init() helper to create the drm_connector, or implement it manually on top of the connector-related operations exposed by the bridge (see the overview documentation of bridge operations for more details).

Special Care with MIPI-DSI bridges

The interaction between the bridges and other frameworks involved in the probing of the upstream driver and the bridge driver can be challenging. Indeed, there’s multiple cases that needs to be considered:

  • The upstream driver doesn’t use the component framework and isn’t a MIPI-DSI host. In this case, the bridge driver will probe at some point and the upstream driver should try to probe again by returning EPROBE_DEFER as long as the bridge driver hasn’t probed.

  • The upstream driver doesn’t use the component framework, but is a MIPI-DSI host. The bridge device uses the MIPI-DCS commands to be controlled. In this case, the bridge device is a child of the display device and when it will probe it’s assured that the display device (and MIPI-DSI host) is present. The upstream driver will be assured that the bridge driver is connected between the mipi_dsi_host_ops.attach and mipi_dsi_host_ops.detach operations. Therefore, it must run mipi_dsi_host_register() in its probe function, and then run drm_bridge_attach() in its mipi_dsi_host_ops.attach hook.

  • The upstream driver uses the component framework and is a MIPI-DSI host. The bridge device uses the MIPI-DCS commands to be controlled. This is the same situation than above, and can run mipi_dsi_host_register() in either its probe or bind hooks.

  • The upstream driver uses the component framework and is a MIPI-DSI host. The bridge device uses a separate bus (such as I2C) to be controlled. In this case, there’s no correlation between the probe of the bridge and upstream drivers, so care must be taken to avoid an endless EPROBE_DEFER loop, with each driver waiting for the other to probe.

The ideal pattern to cover the last item (and all the others in the MIPI-DSI host driver case) is to split the operations like this:

  • The MIPI-DSI host driver must run mipi_dsi_host_register() in its probe hook. It will make sure that the MIPI-DSI host sticks around, and that the driver’s bind can be called.

  • In its probe hook, the bridge driver must try to find its MIPI-DSI host, register as a MIPI-DSI device and attach the MIPI-DSI device to its host. The bridge driver is now functional.

  • In its struct mipi_dsi_host_ops.attach hook, the MIPI-DSI host can now add its component. Its bind hook will now be called and since the bridge driver is attached and registered, we can now look for and attach it.

At this point, we’re now certain that both the upstream driver and the bridge driver are functional and we can’t have a deadlock-like situation when probing.

Bridge Operations

Bridge drivers expose operations through the drm_bridge_funcs structure. The DRM internals (atomic and CRTC helpers) use the helpers defined in drm_bridge.c to call bridge operations. Those operations are divided in three big categories to support different parts of the bridge usage.

  • The encoder-related operations support control of the bridges in the chain, and are roughly counterparts to the drm_encoder_helper_funcs operations. They are used by the legacy CRTC and the atomic modeset helpers to perform mode validation, fixup and setting, and enable and disable the bridge automatically.

    The enable and disable operations are split in drm_bridge_funcs.pre_enable, drm_bridge_funcs.enable, drm_bridge_funcs.disable and drm_bridge_funcs.post_disable to provide finer-grained control.

    Bridge drivers may implement the legacy version of those operations, or the atomic version (prefixed with atomic_), in which case they shall also implement the atomic state bookkeeping operations (drm_bridge_funcs.atomic_duplicate_state, drm_bridge_funcs.atomic_destroy_state and drm_bridge_funcs.reset). Mixing atomic and non-atomic versions of the operations is not supported.

  • The bus format negotiation operations drm_bridge_funcs.atomic_get_output_bus_fmts and drm_bridge_funcs.atomic_get_input_bus_fmts allow bridge drivers to negotiate the formats transmitted between bridges in the chain when multiple formats are supported. Negotiation for formats is performed transparently for display drivers by the atomic modeset helpers. Only atomic versions of those operations exist, bridge drivers that need to implement them shall thus also implement the atomic version of the encoder-related operations. This feature is not supported by the legacy CRTC helpers.

  • The connector-related operations support implementing a drm_connector based on a chain of bridges. DRM bridges traditionally create a drm_connector for bridges meant to be used at the end of the chain. This puts additional burden on bridge drivers, especially for bridges that may be used in the middle of a chain or at the end of it. Furthermore, it requires all operations of the drm_connector to be handled by a single bridge, which doesn’t always match the hardware architecture.

    To simplify bridge drivers and make the connector implementation more flexible, a new model allows bridges to unconditionally skip creation of drm_connector and instead expose drm_bridge_funcs operations to support an externally-implemented drm_connector. Those operations are drm_bridge_funcs.detect, drm_bridge_funcs.get_modes, drm_bridge_funcs.get_edid, drm_bridge_funcs.hpd_notify, drm_bridge_funcs.hpd_enable and drm_bridge_funcs.hpd_disable. When implemented, display drivers shall create a drm_connector instance for each chain of bridges, and implement those connector instances based on the bridge connector operations.

    Bridge drivers shall implement the connector-related operations for all the features that the bridge hardware support. For instance, if a bridge supports reading EDID, the drm_bridge_funcs.get_edid shall be implemented. This however doesn’t mean that the DDC lines are wired to the bridge on a particular platform, as they could also be connected to an I2C controller of the SoC. Support for the connector-related operations on the running platform is reported through the drm_bridge.ops flags. Bridge drivers shall detect which operations they can support on the platform (usually this information is provided by ACPI or DT), and set the drm_bridge.ops flags for all supported operations. A flag shall only be set if the corresponding drm_bridge_funcs operation is implemented, but an implemented operation doesn’t necessarily imply that the corresponding flag will be set. Display drivers shall use the drm_bridge.ops flags to decide which bridge to delegate a connector operation to. This mechanism allows providing a single static const drm_bridge_funcs instance in bridge drivers, improving security by storing function pointers in read-only memory.

    In order to ease transition, bridge drivers may support both the old and new models by making connector creation optional and implementing the connected-related bridge operations. Connector creation is then controlled by the flags argument to the drm_bridge_attach() function. Display drivers that support the new model and create connectors themselves shall set the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag, and bridge drivers shall then skip connector creation. For intermediate bridges in the chain, the flag shall be passed to the drm_bridge_attach() call for the downstream bridge. Bridge drivers that implement the new model only shall return an error from their drm_bridge_funcs.attach handler when the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag is not set. New display drivers should use the new model, and convert the bridge drivers they use if needed, in order to gradually transition to the new model.

Bridge Connector Helper

The DRM bridge connector helper object provides a DRM connector implementation that wraps a chain of struct drm_bridge. The connector operations are fully implemented based on the operations of the bridges in the chain, and don’t require any intervention from the display controller driver at runtime.

To use the helper, display controller drivers create a bridge connector with a call to drm_bridge_connector_init(). This associates the newly created connector with the chain of bridges passed to the function and registers it with the DRM device. At that point the connector becomes fully usable, no further operation is needed.

The DRM bridge connector operations are implemented based on the operations provided by the bridges in the chain. Each connector operation is delegated to the bridge closest to the connector (at the end of the chain) that provides the relevant functionality.

To make use of this helper, all bridges in the chain shall report bridge operation flags (drm_bridge->ops) and bridge output type (drm_bridge->type), as well as the DRM_BRIDGE_ATTACH_NO_CONNECTOR attach flag (none of the bridges shall create a DRM connector directly).

Bridge Helper Reference

enum drm_bridge_attach_flags

Flags for drm_bridge_funcs.attach

Constants

DRM_BRIDGE_ATTACH_NO_CONNECTOR

When this flag is set the bridge shall not create a drm_connector.

struct drm_bridge_funcs

drm_bridge control functions

Definition:

struct drm_bridge_funcs {
    int (*attach)(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags);
    void (*detach)(struct drm_bridge *bridge);
    enum drm_mode_status (*mode_valid)(struct drm_bridge *bridge,const struct drm_display_info *info, const struct drm_display_mode *mode);
    bool (*mode_fixup)(struct drm_bridge *bridge,const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode);
    void (*disable)(struct drm_bridge *bridge);
    void (*post_disable)(struct drm_bridge *bridge);
    void (*mode_set)(struct drm_bridge *bridge,const struct drm_display_mode *mode, const struct drm_display_mode *adjusted_mode);
    void (*pre_enable)(struct drm_bridge *bridge);
    void (*enable)(struct drm_bridge *bridge);
    void (*atomic_pre_enable)(struct drm_bridge *bridge, struct drm_bridge_state *old_bridge_state);
    void (*atomic_enable)(struct drm_bridge *bridge, struct drm_bridge_state *old_bridge_state);
    void (*atomic_disable)(struct drm_bridge *bridge, struct drm_bridge_state *old_bridge_state);
    void (*atomic_post_disable)(struct drm_bridge *bridge, struct drm_bridge_state *old_bridge_state);
    struct drm_bridge_state *(*atomic_duplicate_state)(struct drm_bridge *bridge);
    void (*atomic_destroy_state)(struct drm_bridge *bridge, struct drm_bridge_state *state);
    u32 *(*atomic_get_output_bus_fmts)(struct drm_bridge *bridge,struct drm_bridge_state *bridge_state,struct drm_crtc_state *crtc_state,struct drm_connector_state *conn_state, unsigned int *num_output_fmts);
    u32 *(*atomic_get_input_bus_fmts)(struct drm_bridge *bridge,struct drm_bridge_state *bridge_state,struct drm_crtc_state *crtc_state,struct drm_connector_state *conn_state,u32 output_fmt, unsigned int *num_input_fmts);
    int (*atomic_check)(struct drm_bridge *bridge,struct drm_bridge_state *bridge_state,struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state);
    struct drm_bridge_state *(*atomic_reset)(struct drm_bridge *bridge);
    enum drm_connector_status (*detect)(struct drm_bridge *bridge);
    int (*get_modes)(struct drm_bridge *bridge, struct drm_connector *connector);
    const struct drm_edid *(*edid_read)(struct drm_bridge *bridge, struct drm_connector *connector);
    void (*hpd_notify)(struct drm_bridge *bridge, enum drm_connector_status status);
    void (*hpd_enable)(struct drm_bridge *bridge);
    void (*hpd_disable)(struct drm_bridge *bridge);
    enum drm_mode_status(*hdmi_tmds_char_rate_valid)(const struct drm_bridge *bridge,const struct drm_display_mode *mode, unsigned long long tmds_rate);
    int (*hdmi_clear_infoframe)(struct drm_bridge *bridge, enum hdmi_infoframe_type type);
    int (*hdmi_write_infoframe)(struct drm_bridge *bridge,enum hdmi_infoframe_type type, const u8 *buffer, size_t len);
    void (*debugfs_init)(struct drm_bridge *bridge, struct dentry *root);
};

Members

attach

This callback is invoked whenever our bridge is being attached to a drm_encoder. The flags argument tunes the behaviour of the attach operation (see DRM_BRIDGE_ATTACH_*).

The attach callback is optional.

RETURNS:

Zero on success, error code on failure.

detach

This callback is invoked whenever our bridge is being detached from a drm_encoder.

The detach callback is optional.

mode_valid

This callback is used to check if a specific mode is valid in this bridge. This should be implemented if the bridge has some sort of restriction in the modes it can display. For example, a given bridge may be responsible to set a clock value. If the clock can not produce all the values for the available modes then this callback can be used to restrict the number of modes to only the ones that can be displayed.

This hook is used by the probe helpers to filter the mode list in drm_helper_probe_single_connector_modes(), and it is used by the atomic helpers to validate modes supplied by userspace in drm_atomic_helper_check_modeset().

The mode_valid callback is optional.

NOTE:

Since this function is both called from the check phase of an atomic commit, and the mode validation in the probe paths it is not allowed to look at anything else but the passed-in mode, and validate it against configuration-invariant hardware constraints. Any further limits which depend upon the configuration can only be checked in mode_fixup.

RETURNS:

drm_mode_status Enum

mode_fixup

This callback is used to validate and adjust a mode. The parameter mode is the display mode that should be fed to the next element in the display chain, either the final drm_connector or the next drm_bridge. The parameter adjusted_mode is the input mode the bridge requires. It can be modified by this callback and does not need to match mode. See also drm_crtc_state.adjusted_mode for more details.

This is the only hook that allows a bridge to reject a modeset. If this function passes all other callbacks must succeed for this configuration.

The mode_fixup callback is optional. drm_bridge_funcs.mode_fixup() is not called when drm_bridge_funcs.atomic_check() is implemented, so only one of them should be provided.

NOTE:

This function is called in the check 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 beware that userspace can request its own custom modes, neither core nor helpers filter modes to the list of probe modes reported by the GETCONNECTOR IOCTL and stored in drm_connector.modes. To ensure that modes are filtered consistently put any bridge constraints and limits checks into mode_valid.

RETURNS:

True if an acceptable configuration is possible, false if the modeset operation should be rejected.

disable

This callback should disable the bridge. It is called right before the preceding element in the display pipe is disabled. If the preceding element is a bridge this means it’s called before that bridge’s disable vfunc. If the preceding element is a drm_encoder it’s called right before the drm_encoder_helper_funcs.disable, drm_encoder_helper_funcs.prepare or drm_encoder_helper_funcs.dpms hook.

The bridge can assume that the display pipe (i.e. clocks and timing signals) feeding it is still running when this callback is called.

The disable callback is optional.

NOTE:

This is deprecated, do not use! New drivers shall use drm_bridge_funcs.atomic_disable.

post_disable

This callback should disable the bridge. It is called right after the preceding element in the display pipe is disabled. If the preceding element is a bridge this means it’s called after that bridge’s post_disable function. If the preceding element is a drm_encoder it’s called right after the encoder’s drm_encoder_helper_funcs.disable, drm_encoder_helper_funcs.prepare or drm_encoder_helper_funcs.dpms hook.

The bridge must assume that the display pipe (i.e. clocks and timing signals) feeding it is no longer running when this callback is called.

The post_disable callback is optional.

NOTE:

This is deprecated, do not use! New drivers shall use drm_bridge_funcs.atomic_post_disable.

mode_set

This callback should set the given mode on the bridge. It is called after the mode_set callback for the preceding element in the display pipeline has been called already. If the bridge is the first element then this would be drm_encoder_helper_funcs.mode_set. The display pipe (i.e. clocks and timing signals) is off when this function is called.

The adjusted_mode parameter is the mode output by the CRTC for the first bridge in the chain. It can be different from the mode parameter that contains the desired mode for the connector at the end of the bridges chain, for instance when the first bridge in the chain performs scaling. The adjusted mode is mostly useful for the first bridge in the chain and is likely irrelevant for the other bridges.

For atomic drivers the adjusted_mode is the mode stored in drm_crtc_state.adjusted_mode.

NOTE:

This is deprecated, do not use! New drivers shall set their mode in the drm_bridge_funcs.atomic_enable operation.

pre_enable

This callback should enable the bridge. It is called right before the preceding element in the display pipe is enabled. If the preceding element is a bridge this means it’s called before that bridge’s pre_enable function. If the preceding element is a drm_encoder it’s called right before the encoder’s drm_encoder_helper_funcs.enable, drm_encoder_helper_funcs.commit or drm_encoder_helper_funcs.dpms hook.

The display pipe (i.e. clocks and timing signals) feeding this bridge will not yet be running when this callback is called. The bridge must not enable the display link feeding the next bridge in the chain (if there is one) when this callback is called.

The pre_enable callback is optional.

NOTE:

This is deprecated, do not use! New drivers shall use drm_bridge_funcs.atomic_pre_enable.

enable

This callback should enable the bridge. It is called right after the preceding element in the display pipe is enabled. If the preceding element is a bridge this means it’s called after that bridge’s enable function. If the preceding element is a drm_encoder it’s called right after the encoder’s drm_encoder_helper_funcs.enable, drm_encoder_helper_funcs.commit or drm_encoder_helper_funcs.dpms hook.

The bridge can assume that the display pipe (i.e. clocks and timing signals) feeding it is running when this callback is called. This callback must enable the display link feeding the next bridge in the chain if there is one.

The enable callback is optional.

NOTE:

This is deprecated, do not use! New drivers shall use drm_bridge_funcs.atomic_enable.

atomic_pre_enable

This callback should enable the bridge. It is called right before the preceding element in the display pipe is enabled. If the preceding element is a bridge this means it’s called before that bridge’s atomic_pre_enable or pre_enable function. If the preceding element is a drm_encoder it’s called right before the encoder’s drm_encoder_helper_funcs.atomic_enable hook.

The display pipe (i.e. clocks and timing signals) feeding this bridge will not yet be running when this callback is called. The bridge must not enable the display link feeding the next bridge in the chain (if there is one) when this callback is called.

The atomic_pre_enable callback is optional.

atomic_enable

This callback should enable the bridge. It is called right after the preceding element in the display pipe is enabled. If the preceding element is a bridge this means it’s called after that bridge’s atomic_enable or enable function. If the preceding element is a drm_encoder it’s called right after the encoder’s drm_encoder_helper_funcs.atomic_enable hook.

The bridge can assume that the display pipe (i.e. clocks and timing signals) feeding it is running when this callback is called. This callback must enable the display link feeding the next bridge in the chain if there is one.

The atomic_enable callback is optional.

atomic_disable

This callback should disable the bridge. It is called right before the preceding element in the display pipe is disabled. If the preceding element is a bridge this means it’s called before that bridge’s atomic_disable or disable vfunc. If the preceding element is a drm_encoder it’s called right before the drm_encoder_helper_funcs.atomic_disable hook.

The bridge can assume that the display pipe (i.e. clocks and timing signals) feeding it is still running when this callback is called.

The atomic_disable callback is optional.

atomic_post_disable

This callback should disable the bridge. It is called right after the preceding element in the display pipe is disabled. If the preceding element is a bridge this means it’s called after that bridge’s atomic_post_disable or post_disable function. If the preceding element is a drm_encoder it’s called right after the encoder’s drm_encoder_helper_funcs.atomic_disable hook.

The bridge must assume that the display pipe (i.e. clocks and timing signals) feeding it is no longer running when this callback is called.

The atomic_post_disable callback is optional.

atomic_duplicate_state

Duplicate the current bridge state object (which is guaranteed to be non-NULL).

The atomic_duplicate_state hook is mandatory if the bridge implements any of the atomic hooks, and should be left unassigned otherwise. For bridges that don’t subclass drm_bridge_state, the drm_atomic_helper_bridge_duplicate_state() helper function shall be used to implement this hook.

RETURNS: A valid drm_bridge_state object or NULL if the allocation fails.

atomic_destroy_state

Destroy a bridge state object previously allocated by drm_bridge_funcs.atomic_duplicate_state().

The atomic_destroy_state hook is mandatory if the bridge implements any of the atomic hooks, and should be left unassigned otherwise. For bridges that don’t subclass drm_bridge_state, the drm_atomic_helper_bridge_destroy_state() helper function shall be used to implement this hook.

atomic_get_output_bus_fmts

Return the supported bus formats on the output end of a bridge. The returned array must be allocated with kmalloc() and will be freed by the caller. If the allocation fails, NULL should be returned. num_output_fmts must be set to the returned array size. Formats listed in the returned array should be listed in decreasing preference order (the core will try all formats until it finds one that works).

This method is only called on the last element of the bridge chain as part of the bus format negotiation process that happens in drm_atomic_bridge_chain_select_bus_fmts`(). This method is optional. When not implemented, the core will fall back to :c:type:`drm_connector.display_info.bus_formats[0] if drm_connector.display_info.num_bus_formats > 0, or to MEDIA_BUS_FMT_FIXED otherwise.

atomic_get_input_bus_fmts

Return the supported bus formats on the input end of a bridge for a specific output bus format.

The returned array must be allocated with kmalloc() and will be freed by the caller. If the allocation fails, NULL should be returned. num_input_fmts must be set to the returned array size. Formats listed in the returned array should be listed in decreasing preference order (the core will try all formats until it finds one that works). When the format is not supported NULL should be returned and num_input_fmts should be set to 0.

This method is called on all elements of the bridge chain as part of the bus format negotiation process that happens in drm_atomic_bridge_chain_select_bus_fmts(). This method is optional. When not implemented, the core will bypass bus format negotiation on this element of the bridge without failing, and the previous element in the chain will be passed MEDIA_BUS_FMT_FIXED as its output bus format.

Bridge drivers that need to support being linked to bridges that are not supporting bus format negotiation should handle the output_fmt == MEDIA_BUS_FMT_FIXED case appropriately, by selecting a sensible default value or extracting this information from somewhere else (FW property, drm_display_mode, drm_display_info, ...)

Note: Even if input format selection on the first bridge has no impact on the negotiation process (bus format negotiation stops once we reach the first element of the chain), drivers are expected to return accurate input formats as the input format may be used to configure the CRTC output appropriately.

atomic_check

This method is responsible for checking bridge state correctness. It can also check the state of the surrounding components in chain to make sure the whole pipeline can work properly.

drm_bridge_funcs.atomic_check() hooks are called in reverse order (from the last to the first bridge).

This method is optional. drm_bridge_funcs.mode_fixup() is not called when drm_bridge_funcs.atomic_check() is implemented, so only one of them should be provided.

If drivers need to tweak drm_bridge_state.input_bus_cfg.flags or drm_bridge_state.output_bus_cfg.flags it should happen in this function. By default the drm_bridge_state.output_bus_cfg.flags field is set to the next bridge drm_bridge_state.input_bus_cfg.flags value or drm_connector.display_info.bus_flags if the bridge is the last element in the chain.

RETURNS: zero if the check passed, a negative error code otherwise.

atomic_reset

Reset the bridge to a predefined state (or retrieve its current state) and return a drm_bridge_state object matching this state. This function is called at attach time.

The atomic_reset hook is mandatory if the bridge implements any of the atomic hooks, and should be left unassigned otherwise. For bridges that don’t subclass drm_bridge_state, the drm_atomic_helper_bridge_reset() helper function shall be used to implement this hook.

Note that the atomic_reset() semantics is not exactly matching the reset() semantics found on other components (connector, plane, ...).

  1. The reset operation happens when the bridge is attached, not when drm_mode_config_reset() is called

  2. It’s meant to be used exclusively on bridges that have been converted to the ATOMIC API

RETURNS: A valid drm_bridge_state object in case of success, an ERR_PTR() giving the reason of the failure otherwise.

detect

Check if anything is attached to the bridge output.

This callback is optional, if not implemented the bridge will be considered as always having a component attached to its output. Bridges that implement this callback shall set the DRM_BRIDGE_OP_DETECT flag in their drm_bridge->ops.

RETURNS:

drm_connector_status indicating the bridge output status.

get_modes

Fill all modes currently valid for the sink into the drm_connector with drm_mode_probed_add().

The get_modes callback is mostly intended to support non-probeable displays such as many fixed panels. Bridges that support reading EDID shall leave get_modes unimplemented and implement the drm_bridge_funcs->edid_read callback instead.

This callback is optional. Bridges that implement it shall set the DRM_BRIDGE_OP_MODES flag in their drm_bridge->ops.

The connector parameter shall be used for the sole purpose of filling modes, and shall not be stored internally by bridge drivers for future usage.

RETURNS:

The number of modes added by calling drm_mode_probed_add().

edid_read

Read the EDID data of the connected display.

The edid_read callback is the preferred way of reporting mode information for a display connected to the bridge output. Bridges that support reading EDID shall implement this callback and leave the get_modes callback unimplemented.

The caller of this operation shall first verify the output connection status and refrain from reading EDID from a disconnected output.

This callback is optional. Bridges that implement it shall set the DRM_BRIDGE_OP_EDID flag in their drm_bridge->ops.

The connector parameter shall be used for the sole purpose of EDID retrieval, and shall not be stored internally by bridge drivers for future usage.

RETURNS:

An edid structure newly allocated with drm_edid_alloc() or returned from drm_edid_read() family of functions on success, or NULL otherwise. The caller is responsible for freeing the returned edid structure with drm_edid_free().

hpd_notify

Notify the bridge of hot plug detection.

This callback is optional, it may be implemented by bridges that need to be notified of display connection or disconnection for internal reasons. One use case is to reset the internal state of CEC controllers for HDMI bridges.

hpd_enable

Enable hot plug detection. From now on the bridge shall call drm_bridge_hpd_notify() each time a change is detected in the output connection status, until hot plug detection gets disabled with hpd_disable.

This callback is optional and shall only be implemented by bridges that support hot-plug notification without polling. Bridges that implement it shall also implement the hpd_disable callback and set the DRM_BRIDGE_OP_HPD flag in their drm_bridge->ops.

hpd_disable

Disable hot plug detection. Once this function returns the bridge shall not call drm_bridge_hpd_notify() when a change in the output connection status occurs.

This callback is optional and shall only be implemented by bridges that support hot-plug notification without polling. Bridges that implement it shall also implement the hpd_enable callback and set the DRM_BRIDGE_OP_HPD flag in their drm_bridge->ops.

hdmi_tmds_char_rate_valid

Check whether a particular TMDS character rate is supported by the driver.

This callback is optional and should only be implemented by the bridges that take part in the HDMI connector implementation. Bridges that implement it shall set the DRM_BRIDGE_OP_HDMI flag in their drm_bridge->ops.

Returns:

Either drm_mode_status.MODE_OK or one of the failure reasons in enum drm_mode_status.

hdmi_clear_infoframe

This callback clears the infoframes in the hardware during commit. It will be called multiple times, once for every disabled infoframe type.

This callback is optional but it must be implemented by bridges that set the DRM_BRIDGE_OP_HDMI flag in their drm_bridge->ops.

hdmi_write_infoframe

Program the infoframe into the hardware. It will be called multiple times, once for every updated infoframe type.

This callback is optional but it must be implemented by bridges that set the DRM_BRIDGE_OP_HDMI flag in their drm_bridge->ops.

debugfs_init

Allows bridges to create bridge-specific debugfs files.

struct drm_bridge_timings

timing information for the bridge

Definition:

struct drm_bridge_timings {
    u32 input_bus_flags;
    u32 setup_time_ps;
    u32 hold_time_ps;
    bool dual_link;
};

Members

input_bus_flags

Tells what additional settings for the pixel data on the bus this bridge requires (like pixel signal polarity). See also drm_display_info->bus_flags.

setup_time_ps

Defines the time in picoseconds the input data lines must be stable before the clock edge.

hold_time_ps

Defines the time in picoseconds taken for the bridge to sample the input signal after the clock edge.

dual_link

True if the bus operates in dual-link mode. The exact meaning is dependent on the bus type. For LVDS buses, this indicates that even- and odd-numbered pixels are received on separate links.

enum drm_bridge_ops

Bitmask of operations supported by the bridge

Constants

DRM_BRIDGE_OP_DETECT

The bridge can detect displays connected to its output. Bridges that set this flag shall implement the drm_bridge_funcs->detect callback.

DRM_BRIDGE_OP_EDID

The bridge can retrieve the EDID of the display connected to its output. Bridges that set this flag shall implement the drm_bridge_funcs->edid_read callback.

DRM_BRIDGE_OP_HPD

The bridge can detect hot-plug and hot-unplug without requiring polling. Bridges that set this flag shall implement the drm_bridge_funcs->hpd_enable and drm_bridge_funcs->hpd_disable callbacks if they support enabling and disabling hot-plug detection dynamically.

DRM_BRIDGE_OP_MODES

The bridge can retrieve the modes supported by the display at its output. This does not include reading EDID which is separately covered by DRM_BRIDGE_OP_EDID. Bridges that set this flag shall implement the drm_bridge_funcs->get_modes callback.

DRM_BRIDGE_OP_HDMI

The bridge provides HDMI connector operations, including infoframes support. Bridges that set this flag must implement the drm_bridge_funcs->write_infoframe callback.

Note: currently there can be at most one bridge in a chain that sets this bit. This is to simplify corresponding glue code in connector drivers.

struct drm_bridge

central DRM bridge control structure

Definition:

struct drm_bridge {
    struct drm_private_obj base;
    struct drm_device *dev;
    struct drm_encoder *encoder;
    struct list_head chain_node;
    struct device_node *of_node;
    struct list_head list;
    const struct drm_bridge_timings *timings;
    const struct drm_bridge_funcs *funcs;
    void *driver_private;
    enum drm_bridge_ops ops;
    int type;
    bool interlace_allowed;
    bool pre_enable_prev_first;
    struct i2c_adapter *ddc;
    struct mutex hpd_mutex;
    void (*hpd_cb)(void *data, enum drm_connector_status status);
    void *hpd_data;
    const char *vendor;
    const char *product;
    unsigned int supported_formats;
    unsigned int max_bpc;
};

Members

base

inherit from drm_private_object

dev

DRM device this bridge belongs to

encoder

encoder to which this bridge is connected

chain_node

used to form a bridge chain

of_node

device node pointer to the bridge

list

to keep track of all added bridges

timings

the timing specification for the bridge, if any (may be NULL)

funcs

control functions

driver_private

pointer to the bridge driver’s internal context

ops

bitmask of operations supported by the bridge

type

Type of the connection at the bridge output (DRM_MODE_CONNECTOR_*). For bridges at the end of this chain this identifies the type of connected display.

interlace_allowed

Indicate that the bridge can handle interlaced modes.

pre_enable_prev_first

The bridge requires that the prev bridge pre_enable function is called before its pre_enable, and conversely for post_disable. This is most frequently a requirement for DSI devices which need the host to be initialised before the peripheral.

ddc

Associated I2C adapter for DDC access, if any.

hpd_mutex

Protects the hpd_cb and hpd_data fields.

hpd_cb

Hot plug detection callback, registered with drm_bridge_hpd_enable().

hpd_data

Private data passed to the Hot plug detection callback hpd_cb.

vendor

Vendor of the product to be used for the SPD InfoFrame generation. This is required if DRM_BRIDGE_OP_HDMI is set.

product

Name of the product to be used for the SPD InfoFrame generation. This is required if DRM_BRIDGE_OP_HDMI is set.

supported_formats

Bitmask of hdmi_colorspace listing supported output formats. This is only relevant if DRM_BRIDGE_OP_HDMI is set.

max_bpc

Maximum bits per char the HDMI bridge supports. Allowed values are 8, 10 and 12. This is only relevant if DRM_BRIDGE_OP_HDMI is set.

struct drm_bridge *drm_bridge_get_next_bridge(struct drm_bridge *bridge)

Get the next bridge in the chain

Parameters

struct drm_bridge *bridge

bridge object

Return

the next bridge in the chain after bridge, or NULL if bridge is the last.

struct drm_bridge *drm_bridge_get_prev_bridge(struct drm_bridge *bridge)

Get the previous bridge in the chain

Parameters

struct drm_bridge *bridge

bridge object

Return

the previous bridge in the chain, or NULL if bridge is the first.

struct drm_bridge *drm_bridge_chain_get_first_bridge(struct drm_encoder *encoder)

Get the first bridge in the chain

Parameters

struct drm_encoder *encoder

encoder object

Return

the first bridge in the chain, or NULL if encoder has no bridge attached to it.

drm_for_each_bridge_in_chain

drm_for_each_bridge_in_chain (encoder, bridge)

Iterate over all bridges present in a chain

Parameters

encoder

the encoder to iterate bridges on

bridge

a bridge pointer updated to point to the current bridge at each iteration

Description

Iterate over all bridges present in the bridge chain attached to encoder.

void drm_bridge_add(struct drm_bridge *bridge)

add the given bridge to the global bridge list

Parameters

struct drm_bridge *bridge

bridge control structure

int devm_drm_bridge_add(struct device *dev, struct drm_bridge *bridge)

devm managed version of drm_bridge_add()

Parameters

struct device *dev

device to tie the bridge lifetime to

struct drm_bridge *bridge

bridge control structure

Description

This is the managed version of drm_bridge_add() which automatically calls drm_bridge_remove() when dev is unbound.

Return

0 if no error or negative error code.

void drm_bridge_remove(struct drm_bridge *bridge)

remove the given bridge from the global bridge list

Parameters

struct drm_bridge *bridge

bridge control structure

int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, struct drm_bridge *previous, enum drm_bridge_attach_flags flags)

attach the bridge to an encoder’s chain

Parameters

struct drm_encoder *encoder

DRM encoder

struct drm_bridge *bridge

bridge to attach

struct drm_bridge *previous

previous bridge in the chain (optional)

enum drm_bridge_attach_flags flags

DRM_BRIDGE_ATTACH_* flags

Description

Called by a kms driver to link the bridge to an encoder’s chain. The previous argument specifies the previous bridge in the chain. If NULL, the bridge is linked directly at the encoder’s output. Otherwise it is linked at the previous bridge’s output.

If non-NULL the previous bridge must be already attached by a call to this function.

Note that bridges attached to encoders are auto-detached during encoder cleanup in drm_encoder_cleanup(), so drm_bridge_attach() should generally not be balanced with a drm_bridge_detach() in driver code.

Return

Zero on success, error code on failure

enum drm_mode_status drm_bridge_chain_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *info, const struct drm_display_mode *mode)

validate the mode against all bridges in the encoder chain.

Parameters

struct drm_bridge *bridge

bridge control structure

const struct drm_display_info *info

display info against which the mode shall be validated

const struct drm_display_mode *mode

desired mode to be validated

Description

Calls drm_bridge_funcs.mode_valid for all the bridges in the encoder chain, starting from the first bridge to the last. If at least one bridge does not accept the mode the function returns the error code.

Note

the bridge passed should be the one closest to the encoder.

Return

MODE_OK on success, drm_mode_status Enum error code on failure

void drm_bridge_chain_mode_set(struct drm_bridge *bridge, const struct drm_display_mode *mode, const struct drm_display_mode *adjusted_mode)

set proposed mode for all bridges in the encoder chain

Parameters

struct drm_bridge *bridge

bridge control structure

const struct drm_display_mode *mode

desired mode to be set for the encoder chain

const struct drm_display_mode *adjusted_mode

updated mode that works for this encoder chain

Description

Calls drm_bridge_funcs.mode_set op for all the bridges in the encoder chain, starting from the first bridge to the last.

Note

the bridge passed should be the one closest to the encoder

void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge, struct drm_atomic_state *old_state)

disables all bridges in the encoder chain

Parameters

struct drm_bridge *bridge

bridge control structure

struct drm_atomic_state *old_state

old atomic state

Description

Calls drm_bridge_funcs.atomic_disable (falls back on drm_bridge_funcs.disable) op for all the bridges in the encoder chain, starting from the last bridge to the first. These are called before calling drm_encoder_helper_funcs.atomic_disable

Note

the bridge passed should be the one closest to the encoder

void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge, struct drm_atomic_state *old_state)

cleans up after disabling all bridges in the encoder chain

Parameters

struct drm_bridge *bridge

bridge control structure

struct drm_atomic_state *old_state

old atomic state

Description

Calls drm_bridge_funcs.atomic_post_disable (falls back on drm_bridge_funcs.post_disable) op for all the bridges in the encoder chain, starting from the first bridge to the last. These are called after completing drm_encoder_helper_funcs.atomic_disable

If a bridge sets pre_enable_prev_first, then the post_disable for that bridge will be called before the previous one to reverse the pre_enable calling direction.

With pre_enable_prev_first flag enable in Bridge B, D, E then the resulting post_disable order would be, Bridge B, Bridge A, Bridge E, Bridge D, Bridge C.

Example

Bridge A ---> Bridge B ---> Bridge C ---> Bridge D ---> Bridge E

Note

the bridge passed should be the one closest to the encoder

void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge, struct drm_atomic_state *old_state)

prepares for enabling all bridges in the encoder chain

Parameters

struct drm_bridge *bridge

bridge control structure

struct drm_atomic_state *old_state

old atomic state

Description

Calls drm_bridge_funcs.atomic_pre_enable (falls back on drm_bridge_funcs.pre_enable) op for all the bridges in the encoder chain, starting from the last bridge to the first. These are called before calling drm_encoder_helper_funcs.atomic_enable

If a bridge sets pre_enable_prev_first, then the pre_enable for the prev bridge will be called before pre_enable of this bridge.

With pre_enable_prev_first flag enable in Bridge B, D, E then the resulting pre_enable order would be, Bridge C, Bridge D, Bridge E, Bridge A, Bridge B.

Example

Bridge A ---> Bridge B ---> Bridge C ---> Bridge D ---> Bridge E

Note

the bridge passed should be the one closest to the encoder

void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge, struct drm_atomic_state *old_state)

enables all bridges in the encoder chain

Parameters

struct drm_bridge *bridge

bridge control structure

struct drm_atomic_state *old_state

old atomic state

Description

Calls drm_bridge_funcs.atomic_enable (falls back on drm_bridge_funcs.enable) op for all the bridges in the encoder chain, starting from the first bridge to the last. These are called after completing drm_encoder_helper_funcs.atomic_enable

Note

the bridge passed should be the one closest to the encoder

int drm_atomic_bridge_chain_check(struct drm_bridge *bridge, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state)

Do an atomic check on the bridge chain

Parameters

struct drm_bridge *bridge

bridge control structure

struct drm_crtc_state *crtc_state

new CRTC state

struct drm_connector_state *conn_state

new connector state

Description

First trigger a bus format negotiation before calling drm_bridge_funcs.atomic_check() (falls back on drm_bridge_funcs.mode_fixup()) op for all the bridges in the encoder chain, starting from the last bridge to the first. These are called before calling drm_encoder_helper_funcs.atomic_check()

Return

0 on success, a negative error code on failure

enum drm_connector_status drm_bridge_detect(struct drm_bridge *bridge)

check if anything is attached to the bridge output

Parameters

struct drm_bridge *bridge

bridge control structure

Description

If the bridge supports output detection, as reported by the DRM_BRIDGE_OP_DETECT bridge ops flag, call drm_bridge_funcs.detect for the bridge and return the connection status. Otherwise return connector_status_unknown.

Return

The detection status on success, or connector_status_unknown if the bridge doesn’t support output detection.

int drm_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *connector)

fill all modes currently valid for the sink into the connector

Parameters

struct drm_bridge *bridge

bridge control structure

struct drm_connector *connector

the connector to fill with modes

Description

If the bridge supports output modes retrieval, as reported by the DRM_BRIDGE_OP_MODES bridge ops flag, call drm_bridge_funcs.get_modes to fill the connector with all valid modes and return the number of modes added. Otherwise return 0.

Return

The number of modes added to the connector.

const struct drm_edid *drm_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector *connector)

read the EDID data of the connected display

Parameters

struct drm_bridge *bridge

bridge control structure

struct drm_connector *connector

the connector to read EDID for

Description

If the bridge supports output EDID retrieval, as reported by the DRM_BRIDGE_OP_EDID bridge ops flag, call drm_bridge_funcs.edid_read to get the EDID and return it. Otherwise return NULL.

Return

The retrieved EDID on success, or NULL otherwise.

void drm_bridge_hpd_enable(struct drm_bridge *bridge, void (*cb)(void *data, enum drm_connector_status status), void *data)

enable hot plug detection for the bridge

Parameters

struct drm_bridge *bridge

bridge control structure

void (*cb)(void *data, enum drm_connector_status status)

hot-plug detection callback

void *data

data to be passed to the hot-plug detection callback

Description

Call drm_bridge_funcs.hpd_enable if implemented and register the given cb and data as hot plug notification callback. From now on the cb will be called with data when an output status change is detected by the bridge, until hot plug notification gets disabled with drm_bridge_hpd_disable().

Hot plug detection is supported only if the DRM_BRIDGE_OP_HPD flag is set in bridge->ops. This function shall not be called when the flag is not set.

Only one hot plug detection callback can be registered at a time, it is an error to call this function when hot plug detection is already enabled for the bridge.

void drm_bridge_hpd_disable(struct drm_bridge *bridge)

disable hot plug detection for the bridge

Parameters

struct drm_bridge *bridge

bridge control structure

Description

Call drm_bridge_funcs.hpd_disable if implemented and unregister the hot plug detection callback previously registered with drm_bridge_hpd_enable(). Once this function returns the callback will not be called by the bridge when an output status change occurs.

Hot plug detection is supported only if the DRM_BRIDGE_OP_HPD flag is set in bridge->ops. This function shall not be called when the flag is not set.

void drm_bridge_hpd_notify(struct drm_bridge *bridge, enum drm_connector_status status)

notify hot plug detection events

Parameters

struct drm_bridge *bridge

bridge control structure

enum drm_connector_status status

output connection status

Description

Bridge drivers shall call this function to report hot plug events when they detect a change in the output status, when hot plug detection has been enabled by drm_bridge_hpd_enable().

This function shall be called in a context that can sleep.

struct drm_bridge *of_drm_find_bridge(struct device_node *np)

find the bridge corresponding to the device node in the global bridge list

Parameters

struct device_node *np

device node

Return

drm_bridge control struct on success, NULL on failure

MIPI-DSI bridge operation

DSI host interfaces are expected to be implemented as bridges rather than encoders, however there are a few aspects of their operation that need to be defined in order to provide a consistent interface.

A DSI host should keep the PHY powered down until the pre_enable operation is called. All lanes are in an undefined idle state up to this point, and it must not be assumed that it is LP-11. pre_enable should initialise the PHY, set the data lanes to LP-11, and the clock lane to either LP-11 or HS depending on the mode_flag MIPI_DSI_CLOCK_NON_CONTINUOUS.

Ordinarily the downstream bridge DSI peripheral pre_enable will have been called before the DSI host. If the DSI peripheral requires LP-11 and/or the clock lane to be in HS mode prior to pre_enable, then it can set the pre_enable_prev_first flag to request the pre_enable (and post_disable) order to be altered to enable the DSI host first.

Either the CRTC being enabled, or the DSI host enable operation should switch the host to actively transmitting video on the data lanes.

The reverse also applies. The DSI host disable operation or stopping the CRTC should stop transmitting video, and the data lanes should return to the LP-11 state. The DSI host post_disable operation should disable the PHY. If the pre_enable_prev_first flag is set, then the DSI peripheral’s bridge post_disable will be called before the DSI host’s post_disable.

Whilst it is valid to call host_transfer prior to pre_enable or after post_disable, the exact state of the lanes is undefined at this point. The DSI host should initialise the interface, transmit the data, and then disable the interface again.

Ultra Low Power State (ULPS) is not explicitly supported by DRM. If implemented, it therefore needs to be handled entirely within the DSI Host driver.

Bridge Connector Helper Reference

struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, struct drm_encoder *encoder)

Initialise a connector for a chain of bridges

Parameters

struct drm_device *drm

the DRM device

struct drm_encoder *encoder

the encoder where the bridge chain starts

Description

Allocate, initialise and register a drm_bridge_connector with the drm device. The connector is associated with a chain of bridges that starts at the encoder. All bridges in the chain shall report bridge operation flags (drm_bridge->ops) and bridge output type (drm_bridge->type), and none of them may create a DRM connector directly.

Returns a pointer to the new connector on success, or a negative error pointer otherwise.

Panel-Bridge Helper Reference

bool drm_bridge_is_panel(const struct drm_bridge *bridge)

Checks if a drm_bridge is a panel_bridge.

Parameters

const struct drm_bridge *bridge

The drm_bridge to be checked.

Description

Returns true if the bridge is a panel bridge, or false otherwise.

struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel)

Creates a drm_bridge and drm_connector that just calls the appropriate functions from drm_panel.

Parameters

struct drm_panel *panel

The drm_panel being wrapped. Must be non-NULL.

Description

For drivers converting from directly using drm_panel: The expected usage pattern is that during either encoder module probe or DSI host attach, a drm_panel will be looked up through drm_of_find_panel_or_bridge(). drm_panel_bridge_add() is used to wrap that panel in the new bridge, and the result can then be passed to drm_bridge_attach(). The drm_panel_prepare() and related functions can be dropped from the encoder driver (they’re now called by the KMS helpers before calling into the encoder), along with connector creation. When done with the bridge (after drm_mode_config_cleanup() if the bridge has already been attached), then drm_panel_bridge_remove() to free it.

The connector type is set to panel->connector_type, which must be set to a known type. Calling this function with a panel whose connector type is DRM_MODE_CONNECTOR_Unknown will return ERR_PTR(-EINVAL).

See devm_drm_panel_bridge_add() for an automatically managed version of this function.

struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel, u32 connector_type)

Creates a drm_bridge and drm_connector with an explicit connector type.

Parameters

struct drm_panel *panel

The drm_panel being wrapped. Must be non-NULL.

u32 connector_type

The connector type (DRM_MODE_CONNECTOR_*)

Description

This is just like drm_panel_bridge_add(), but forces the connector type to connector_type instead of infering it from the panel.

This function is deprecated and should not be used in new drivers. Use drm_panel_bridge_add() instead, and fix panel drivers as necessary if they don’t report a connector type.

void drm_panel_bridge_remove(struct drm_bridge *bridge)

Unregisters and frees a drm_bridge created by drm_panel_bridge_add().

Parameters

struct drm_bridge *bridge

The drm_bridge being freed.

int drm_panel_bridge_set_orientation(struct drm_connector *connector, struct drm_bridge *bridge)

Set the connector’s panel orientation from the bridge that can be transformed to panel bridge.

Parameters

struct drm_connector *connector

The connector to be set panel orientation.

struct drm_bridge *bridge

The drm_bridge to be transformed to panel bridge.

Description

Returns 0 on success, negative errno on failure.

struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev, struct drm_panel *panel)

Creates a managed drm_bridge and drm_connector that just calls the appropriate functions from drm_panel.

Parameters

struct device *dev

device to tie the bridge lifetime to

struct drm_panel *panel

The drm_panel being wrapped. Must be non-NULL.

Description

This is the managed version of drm_panel_bridge_add() which automatically calls drm_panel_bridge_remove() when dev is unbound.

struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev, struct drm_panel *panel, u32 connector_type)

Creates a managed drm_bridge and drm_connector with an explicit connector type.

Parameters

struct device *dev

device to tie the bridge lifetime to

struct drm_panel *panel

The drm_panel being wrapped. Must be non-NULL.

u32 connector_type

The connector type (DRM_MODE_CONNECTOR_*)

Description

This is just like devm_drm_panel_bridge_add(), but forces the connector type to connector_type instead of infering it from the panel.

This function is deprecated and should not be used in new drivers. Use devm_drm_panel_bridge_add() instead, and fix panel drivers as necessary if they don’t report a connector type.

struct drm_bridge *drmm_panel_bridge_add(struct drm_device *drm, struct drm_panel *panel)

Creates a DRM-managed drm_bridge and drm_connector that just calls the appropriate functions from drm_panel.

Parameters

struct drm_device *drm

DRM device to tie the bridge lifetime to

struct drm_panel *panel

The drm_panel being wrapped. Must be non-NULL.

Description

This is the DRM-managed version of drm_panel_bridge_add() which automatically calls drm_panel_bridge_remove() when dev is cleaned up.

struct drm_connector *drm_panel_bridge_connector(struct drm_bridge *bridge)

return the connector for the panel bridge

Parameters

struct drm_bridge *bridge

The drm_bridge.

Description

drm_panel_bridge creates the connector. This function gives external access to the connector.

Return

Pointer to drm_connector

struct drm_bridge *devm_drm_of_get_bridge(struct device *dev, struct device_node *np, u32 port, u32 endpoint)

Return next bridge in the chain

Parameters

struct device *dev

device to tie the bridge lifetime to

struct device_node *np

device tree node containing encoder output ports

u32 port

port in the device tree node

u32 endpoint

endpoint in the device tree node

Description

Given a DT node’s port and endpoint number, finds the connected node and returns the associated bridge if any, or creates and returns a drm panel bridge instance if a panel is connected.

Returns a pointer to the bridge if successful, or an error pointer otherwise.

struct drm_bridge *drmm_of_get_bridge(struct drm_device *drm, struct device_node *np, u32 port, u32 endpoint)

Return next bridge in the chain

Parameters

struct drm_device *drm

device to tie the bridge lifetime to

struct device_node *np

device tree node containing encoder output ports

u32 port

port in the device tree node

u32 endpoint

endpoint in the device tree node

Description

Given a DT node’s port and endpoint number, finds the connected node and returns the associated bridge if any, or creates and returns a drm panel bridge instance if a panel is connected.

Returns a drmm managed pointer to the bridge if successful, or an error pointer otherwise.

Panel Helper Reference

The DRM panel helpers allow drivers to register panel objects with a central registry and provide functions to retrieve those panels in display drivers.

For easy integration into drivers using the drm_bridge infrastructure please take look at drm_panel_bridge_add() and devm_drm_panel_bridge_add().

struct drm_panel_funcs

perform operations on a given panel

Definition:

struct drm_panel_funcs {
    int (*prepare)(struct drm_panel *panel);
    int (*enable)(struct drm_panel *panel);
    int (*disable)(struct drm_panel *panel);
    int (*unprepare)(struct drm_panel *panel);
    int (*get_modes)(struct drm_panel *panel, struct drm_connector *connector);
    enum drm_panel_orientation (*get_orientation)(struct drm_panel *panel);
    int (*get_timings)(struct drm_panel *panel, unsigned int num_timings, struct display_timing *timings);
    void (*debugfs_init)(struct drm_panel *panel, struct dentry *root);
};

Members

prepare

Turn on panel and perform set up.

This function is optional.

enable

Enable panel (turn on back light, etc.).

This function is optional.

disable

Disable panel (turn off back light, etc.).

This function is optional.

unprepare

Turn off panel.

This function is optional.

get_modes

Add modes to the connector that the panel is attached to and returns the number of modes added.

This function is mandatory.

get_orientation

Return the panel orientation set by device tree or EDID.

This function is optional.

get_timings

Copy display timings into the provided array and return the number of display timings available.

This function is optional.

debugfs_init

Allows panels to create panels-specific debugfs files.

Description

The .prepare() function is typically called before the display controller starts to transmit video data. Panel drivers can use this to turn the panel on and wait for it to become ready. If additional configuration is required (via a control bus such as I2C, SPI or DSI for example) this is a good time to do that.

After the display controller has started transmitting video data, it’s safe to call the .enable() function. This will typically enable the backlight to make the image on screen visible. Some panels require a certain amount of time or frames before the image is displayed. This function is responsible for taking this into account before enabling the backlight to avoid visual glitches.

Before stopping video transmission from the display controller it can be necessary to turn off the panel to avoid visual glitches. This is done in the .disable() function. Analogously to .enable() this typically involves turning off the backlight and waiting for some time to make sure no image is visible on the panel. It is then safe for the display controller to cease transmission of video data.

To save power when no video data is transmitted, a driver can power down the panel. This is the job of the .unprepare() function.

Backlight can be handled automatically if configured using drm_panel_of_backlight() or drm_panel_dp_aux_backlight(). Then the driver does not need to implement the functionality to enable/disable backlight.

struct drm_panel

DRM panel object

Definition:

struct drm_panel {
    struct device *dev;
    struct backlight_device *backlight;
    const struct drm_panel_funcs *funcs;
    int connector_type;
    struct list_head list;
    struct list_head followers;
    struct mutex follower_lock;
    bool prepare_prev_first;
    bool prepared;
    bool enabled;
};

Members

dev

Parent device of the panel.

backlight

Backlight device, used to turn on backlight after the call to enable(), and to turn off backlight before the call to disable(). backlight is set by drm_panel_of_backlight() or drm_panel_dp_aux_backlight() and drivers shall not assign it.

funcs

Operations that can be performed on the panel.

connector_type

Type of the panel as a DRM_MODE_CONNECTOR_* value. This is used to initialise the drm_connector corresponding to the panel with the correct connector type.

list

Panel entry in registry.

followers

A list of struct drm_panel_follower dependent on this panel.

follower_lock

Lock for followers list.

prepare_prev_first

The previous controller should be prepared first, before the prepare for the panel is called. This is largely required for DSI panels where the DSI host controller should be initialised to LP-11 before the panel is powered up.

prepared

If true then the panel has been prepared.

enabled

If true then the panel has been enabled.

void drm_panel_init(struct drm_panel *panel, struct device *dev, const struct drm_panel_funcs *funcs, int connector_type)

initialize a panel

Parameters

struct drm_panel *panel

DRM panel

struct device *dev

parent device of the panel

const struct drm_panel_funcs *funcs

panel operations

int connector_type

the connector type (DRM_MODE_CONNECTOR_*) corresponding to the panel interface

Description

Initialize the panel structure for subsequent registration with drm_panel_add().

void drm_panel_add(struct drm_panel *panel)

add a panel to the global registry

Parameters

struct drm_panel *panel

panel to add

Description

Add a panel to the global registry so that it can be looked up by display drivers.

void drm_panel_remove(struct drm_panel *panel)

remove a panel from the global registry

Parameters

struct drm_panel *panel

DRM panel

Description

Removes a panel from the global registry.

int drm_panel_prepare(struct drm_panel *panel)

power on a panel

Parameters

struct drm_panel *panel

DRM panel

Description

Calling this function will enable power and deassert any reset signals to the panel. After this has completed it is possible to communicate with any integrated circuitry via a command bus.

Return

0 on success or a negative error code on failure.

int drm_panel_unprepare(struct drm_panel *panel)

power off a panel

Parameters

struct drm_panel *panel

DRM panel

Description

Calling this function will completely power off a panel (assert the panel’s reset, turn off power supplies, ...). After this function has completed, it is usually no longer possible to communicate with the panel until another call to drm_panel_prepare().

Return

0 on success or a negative error code on failure.

int drm_panel_enable(struct drm_panel *panel)

enable a panel

Parameters

struct drm_panel *panel

DRM panel

Description

Calling this function will cause the panel display drivers to be turned on and the backlight to be enabled. Content will be visible on screen after this call completes.

Return

0 on success or a negative error code on failure.

int drm_panel_disable(struct drm_panel *panel)

disable a panel

Parameters

struct drm_panel *panel

DRM panel

Description

This will typically turn off the panel’s backlight or disable the display drivers. For smart panels it should still be possible to communicate with the integrated circuitry via any command bus after this call.

Return

0 on success or a negative error code on failure.

int drm_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector)

probe the available display modes of a panel

Parameters

struct drm_panel *panel

DRM panel

struct drm_connector *connector

DRM connector

Description

The modes probed from the panel are automatically added to the connector that the panel is attached to.

Return

The number of modes available from the panel on success, or 0 on failure (no modes).

struct drm_panel *of_drm_find_panel(const struct device_node *np)

look up a panel using a device tree node

Parameters

const struct device_node *np

device tree node of the panel

Description

Searches the set of registered panels for one that matches the given device tree node. If a matching panel is found, return a pointer to it.

Possible error codes returned by this function:

  • EPROBE_DEFER: the panel device has not been probed yet, and the caller should retry later

  • ENODEV: the device is not available (status != “okay” or “ok”)

Return

A pointer to the panel registered for the specified device tree node or an ERR_PTR() if no panel matching the device tree node can be found.

int of_drm_get_panel_orientation(const struct device_node *np, enum drm_panel_orientation *orientation)

look up the orientation of the panel through the “rotation” binding from a device tree node

Parameters

const struct device_node *np

device tree node of the panel

enum drm_panel_orientation *orientation

orientation enum to be filled in

Description

Looks up the rotation of a panel in the device tree. The orientation of the panel is expressed as a property name “rotation” in the device tree. The rotation in the device tree is counter clockwise.

Return

0 when a valid rotation value (0, 90, 180, or 270) is read or the rotation property doesn’t exist. Return a negative error code on failure.

bool drm_is_panel_follower(struct device *dev)

Check if the device is a panel follower

Parameters

struct device *dev

The ‘struct device’ to check

Description

This checks to see if a device needs to be power sequenced together with a panel using the panel follower API. At the moment panels can only be followed on device tree enabled systems. The “panel” property of the follower points to the panel to be followed.

Return

true if we should be power sequenced with a panel; false otherwise.

int drm_panel_add_follower(struct device *follower_dev, struct drm_panel_follower *follower)

Register something to follow panel state.

Parameters

struct device *follower_dev

The ‘struct device’ for the follower.

struct drm_panel_follower *follower

The panel follower descriptor for the follower.

Description

A panel follower is called right after preparing the panel and right before unpreparing the panel. It’s primary intention is to power on an associated touchscreen, though it could be used for any similar devices. Multiple devices are allowed the follow the same panel.

If a follower is added to a panel that’s already been turned on, the follower’s prepare callback is called right away.

At the moment panels can only be followed on device tree enabled systems. The “panel” property of the follower points to the panel to be followed.

Return

0 or an error code. Note that -ENODEV means that we detected that

follower_dev is not actually following a panel. The caller may choose to ignore this return value if following a panel is optional.

void drm_panel_remove_follower(struct drm_panel_follower *follower)

Reverse drm_panel_add_follower().

Parameters

struct drm_panel_follower *follower

The panel follower descriptor for the follower.

Description

Undo drm_panel_add_follower(). This includes calling the follower’s unprepare function if we’re removed from a panel that’s currently prepared.

Return

0 or an error code.

int devm_drm_panel_add_follower(struct device *follower_dev, struct drm_panel_follower *follower)

devm version of drm_panel_add_follower()

Parameters

struct device *follower_dev

The ‘struct device’ for the follower.

struct drm_panel_follower *follower

The panel follower descriptor for the follower.

Description

Handles calling drm_panel_remove_follower() using devm on the follower_dev.

Return

0 or an error code.

int drm_panel_of_backlight(struct drm_panel *panel)

use backlight device node for backlight

Parameters

struct drm_panel *panel

DRM panel

Description

Use this function to enable backlight handling if your panel uses device tree and has a backlight phandle.

When the panel is enabled backlight will be enabled after a successful call to drm_panel_funcs.enable()

When the panel is disabled backlight will be disabled before the call to drm_panel_funcs.disable().

A typical implementation for a panel driver supporting device tree will call this function at probe time. Backlight will then be handled transparently without requiring any intervention from the driver. drm_panel_of_backlight() must be called after the call to drm_panel_init().

Return

0 on success or a negative error code on failure.

int drm_get_panel_orientation_quirk(int width, int height)

Check for panel orientation quirks

Parameters

int width

width in pixels of the panel

int height

height in pixels of the panel

Description

This function checks for platform specific (e.g. DMI based) quirks providing info on panel_orientation for systems where this cannot be probed from the hard-/firm-ware. To avoid false-positive this function takes the panel resolution as argument and checks that against the resolution expected by the quirk-table entry.

Note this function is also used outside of the drm-subsys, by for example the efifb code. Because of this this function gets compiled into its own kernel-module when built as a module.

Return

A DRM_MODE_PANEL_ORIENTATION_* value if there is a quirk for this system, or DRM_MODE_PANEL_ORIENTATION_UNKNOWN if there is no quirk.

Panel Self Refresh Helper Reference

This helper library provides an easy way for drivers to leverage the atomic framework to implement panel self refresh (SR) support. Drivers are responsible for initializing and cleaning up the SR helpers on load/unload (see drm_self_refresh_helper_init/drm_self_refresh_helper_cleanup). The connector is responsible for setting drm_connector_state.self_refresh_aware to true at runtime if it is SR-aware (meaning it knows how to initiate self refresh on the panel).

Once a crtc has enabled SR using drm_self_refresh_helper_init, the helpers will monitor activity and call back into the driver to enable/disable SR as appropriate. The best way to think about this is that it’s a DPMS on/off request with drm_crtc_state.self_refresh_active set in crtc state that tells you to disable/enable SR on the panel instead of power-cycling it.

During SR, drivers may choose to fully disable their crtc/encoder/bridge hardware (in which case no driver changes are necessary), or they can inspect drm_crtc_state.self_refresh_active if they want to enter low power mode without full disable (in case full disable/enable is too slow).

SR will be deactivated if there are any atomic updates affecting the pipe that is in SR mode. If a crtc is driving multiple connectors, all connectors must be SR aware and all will enter/exit SR mode at the same time.

If the crtc and connector are SR aware, but the panel connected does not support it (or is otherwise unable to enter SR), the driver should fail atomic_check when drm_crtc_state.self_refresh_active is true.

void drm_self_refresh_helper_update_avg_times(struct drm_atomic_state *state, unsigned int commit_time_ms, unsigned int new_self_refresh_mask)

Updates a crtc’s SR time averages

Parameters

struct drm_atomic_state *state

the state which has just been applied to hardware

unsigned int commit_time_ms

the amount of time in ms that this commit took to complete

unsigned int new_self_refresh_mask

bitmask of crtc’s that have self_refresh_active in new state

Description

Called after drm_mode_config_funcs.atomic_commit_tail, this function will update the average entry/exit self refresh times on self refresh transitions. These averages will be used when calculating how long to delay before entering self refresh mode after activity.

void drm_self_refresh_helper_alter_state(struct drm_atomic_state *state)

Alters the atomic state for SR exit

Parameters

struct drm_atomic_state *state

the state currently being checked

Description

Called at the end of atomic check. This function checks the state for flags incompatible with self refresh exit and changes them. This is a bit disingenuous since userspace is expecting one thing and we’re giving it another. However in order to keep self refresh entirely hidden from userspace, this is required.

At the end, we queue up the self refresh entry work so we can enter PSR after the desired delay.

int drm_self_refresh_helper_init(struct drm_crtc *crtc)

Initializes self refresh helpers for a crtc

Parameters

struct drm_crtc *crtc

the crtc which supports self refresh supported displays

Description

Returns zero if successful or -errno on failure

void drm_self_refresh_helper_cleanup(struct drm_crtc *crtc)

Cleans up self refresh helpers for a crtc

Parameters

struct drm_crtc *crtc

the crtc to cleanup

HDCP Helper Functions Reference

int drm_hdcp_check_ksvs_revoked(struct drm_device *drm_dev, u8 *ksvs, u32 ksv_count)

Check the revoked status of the IDs

Parameters

struct drm_device *drm_dev

drm_device for which HDCP revocation check is requested

u8 *ksvs

List of KSVs (HDCP receiver IDs)

u32 ksv_count

KSV count passed in through ksvs

Description

This function reads the HDCP System renewability Message(SRM Table) from userspace as a firmware and parses it for the revoked HDCP KSVs(Receiver IDs) detected by DCP LLC. Once the revoked KSVs are known, revoked state of the KSVs in the list passed in by display drivers are decided and response is sent.

SRM should be presented in the name of “display_hdcp_srm.bin”.

Format of the SRM table, that userspace needs to write into the binary file, is defined at: 1. Renewability chapter on 55th page of HDCP 1.4 specification https://www.digital-cp.com/sites/default/files/specifications/HDCP``20Specification````20Rev1_4_Secure``.pdf 2. Renewability chapter on 63rd page of HDCP 2.2 specification https://www.digital-cp.com/sites/default/files/specifications/HDCP``20on````20HDMI````20Specification````20Rev2_2_Final1``.pdf

Return

Count of the revoked KSVs or -ve error number in case of the failure.

int drm_connector_attach_content_protection_property(struct drm_connector *connector, bool hdcp_content_type)

attach content protection property

Parameters

struct drm_connector *connector

connector to attach CP property on.

bool hdcp_content_type

is HDCP Content Type property needed for connector

Description

This is used to add support for content protection on select connectors. Content Protection is intentionally vague to allow for different underlying technologies, however it is most implemented by HDCP.

When hdcp_content_type is true enum property called HDCP Content Type is created (if it is not already) and attached to the connector.

This property is used for sending the protected content’s stream type from userspace to kernel on selected connectors. Protected content provider will decide their type of their content and declare the same to kernel.

Content type will be used during the HDCP 2.2 authentication. Content type will be set to drm_connector_state.hdcp_content_type.

The content protection will be set to drm_connector_state.content_protection

When kernel triggered content protection state change like DESIRED->ENABLED and ENABLED->DESIRED, will use drm_hdcp_update_content_protection() to update the content protection state of a connector.

Return

Zero on success, negative errno on failure.

void drm_hdcp_update_content_protection(struct drm_connector *connector, u64 val)

Updates the content protection state of a connector

Parameters

struct drm_connector *connector

drm_connector on which content protection state needs an update

u64 val

New state of the content protection property

Description

This function can be used by display drivers, to update the kernel triggered content protection state changes of a drm_connector such as DESIRED->ENABLED and ENABLED->DESIRED. No uevent for DESIRED->UNDESIRED or ENABLED->UNDESIRED, as userspace is triggering such state change and kernel performs it without fail.This function update the new state of the property into the connector’s state and generate an uevent to notify the userspace.

Display Port Helper Functions Reference

These functions contain some common logic and helpers at various abstraction levels to deal with Display Port sink devices and related things like DP aux channel transfers, EDID reading over DP aux channels, decoding certain DPCD blocks, ...

The DisplayPort AUX channel is an abstraction to allow generic, driver- independent access to AUX functionality. Drivers can take advantage of this by filling in the fields of the drm_dp_aux structure.

Transactions are described using a hardware-independent drm_dp_aux_msg structure, which is passed into a driver’s .transfer() implementation. Both native and I2C-over-AUX transactions are supported.

struct dp_sdp_header

DP secondary data packet header

Definition:

struct dp_sdp_header {
    u8 HB0;
    u8 HB1;
    u8 HB2;
    u8 HB3;
};

Members

HB0

Secondary Data Packet ID

HB1

Secondary Data Packet Type

HB2

Secondary Data Packet Specific header, Byte 0

HB3

Secondary Data packet Specific header, Byte 1

struct dp_sdp

DP secondary data packet

Definition:

struct dp_sdp {
    struct dp_sdp_header sdp_header;
    u8 db[32];
};

Members

sdp_header

DP secondary data packet header

db

DP secondaray data packet data blocks VSC SDP Payload for PSR db[0]: Stereo Interface db[1]: 0 - PSR State; 1 - Update RFB; 2 - CRC Valid db[2]: CRC value bits 7:0 of the R or Cr component db[3]: CRC value bits 15:8 of the R or Cr component db[4]: CRC value bits 7:0 of the G or Y component db[5]: CRC value bits 15:8 of the G or Y component db[6]: CRC value bits 7:0 of the B or Cb component db[7]: CRC value bits 15:8 of the B or Cb component db[8] - db[31]: Reserved VSC SDP Payload for Pixel Encoding/Colorimetry Format db[0] - db[15]: Reserved db[16]: Pixel Encoding and Colorimetry Formats db[17]: Dynamic Range and Component Bit Depth db[18]: Content Type db[19] - db[31]: Reserved

enum dp_pixelformat

drm DP Pixel encoding formats

Constants

DP_PIXELFORMAT_RGB

RGB pixel encoding format

DP_PIXELFORMAT_YUV444

YCbCr 4:4:4 pixel encoding format

DP_PIXELFORMAT_YUV422

YCbCr 4:2:2 pixel encoding format

DP_PIXELFORMAT_YUV420

YCbCr 4:2:0 pixel encoding format

DP_PIXELFORMAT_Y_ONLY

Y Only pixel encoding format

DP_PIXELFORMAT_RAW

RAW pixel encoding format

DP_PIXELFORMAT_RESERVED

Reserved pixel encoding format

Description

This enum is used to indicate DP VSC SDP Pixel encoding formats. It is based on DP 1.4 spec [Table 2-117: VSC SDP Payload for DB16 through DB18]

enum dp_colorimetry

drm DP Colorimetry formats

Constants

DP_COLORIMETRY_DEFAULT

sRGB (IEC 61966-2-1) or ITU-R BT.601 colorimetry format

DP_COLORIMETRY_RGB_WIDE_FIXED

RGB wide gamut fixed point colorimetry format

DP_COLORIMETRY_BT709_YCC

ITU-R BT.709 colorimetry format

DP_COLORIMETRY_RGB_WIDE_FLOAT

RGB wide gamut floating point (scRGB (IEC 61966-2-2)) colorimetry format

DP_COLORIMETRY_XVYCC_601

xvYCC601 colorimetry format

DP_COLORIMETRY_OPRGB

OpRGB colorimetry format

DP_COLORIMETRY_XVYCC_709

xvYCC709 colorimetry format

DP_COLORIMETRY_DCI_P3_RGB

DCI-P3 (SMPTE RP 431-2) colorimetry format

DP_COLORIMETRY_SYCC_601

sYCC601 colorimetry format

DP_COLORIMETRY_RGB_CUSTOM

RGB Custom Color Profile colorimetry format

DP_COLORIMETRY_OPYCC_601

opYCC601 colorimetry format

DP_COLORIMETRY_BT2020_RGB

ITU-R BT.2020 R’ G’ B’ colorimetry format

DP_COLORIMETRY_BT2020_CYCC

ITU-R BT.2020 Y’c C’bc C’rc colorimetry format

DP_COLORIMETRY_BT2020_YCC

ITU-R BT.2020 Y’ C’b C’r colorimetry format

Description

This enum is used to indicate DP VSC SDP Colorimetry formats. It is based on DP 1.4 spec [Table 2-117: VSC SDP Payload for DB16 through DB18] and a name of enum member follows enum drm_colorimetry definition.

enum dp_dynamic_range

drm DP Dynamic Range

Constants

DP_DYNAMIC_RANGE_VESA

VESA range

DP_DYNAMIC_RANGE_CTA

CTA range

Description

This enum is used to indicate DP VSC SDP Dynamic Range. It is based on DP 1.4 spec [Table 2-117: VSC SDP Payload for DB16 through DB18]

enum dp_content_type

drm DP Content Type

Constants

DP_CONTENT_TYPE_NOT_DEFINED

Not defined type

DP_CONTENT_TYPE_GRAPHICS

Graphics type

DP_CONTENT_TYPE_PHOTO

Photo type

DP_CONTENT_TYPE_VIDEO

Video type

DP_CONTENT_TYPE_GAME

Game type

Description

This enum is used to indicate DP VSC SDP Content Types. It is based on DP 1.4 spec [Table 2-117: VSC SDP Payload for DB16 through DB18] CTA-861-G defines content types and expected processing by a sink device

struct drm_dp_vsc_sdp

drm DP VSC SDP

Definition:

struct drm_dp_vsc_sdp {
    unsigned char sdp_type;
    unsigned char revision;
    unsigned char length;
    enum dp_pixelformat pixelformat;
    enum dp_colorimetry colorimetry;
    int bpc;
    enum dp_dynamic_range dynamic_range;
    enum dp_content_type content_type;
};

Members

sdp_type

secondary-data packet type

revision

revision number

length

number of valid data bytes

pixelformat

pixel encoding format

colorimetry

colorimetry format

bpc

bit per color

dynamic_range

dynamic range information

content_type

CTA-861-G defines content types and expected processing by a sink device

Description

This structure represents a DP VSC SDP of drm It is based on DP 1.4 spec [Table 2-116: VSC SDP Header Bytes] and [Table 2-117: VSC SDP Payload for DB16 through DB18]

struct drm_dp_as_sdp

drm DP Adaptive Sync SDP

Definition:

struct drm_dp_as_sdp {
    unsigned char sdp_type;
    unsigned char revision;
    unsigned char length;
    int vtotal;
    int target_rr;
    int duration_incr_ms;
    int duration_decr_ms;
    bool target_rr_divider;
    enum operation_mode mode;
};

Members

sdp_type

Secondary-data packet type

revision

Revision Number

length

Number of valid data bytes

vtotal

Minimum Vertical Vtotal

target_rr

Target Refresh

duration_incr_ms

Successive frame duration increase

duration_decr_ms

Successive frame duration decrease

target_rr_divider

Target refresh rate divider

mode

Adaptive Sync Operation Mode

Description

This structure represents a DP AS SDP of drm It is based on DP 2.1 spec [Table 2-126: Adaptive-Sync SDP Header Bytes] and [Table 2-127: Adaptive-Sync SDP Payload for DB0 through DB8]

bool drm_dp_dsc_sink_supports_format(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], u8 output_format)

check if sink supports DSC with given output format

Parameters

const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]

DSC-capability DPCDs of the sink

u8 output_format

output_format which is to be checked

Description

Returns true if the sink supports DSC with the given output_format, false otherwise.

bool drm_edp_backlight_supported(const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE])

Check an eDP DPCD for VESA backlight support

Parameters

const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]

The DPCD to check

Description

Note that currently this function will return false for panels which support various DPCD backlight features but which require the brightness be set through PWM, and don’t support setting the brightness level via the DPCD.

Return

True if edp_dpcd indicates that VESA backlight controls are supported, false otherwise

bool drm_dp_is_uhbr_rate(int link_rate)

Determine if a link rate is UHBR

Parameters

int link_rate

link rate in 10kbits/s units

Description

Determine if the provided link rate is an UHBR rate.

Return

True if link_rate is an UHBR rate.

struct drm_dp_aux_msg

DisplayPort AUX channel transaction

Definition:

struct drm_dp_aux_msg {
    unsigned int address;
    u8 request;
    u8 reply;
    void *buffer;
    size_t size;
};

Members

address

address of the (first) register to access

request

contains the type of transaction (see DP_AUX_* macros)

reply

upon completion, contains the reply type of the transaction

buffer

pointer to a transmission or reception buffer

size

size of buffer

struct drm_dp_aux_cec

DisplayPort CEC-Tunneling-over-AUX

Definition:

struct drm_dp_aux_cec {
    struct mutex lock;
    struct cec_adapter *adap;
    struct drm_connector *connector;
    struct delayed_work unregister_work;
};

Members

lock

mutex protecting this struct

adap

the CEC adapter for CEC-Tunneling-over-AUX support.

connector

the connector this CEC adapter is associated with

unregister_work

unregister the CEC adapter

struct drm_dp_aux

DisplayPort AUX channel

Definition:

struct drm_dp_aux {
    const char *name;
    struct i2c_adapter ddc;
    struct device *dev;
    struct drm_device *drm_dev;
    struct drm_crtc *crtc;
    struct mutex hw_mutex;
    struct work_struct crc_work;
    u8 crc_count;
    ssize_t (*transfer)(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg);
    int (*wait_hpd_asserted)(struct drm_dp_aux *aux, unsigned long wait_us);
    unsigned i2c_nack_count;
    unsigned i2c_defer_count;
    struct drm_dp_aux_cec cec;
    bool is_remote;
    bool powered_down;
};

Members

name

user-visible name of this AUX channel and the I2C-over-AUX adapter.

It’s also used to specify the name of the I2C adapter. If set to NULL, dev_name() of dev will be used.

ddc

I2C adapter that can be used for I2C-over-AUX communication

dev

pointer to struct device that is the parent for this AUX channel.

drm_dev

pointer to the drm_device that owns this AUX channel. Beware, this may be NULL before drm_dp_aux_register() has been called.

It should be set to the drm_device that will be using this AUX channel as early as possible. For many graphics drivers this should happen before drm_dp_aux_init(), however it’s perfectly fine to set this field later so long as it’s assigned before calling drm_dp_aux_register().

crtc

backpointer to the crtc that is currently using this AUX channel

hw_mutex

internal mutex used for locking transfers.

Note that if the underlying hardware is shared among multiple channels, the driver needs to do additional locking to prevent concurrent access.

crc_work

worker that captures CRCs for each frame

crc_count

counter of captured frame CRCs

transfer

transfers a message representing a single AUX transaction.

This is a hardware-specific implementation of how transactions are executed that the drivers must provide.

A pointer to a drm_dp_aux_msg structure describing the transaction is passed into this function. Upon success, the implementation should return the number of payload bytes that were transferred, or a negative error-code on failure.

Helpers will propagate these errors, with the exception of the -EBUSY error, which causes a transaction to be retried. On a short, helpers will return -EPROTO to make it simpler to check for failure.

The transfer() function must only modify the reply field of the drm_dp_aux_msg structure. The retry logic and i2c helpers assume this is the case.

Also note that this callback can be called no matter the state dev is in and also no matter what state the panel is in. It’s expected:

  • If the dev providing the AUX bus is currently unpowered then it will power itself up for the transfer.

  • If we’re on eDP (using a drm_panel) and the panel is not in a state where it can respond (it’s not powered or it’s in a low power state) then this function may return an error, but not crash. It’s up to the caller of this code to make sure that the panel is powered on if getting an error back is not OK. If a drm_panel driver is initiating a DP AUX transfer it may power itself up however it wants. All other code should ensure that the pre_enable() bridge chain (which eventually calls the drm_panel prepare function) has powered the panel.

wait_hpd_asserted

wait for HPD to be asserted

This is mainly useful for eDP panels drivers to wait for an eDP panel to finish powering on. It is optional for DP AUX controllers to implement this function. It is required for DP AUX endpoints (panel drivers) to call this function after powering up but before doing AUX transfers unless the DP AUX endpoint driver knows that we’re not using the AUX controller’s HPD. One example of the panel driver not needing to call this is if HPD is hooked up to a GPIO that the panel driver can read directly.

If a DP AUX controller does not implement this function then it may still support eDP panels that use the AUX controller’s built-in HPD signal by implementing a long wait for HPD in the transfer() callback, though this is deprecated.

This function will efficiently wait for the HPD signal to be asserted. The wait_us parameter that is passed in says that we know that the HPD signal is expected to be asserted within wait_us microseconds. This function could wait for longer than wait_us if the logic in the DP controller has a long debouncing time. The important thing is that if this function returns success that the DP controller is ready to send AUX transactions.

This function returns 0 if HPD was asserted or -ETIMEDOUT if time expired and HPD wasn’t asserted. This function should not print timeout errors to the log.

The semantics of this function are designed to match the readx_poll_timeout() function. That means a wait_us of 0 means to wait forever. Like readx_poll_timeout(), this function may sleep.

NOTE: this function specifically reports the state of the HPD pin that’s associated with the DP AUX channel. This is different from the HPD concept in much of the rest of DRM which is more about physical presence of a display. For eDP, for instance, a display is assumed always present even if the HPD pin is deasserted.

i2c_nack_count

Counts I2C NACKs, used for DP validation.

i2c_defer_count

Counts I2C DEFERs, used for DP validation.

cec

struct containing fields used for CEC-Tunneling-over-AUX.

is_remote

Is this AUX CH actually using sideband messaging.

powered_down

If true then the remote endpoint is powered down.

Description

An AUX channel can also be used to transport I2C messages to a sink. A typical application of that is to access an EDID that’s present in the sink device. The transfer() function can also be used to execute such transactions. The drm_dp_aux_register() function registers an I2C adapter that can be passed to drm_probe_ddc(). Upon removal, drivers should call drm_dp_aux_unregister() to remove the I2C adapter. The I2C adapter uses long transfers by default; if a partial response is received, the adapter will drop down to the size given by the partial response for this transaction only.

ssize_t drm_dp_dpcd_readb(struct drm_dp_aux *aux, unsigned int offset, u8 *valuep)

read a single byte from the DPCD

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

unsigned int offset

address of the register to read

u8 *valuep

location where the value of the register will be stored

Description

Returns the number of bytes transferred (1) on success, or a negative error code on failure.

ssize_t drm_dp_dpcd_writeb(struct drm_dp_aux *aux, unsigned int offset, u8 value)

write a single byte to the DPCD

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

unsigned int offset

address of the register to write

u8 value

value to write to the register

Description

Returns the number of bytes transferred (1) on success, or a negative error code on failure.

struct drm_dp_desc

DP branch/sink device descriptor

Definition:

struct drm_dp_desc {
    struct drm_dp_dpcd_ident ident;
    u32 quirks;
};

Members

ident

DP device identification from DPCD 0x400 (sink) or 0x500 (branch).

quirks

Quirks; use drm_dp_has_quirk() to query for the quirks.

enum drm_dp_quirk

Display Port sink/branch device specific quirks

Constants

DP_DPCD_QUIRK_CONSTANT_N

The device requires main link attributes Mvid and Nvid to be limited to 16 bits. So will give a constant value (0x8000) for compatability.

DP_DPCD_QUIRK_NO_PSR

The device does not support PSR even if reports that it supports or driver still need to implement proper handling for such device.

DP_DPCD_QUIRK_NO_SINK_COUNT

The device does not set SINK_COUNT to a non-zero value. The driver should ignore SINK_COUNT during detection. Note that drm_dp_read_sink_count_cap() automatically checks for this quirk.

DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD

The device supports MST DSC despite not supporting Virtual DPCD. The DSC caps can be read from the physical aux instead.

DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS

The device supports a link rate of 3.24 Gbps (multiplier 0xc) despite the DP_MAX_LINK_RATE register reporting a lower max multiplier.

DP_DPCD_QUIRK_HBLANK_EXPANSION_REQUIRES_DSC

The device applies HBLANK expansion for some modes, but this requires enabling DSC.

Description

Display Port sink and branch devices in the wild have a variety of bugs, try to collect them here. The quirks are shared, but it’s up to the drivers to implement workarounds for them.

bool drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk)

does the DP device have a specific quirk

Parameters

const struct drm_dp_desc *desc

Device descriptor filled by drm_dp_read_desc()

enum drm_dp_quirk quirk

Quirk to query for

Description

Return true if DP device identified by desc has quirk.

struct drm_edp_backlight_info

Probed eDP backlight info struct

Definition:

struct drm_edp_backlight_info {
    u8 pwmgen_bit_count;
    u8 pwm_freq_pre_divider;
    u16 max;
    bool lsb_reg_used : 1;
    bool aux_enable : 1;
    bool aux_set : 1;
};

Members

pwmgen_bit_count

The pwmgen bit count

pwm_freq_pre_divider

The PWM frequency pre-divider value being used for this backlight, if any

max

The maximum backlight level that may be set

lsb_reg_used

Do we also write values to the DP_EDP_BACKLIGHT_BRIGHTNESS_LSB register?

aux_enable

Does the panel support the AUX enable cap?

aux_set

Does the panel support setting the brightness through AUX?

Description

This structure contains various data about an eDP backlight, which can be populated by using drm_edp_backlight_init().

struct drm_dp_phy_test_params

DP Phy Compliance parameters

Definition:

struct drm_dp_phy_test_params {
    int link_rate;
    u8 num_lanes;
    u8 phy_pattern;
    u8 hbr2_reset[2];
    u8 custom80[10];
    bool enhanced_frame_cap;
};

Members

link_rate

Requested Link rate from DPCD 0x219

num_lanes

Number of lanes requested by sing through DPCD 0x220

phy_pattern

DP Phy test pattern from DPCD 0x248

hbr2_reset

DP HBR2_COMPLIANCE_SCRAMBLER_RESET from DCPD 0x24A and 0x24B

custom80

DP Test_80BIT_CUSTOM_PATTERN from DPCDs 0x250 through 0x259

enhanced_frame_cap

flag for enhanced frame capability.

const char *drm_dp_phy_name(enum drm_dp_phy dp_phy)

Get the name of the given DP PHY

Parameters

enum drm_dp_phy dp_phy

The DP PHY identifier

Description

Given the dp_phy, get a user friendly name of the DP PHY, either “DPRX” or “LTTPR <N>”, or “<INVALID DP PHY>” on errors. The returned string is always non-NULL and valid.

Return

Name of the DP PHY.

int drm_dp_dpcd_probe(struct drm_dp_aux *aux, unsigned int offset)

probe a given DPCD address with a 1-byte read access

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel (SST)

unsigned int offset

address of the register to probe

Description

Probe the provided DPCD address by reading 1 byte from it. The function can be used to trigger some side-effect the read access has, like waking up the sink, without the need for the read-out value.

Returns 0 if the read access suceeded, or a negative error code on failure.

void drm_dp_dpcd_set_powered(struct drm_dp_aux *aux, bool powered)

Set whether the DP device is powered

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel; for convenience it’s OK to pass NULL here and the function will be a no-op.

bool powered

true if powered; false if not

Description

If the endpoint device on the DP AUX bus is known to be powered down then this function can be called to make future transfers fail immediately instead of needing to time out.

If this function is never called then a device defaults to being powered.

ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset, void *buffer, size_t size)

read a series of bytes from the DPCD

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel (SST or MST)

unsigned int offset

address of the (first) register to read

void *buffer

buffer to store the register values

size_t size

number of bytes in buffer

Description

Returns the number of bytes transferred on success, or a negative error code on failure. -EIO is returned if the request was NAKed by the sink or if the retry count was exceeded. If not all bytes were transferred, this function returns -EPROTO. Errors from the underlying AUX channel transfer function, with the exception of -EBUSY (which causes the transaction to be retried), are propagated to the caller.

ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset, void *buffer, size_t size)

write a series of bytes to the DPCD

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel (SST or MST)

unsigned int offset

address of the (first) register to write

void *buffer

buffer containing the values to write

size_t size

number of bytes in buffer

Description

Returns the number of bytes transferred on success, or a negative error code on failure. -EIO is returned if the request was NAKed by the sink or if the retry count was exceeded. If not all bytes were transferred, this function returns -EPROTO. Errors from the underlying AUX channel transfer function, with the exception of -EBUSY (which causes the transaction to be retried), are propagated to the caller.

read DPCD link status (bytes 0x202-0x207)

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

u8 status[DP_LINK_STATUS_SIZE]

buffer to store the link status in (must be at least 6 bytes)

Description

Returns the number of bytes transferred on success or a negative error code on failure.

get the link status information for a DP PHY

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

enum drm_dp_phy dp_phy

the DP PHY to get the link status for

u8 link_status[DP_LINK_STATUS_SIZE]

buffer to return the status in

Description

Fetch the AUX DPCD registers for the DPRX or an LTTPR PHY link status. The layout of the returned link_status matches the DPCD register layout of the DPRX PHY link status.

Returns 0 if the information was read successfully or a negative error code on failure.

bool drm_dp_downstream_is_type(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4], u8 type)

is the downstream facing port of certain type?

Parameters

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

const u8 port_cap[4]

port capabilities

u8 type

port type to be checked. Can be: DP_DS_PORT_TYPE_DP, DP_DS_PORT_TYPE_VGA, DP_DS_PORT_TYPE_DVI, DP_DS_PORT_TYPE_HDMI, DP_DS_PORT_TYPE_NON_EDID, DP_DS_PORT_TYPE_DP_DUALMODE or DP_DS_PORT_TYPE_WIRELESS.

Description

Caveat: Only works with DPCD 1.1+ port caps.

Return

whether the downstream facing port matches the type.

bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4], const struct drm_edid *drm_edid)

is the downstream facing port TMDS?

Parameters

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

const u8 port_cap[4]

port capabilities

const struct drm_edid *drm_edid

EDID

Return

whether the downstream facing port is TMDS (HDMI/DVI).

bool drm_dp_send_real_edid_checksum(struct drm_dp_aux *aux, u8 real_edid_checksum)

send back real edid checksum value

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

u8 real_edid_checksum

real edid checksum for the last block

Return

True on success

int drm_dp_read_dpcd_caps(struct drm_dp_aux *aux, u8 dpcd[DP_RECEIVER_CAP_SIZE])

read DPCD caps and extended DPCD caps if available

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

u8 dpcd[DP_RECEIVER_CAP_SIZE]

Buffer to store the resulting DPCD in

Description

Attempts to read the base DPCD caps for aux. Additionally, this function checks for and reads the extended DPRX caps (DP_DP13_DPCD_REV) if present.

Return

0 if the DPCD was read successfully, negative error code otherwise.

int drm_dp_read_downstream_info(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE], u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS])

read DPCD downstream port info if available

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

A cached copy of the port’s DPCD

u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS]

buffer to store the downstream port info in

Description

See also: drm_dp_downstream_max_clock() drm_dp_downstream_max_bpc()

Return

0 if either the downstream port info was read successfully or there was no downstream info to read, or a negative error code otherwise.

int drm_dp_downstream_max_dotclock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4])

extract downstream facing port max dot clock

Parameters

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

const u8 port_cap[4]

port capabilities

Return

Downstream facing port max dot clock in kHz on success, or 0 if max clock not defined

int drm_dp_downstream_max_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4], const struct drm_edid *drm_edid)

extract downstream facing port max TMDS clock

Parameters

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

const u8 port_cap[4]

port capabilities

const struct drm_edid *drm_edid

EDID

Return

HDMI/DVI downstream facing port max TMDS clock in kHz on success, or 0 if max TMDS clock not defined

int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4], const struct drm_edid *drm_edid)

extract downstream facing port min TMDS clock

Parameters

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

const u8 port_cap[4]

port capabilities

const struct drm_edid *drm_edid

EDID

Return

HDMI/DVI downstream facing port min TMDS clock in kHz on success, or 0 if max TMDS clock not defined

int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4], const struct drm_edid *drm_edid)

extract downstream facing port max bits per component

Parameters

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

const u8 port_cap[4]

downstream facing port capabilities

const struct drm_edid *drm_edid

EDID

Return

Max bpc on success or 0 if max bpc not defined

bool drm_dp_downstream_420_passthrough(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4])

determine downstream facing port YCbCr 4:2:0 pass-through capability

Parameters

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

const u8 port_cap[4]

downstream facing port capabilities

Return

whether the downstream facing port can pass through YCbCr 4:2:0

bool drm_dp_downstream_444_to_420_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4])

determine downstream facing port YCbCr 4:4:4->4:2:0 conversion capability

Parameters

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

const u8 port_cap[4]

downstream facing port capabilities

Return

whether the downstream facing port can convert YCbCr 4:4:4 to 4:2:0

bool drm_dp_downstream_rgb_to_ycbcr_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4], u8 color_spc)

determine downstream facing port RGB->YCbCr conversion capability

Parameters

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

const u8 port_cap[4]

downstream facing port capabilities

u8 color_spc

Colorspace for which conversion cap is sought

Return

whether the downstream facing port can convert RGB->YCbCr for a given colorspace.

struct drm_display_mode *drm_dp_downstream_mode(struct drm_device *dev, const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4])

return a mode for downstream facing port

Parameters

struct drm_device *dev

DRM device

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

const u8 port_cap[4]

port capabilities

Description

Provides a suitable mode for downstream facing ports without EDID.

Return

A new drm_display_mode on success or NULL on failure

int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6])

identify branch device

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

char id[6]

DisplayPort branch device id

Description

Returns branch device id on success or NULL on failure

void drm_dp_downstream_debug(struct seq_file *m, const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4], const struct drm_edid *drm_edid, struct drm_dp_aux *aux)

debug DP branch devices

Parameters

struct seq_file *m

pointer for debugfs file

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

const u8 port_cap[4]

port capabilities

const struct drm_edid *drm_edid

EDID

struct drm_dp_aux *aux

DisplayPort AUX channel

enum drm_mode_subconnector drm_dp_subconnector_type(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4])

get DP branch device type

Parameters

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

const u8 port_cap[4]

port capabilities

void drm_dp_set_subconnector_property(struct drm_connector *connector, enum drm_connector_status status, const u8 *dpcd, const u8 port_cap[4])

set subconnector for DP connector

Parameters

struct drm_connector *connector

connector to set property on

enum drm_connector_status status

connector status

const u8 *dpcd

DisplayPort configuration data

const u8 port_cap[4]

port capabilities

Description

Called by a driver on every detect event.

bool drm_dp_read_sink_count_cap(struct drm_connector *connector, const u8 dpcd[DP_RECEIVER_CAP_SIZE], const struct drm_dp_desc *desc)

Check whether a given connector has a valid sink count

Parameters

struct drm_connector *connector

The DRM connector to check

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

A cached copy of the connector’s DPCD RX capabilities

const struct drm_dp_desc *desc

A cached copy of the connector’s DP descriptor

Description

See also: drm_dp_read_sink_count()

Return

True if the (e)DP connector has a valid sink count that should be probed, false otherwise.

int drm_dp_read_sink_count(struct drm_dp_aux *aux)

Retrieve the sink count for a given sink

Parameters

struct drm_dp_aux *aux

The DP AUX channel to use

Description

See also: drm_dp_read_sink_count_cap()

Return

The current sink count reported by aux, or a negative error code otherwise.

void drm_dp_remote_aux_init(struct drm_dp_aux *aux)

minimally initialise a remote aux channel

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

Description

Used for remote aux channel in general. Merely initialize the crc work struct.

void drm_dp_aux_init(struct drm_dp_aux *aux)

minimally initialise an aux channel

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

Description

If you need to use the drm_dp_aux’s i2c adapter prior to registering it with the outside world, call drm_dp_aux_init() first. For drivers which are grandparents to their AUX adapters (e.g. the AUX adapter is parented by a drm_connector), you must still call drm_dp_aux_register() once the connector has been registered to allow userspace access to the auxiliary DP channel. Likewise, for such drivers you should also assign drm_dp_aux.drm_dev as early as possible so that the drm_device that corresponds to the AUX adapter may be mentioned in debugging output from the DRM DP helpers.

For devices which use a separate platform device for their AUX adapters, this may be called as early as required by the driver.

int drm_dp_aux_register(struct drm_dp_aux *aux)

initialise and register aux channel

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

Description

Automatically calls drm_dp_aux_init() if this hasn’t been done yet. This should only be called once the parent of aux, drm_dp_aux.dev, is initialized. For devices which are grandparents of their AUX channels, drm_dp_aux.dev will typically be the drm_connector device which corresponds to aux. For these devices, it’s advised to call drm_dp_aux_register() in drm_connector_funcs.late_register, and likewise to call drm_dp_aux_unregister() in drm_connector_funcs.early_unregister. Functions which don’t follow this will likely Oops when CONFIG_DRM_DISPLAY_DP_AUX_CHARDEV is enabled.

For devices where the AUX channel is a device that exists independently of the drm_device that uses it, such as SoCs and bridge devices, it is recommended to call drm_dp_aux_register() after a drm_device has been assigned to drm_dp_aux.drm_dev, and likewise to call drm_dp_aux_unregister() once the drm_device should no longer be associated with the AUX channel (e.g. on bridge detach).

Drivers which need to use the aux channel before either of the two points mentioned above need to call drm_dp_aux_init() in order to use the AUX channel before registration.

Returns 0 on success or a negative error code on failure.

void drm_dp_aux_unregister(struct drm_dp_aux *aux)

unregister an AUX adapter

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

int drm_dp_psr_setup_time(const u8 psr_cap[EDP_PSR_RECEIVER_CAP_SIZE])

PSR setup in time usec

Parameters

const u8 psr_cap[EDP_PSR_RECEIVER_CAP_SIZE]

PSR capabilities from DPCD

Return

PSR setup time for the panel in microseconds, negative error code on failure.

int drm_dp_start_crc(struct drm_dp_aux *aux, struct drm_crtc *crtc)

start capture of frame CRCs

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

struct drm_crtc *crtc

CRTC displaying the frames whose CRCs are to be captured

Description

Returns 0 on success or a negative error code on failure.

int drm_dp_stop_crc(struct drm_dp_aux *aux)

stop capture of frame CRCs

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

Description

Returns 0 on success or a negative error code on failure.

int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc, bool is_branch)

read sink/branch descriptor from DPCD

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

struct drm_dp_desc *desc

Device descriptor to fill from DPCD

bool is_branch

true for branch devices, false for sink devices

Description

Read DPCD 0x400 (sink) or 0x500 (branch) into desc. Also debug log the identification.

Returns 0 on success or a negative error code on failure.

int drm_dp_dump_lttpr_desc(struct drm_dp_aux *aux, enum drm_dp_phy dp_phy)

read and dump the DPCD descriptor for an LTTPR PHY

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

enum drm_dp_phy dp_phy

LTTPR PHY instance

Description

Read the DPCD LTTPR PHY descriptor for dp_phy and print a debug message with its details to dmesg.

Returns 0 on success or a negative error code on failure.

u8 drm_dp_dsc_sink_bpp_incr(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])

Get bits per pixel increment

Parameters

const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]

DSC capabilities from DPCD

Description

Returns the bpp precision supported by the DP sink.

u8 drm_dp_dsc_sink_max_slice_count(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], bool is_edp)

Get the max slice count supported by the DSC sink.

Parameters

const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]

DSC capabilities from DPCD

bool is_edp

true if its eDP, false for DP

Description

Read the slice capabilities DPCD register from DSC sink to get the maximum slice count supported. This is used to populate the DSC parameters in the struct drm_dsc_config by the driver. Driver creates an infoframe using these parameters to populate struct drm_dsc_pps_infoframe. These are sent to the sink using DSC infoframe using the helper function drm_dsc_pps_infoframe_pack()

Return

Maximum slice count supported by DSC sink or 0 its invalid

u8 drm_dp_dsc_sink_line_buf_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])

Get the line buffer depth in bits

Parameters

const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]

DSC capabilities from DPCD

Description

Read the DSC DPCD register to parse the line buffer depth in bits which is number of bits of precision within the decoder line buffer supported by the DSC sink. This is used to populate the DSC parameters in the struct drm_dsc_config by the driver. Driver creates an infoframe using these parameters to populate struct drm_dsc_pps_infoframe. These are sent to the sink using DSC infoframe using the helper function drm_dsc_pps_infoframe_pack()

Return

Line buffer depth supported by DSC panel or 0 its invalid

int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], u8 dsc_bpc[3])

Get all the input bits per component values supported by the DSC sink.

Parameters

const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]

DSC capabilities from DPCD

u8 dsc_bpc[3]

An array to be filled by this helper with supported input bpcs.

Description

Read the DSC DPCD from the sink device to parse the supported bits per component values. This is used to populate the DSC parameters in the struct drm_dsc_config by the driver. Driver creates an infoframe using these parameters to populate struct drm_dsc_pps_infoframe. These are sent to the sink using DSC infoframe using the helper function drm_dsc_pps_infoframe_pack()

Return

Number of input BPC values parsed from the DPCD

int drm_dp_read_lttpr_common_caps(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE], u8 caps[DP_LTTPR_COMMON_CAP_SIZE])

read the LTTPR common capabilities

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

u8 caps[DP_LTTPR_COMMON_CAP_SIZE]

buffer to return the capability info in

Description

Read capabilities common to all LTTPRs.

Returns 0 on success or a negative error code on failure.

int drm_dp_read_lttpr_phy_caps(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE], enum drm_dp_phy dp_phy, u8 caps[DP_LTTPR_PHY_CAP_SIZE])

read the capabilities for a given LTTPR PHY

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

enum drm_dp_phy dp_phy

LTTPR PHY to read the capabilities for

u8 caps[DP_LTTPR_PHY_CAP_SIZE]

buffer to return the capability info in

Description

Read the capabilities for the given LTTPR PHY.

Returns 0 on success or a negative error code on failure.

int drm_dp_lttpr_count(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE])

get the number of detected LTTPRs

Parameters

const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]

LTTPR common capabilities

Description

Get the number of detected LTTPRs from the LTTPR common capabilities info.

Return

-ERANGE if more than supported number (8) of LTTPRs are detected -EINVAL if the DP_PHY_REPEATER_CNT register contains an invalid value otherwise the number of detected LTTPRs

get the maximum link rate supported by all LTTPRs

Parameters

const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]

LTTPR common capabilities

Description

Returns the maximum link rate supported by all detected LTTPRs.

int drm_dp_lttpr_max_lane_count(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE])

get the maximum lane count supported by all LTTPRs

Parameters

const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]

LTTPR common capabilities

Description

Returns the maximum lane count supported by all detected LTTPRs.

bool drm_dp_lttpr_voltage_swing_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP_SIZE])

check for LTTPR vswing3 support

Parameters

const u8 caps[DP_LTTPR_PHY_CAP_SIZE]

LTTPR PHY capabilities

Description

Returns true if the caps for an LTTPR TX PHY indicate support for voltage swing level 3.

bool drm_dp_lttpr_pre_emphasis_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP_SIZE])

check for LTTPR preemph3 support

Parameters

const u8 caps[DP_LTTPR_PHY_CAP_SIZE]

LTTPR PHY capabilities

Description

Returns true if the caps for an LTTPR TX PHY indicate support for pre-emphasis level 3.

int drm_dp_get_phy_test_pattern(struct drm_dp_aux *aux, struct drm_dp_phy_test_params *data)

get the requested pattern from the sink.

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

struct drm_dp_phy_test_params *data

DP phy compliance test parameters.

Description

Returns 0 on success or a negative error code on failure.

int drm_dp_set_phy_test_pattern(struct drm_dp_aux *aux, struct drm_dp_phy_test_params *data, u8 dp_rev)

set the pattern to the sink.

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

struct drm_dp_phy_test_params *data

DP phy compliance test parameters.

u8 dp_rev

DP revision to use for compliance testing

Description

Returns 0 on success or a negative error code on failure.

bool drm_dp_as_sdp_supported(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE])

check if adaptive sync sdp is supported

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

Description

Returns true if adaptive sync sdp is supported, else returns false

bool drm_dp_vsc_sdp_supported(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE])

check if vsc sdp is supported

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

Description

Returns true if vsc sdp is supported, else returns false

ssize_t drm_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc, struct dp_sdp *sdp)

pack a given vsc sdp into generic dp_sdp

Parameters

const struct drm_dp_vsc_sdp *vsc

vsc sdp initialized according to its purpose as defined in table 2-118 - table 2-120 in DP 1.4a specification

struct dp_sdp *sdp

valid handle to the generic dp_sdp which will be packed

Description

Returns length of sdp on success and error code on failure

int drm_dp_get_pcon_max_frl_bw(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4])

maximum frl supported by PCON

Parameters

const u8 dpcd[DP_RECEIVER_CAP_SIZE]

DisplayPort configuration data

const u8 port_cap[4]

port capabilities

Description

Returns maximum frl bandwidth supported by PCON in GBPS, returns 0 if not supported.

int drm_dp_pcon_frl_prepare(struct drm_dp_aux *aux, bool enable_frl_ready_hpd)

Prepare PCON for FRL.

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

bool enable_frl_ready_hpd

Configure DP_PCON_ENABLE_HPD_READY.

Description

Returns 0 if success, else returns negative error code.

bool drm_dp_pcon_is_frl_ready(struct drm_dp_aux *aux)

Is PCON ready for FRL

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

Description

Returns true if success, else returns false.

int drm_dp_pcon_frl_configure_1(struct drm_dp_aux *aux, int max_frl_gbps, u8 frl_mode)

Set HDMI LINK Configuration-Step1

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

int max_frl_gbps

maximum frl bw to be configured between PCON and HDMI sink

u8 frl_mode

FRL Training mode, it can be either Concurrent or Sequential. In Concurrent Mode, the FRL link bring up can be done along with DP Link training. In Sequential mode, the FRL link bring up is done prior to the DP Link training.

Description

Returns 0 if success, else returns negative error code.

int drm_dp_pcon_frl_configure_2(struct drm_dp_aux *aux, int max_frl_mask, u8 frl_type)

Set HDMI Link configuration Step-2

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

int max_frl_mask

Max FRL BW to be tried by the PCON with HDMI Sink

u8 frl_type

FRL training type, can be Extended, or Normal. In Normal FRL training, the PCON tries each frl bw from the max_frl_mask starting from min, and stops when link training is successful. In Extended FRL training, all frl bw selected in the mask are trained by the PCON.

Description

Returns 0 if success, else returns negative error code.

int drm_dp_pcon_reset_frl_config(struct drm_dp_aux *aux)

Re-Set HDMI Link configuration.

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

Description

Returns 0 if success, else returns negative error code.

int drm_dp_pcon_frl_enable(struct drm_dp_aux *aux)

Enable HDMI link through FRL

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

Description

Returns 0 if success, else returns negative error code.

check if the PCON HDMI LINK status is active.

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

Description

Returns true if link is active else returns false.

get the PCON HDMI LINK MODE

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

u8 *frl_trained_mask

pointer to store bitmask of the trained bw configuration. Valid only if the MODE returned is FRL. For Normal Link training mode only 1 of the bits will be set, but in case of Extended mode, more than one bits can be set.

Description

Returns the link mode : TMDS or FRL on success, else returns negative error code.

print the error count per lane during link failure between PCON and HDMI sink

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

struct drm_connector *connector

DRM connector code.

int drm_dp_pcon_pps_default(struct drm_dp_aux *aux)

Let PCON fill the default pps parameters for DSC1.2 between PCON & HDMI2.1 sink

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

Description

Returns 0 on success, else returns negative error code.

int drm_dp_pcon_pps_override_buf(struct drm_dp_aux *aux, u8 pps_buf[128])

Configure PPS encoder override buffer for HDMI sink

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

u8 pps_buf[128]

128 bytes to be written into PPS buffer for HDMI sink by PCON.

Description

Returns 0 on success, else returns negative error code.

int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, u16 level)

Set the backlight level of an eDP panel via AUX

Parameters

struct drm_dp_aux *aux

The DP AUX channel to use

const struct drm_edp_backlight_info *bl

Backlight capability info from drm_edp_backlight_init()

u16 level

The brightness level to set

Description

Sets the brightness level of an eDP panel’s backlight. Note that the panel’s backlight must already have been enabled by the driver by calling drm_edp_backlight_enable().

Return

0 on success, negative error code on failure

int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, const u16 level)

Enable an eDP panel’s backlight using DPCD

Parameters

struct drm_dp_aux *aux

The DP AUX channel to use

const struct drm_edp_backlight_info *bl

Backlight capability info from drm_edp_backlight_init()

const u16 level

The initial backlight level to set via AUX, if there is one

Description

This function handles enabling DPCD backlight controls on a panel over DPCD, while additionally restoring any important backlight state such as the given backlight level, the brightness byte count, backlight frequency, etc.

Note that certain panels do not support being enabled or disabled via DPCD, but instead require that the driver handle enabling/disabling the panel through implementation-specific means using the EDP_BL_PWR GPIO. For such panels, drm_edp_backlight_info.aux_enable will be set to false, this function becomes a no-op, and the driver is expected to handle powering the panel on using the EDP_BL_PWR GPIO.

Return

0 on success, negative error code on failure.

int drm_edp_backlight_disable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl)

Disable an eDP backlight using DPCD, if supported

Parameters

struct drm_dp_aux *aux

The DP AUX channel to use

const struct drm_edp_backlight_info *bl

Backlight capability info from drm_edp_backlight_init()

Description

This function handles disabling DPCD backlight controls on a panel over AUX.

Note that certain panels do not support being enabled or disabled via DPCD, but instead require that the driver handle enabling/disabling the panel through implementation-specific means using the EDP_BL_PWR GPIO. For such panels, drm_edp_backlight_info.aux_enable will be set to false, this function becomes a no-op, and the driver is expected to handle powering the panel off using the EDP_BL_PWR GPIO.

Return

0 on success or no-op, negative error code on failure.

int drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl, u16 driver_pwm_freq_hz, const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE], u16 *current_level, u8 *current_mode)

Probe a display panel’s TCON using the standard VESA eDP backlight interface.

Parameters

struct drm_dp_aux *aux

The DP aux device to use for probing

struct drm_edp_backlight_info *bl

The drm_edp_backlight_info struct to fill out with information on the backlight

u16 driver_pwm_freq_hz

Optional PWM frequency from the driver in hz

const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]

A cached copy of the eDP DPCD

u16 *current_level

Where to store the probed brightness level, if any

u8 *current_mode

Where to store the currently set backlight control mode

Description

Initializes a drm_edp_backlight_info struct by probing aux for it’s backlight capabilities, along with also probing the current and maximum supported brightness levels.

If driver_pwm_freq_hz is non-zero, this will be used as the backlight frequency. Otherwise, the default frequency from the panel is used.

Return

0 on success, negative error code on failure.

int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux)

create and use DP AUX backlight

Parameters

struct drm_panel *panel

DRM panel

struct drm_dp_aux *aux

The DP AUX channel to use

Description

Use this function to create and handle backlight if your panel supports backlight control over DP AUX channel using DPCD registers as per VESA’s standard backlight control interface.

When the panel is enabled backlight will be enabled after a successful call to drm_panel_funcs.enable()

When the panel is disabled backlight will be disabled before the call to drm_panel_funcs.disable().

A typical implementation for a panel driver supporting backlight control over DP AUX will call this function at probe time. Backlight will then be handled transparently without requiring any intervention from the driver.

drm_panel_dp_aux_backlight() must be called after the call to drm_panel_init().

Return

0 on success or a negative error code on failure.

int drm_dp_bw_overhead(int lane_count, int hactive, int dsc_slice_count, int bpp_x16, unsigned long flags)

Calculate the BW overhead of a DP link stream

Parameters

int lane_count

DP link lane count

int hactive

pixel count of the active period in one scanline of the stream

int dsc_slice_count

DSC slice count if flags/DRM_DP_LINK_BW_OVERHEAD_DSC is set

int bpp_x16

bits per pixel in .4 binary fixed point

unsigned long flags

DRM_DP_OVERHEAD_x flags

Description

Calculate the BW allocation overhead of a DP link stream, depending on the link’s - lane_count - SST/MST mode (flags / DRM_DP_OVERHEAD_MST) - symbol size (flags / DRM_DP_OVERHEAD_UHBR) - FEC mode (flags / DRM_DP_OVERHEAD_FEC) - SSC/REF_CLK mode (flags / DRM_DP_OVERHEAD_SSC_REF_CLK) as well as the stream’s - hactive timing - bpp_x16 color depth - compression mode (flags / DRM_DP_OVERHEAD_DSC). Note that this overhead doesn’t account for the 8b/10b, 128b/132b channel coding efficiency, for that see drm_dp_link_bw_channel_coding_efficiency().

Returns the overhead as 100% + overhead% in 1ppm units.

int drm_dp_bw_channel_coding_efficiency(bool is_uhbr)

Get a DP link’s channel coding efficiency

Parameters

bool is_uhbr

Whether the link has a 128b/132b channel coding

Description

Return the channel coding efficiency of the given DP link type, which is either 8b/10b or 128b/132b (aka UHBR). The corresponding overhead includes the 8b -> 10b, 128b -> 132b pixel data to link symbol conversion overhead and for 128b/132b any link or PHY level control symbol insertion overhead (LLCP, FEC, PHY sync, see DP Standard v2.1 3.5.2.18). For 8b/10b the corresponding FEC overhead is BW allocation specific, included in the value returned by drm_dp_bw_overhead().

Returns the efficiency in the 100%/coding-overhead% ratio in 1ppm units.

int drm_dp_max_dprx_data_rate(int max_link_rate, int max_lanes)

Get the max data bandwidth of a DPRX sink

Parameters

int max_link_rate

max DPRX link rate in 10kbps units

int max_lanes

max DPRX lane count

Description

Given a link rate and lanes, get the data bandwidth.

Data bandwidth is the actual payload rate, which depends on the data bandwidth efficiency and the link rate.

Note that protocol layers above the DPRX link level considered here can further limit the maximum data rate. Such layers are the MST topology (with limits on the link between the source and first branch device as well as on the whole MST path until the DPRX link) and (Thunderbolt) DP tunnels - which in turn can encapsulate an MST link with its own limit - with each SST or MST encapsulated tunnel sharing the BW of a tunnel group.

Returns the maximum data rate in kBps units.

Display Port CEC Helper Functions Reference

These functions take care of supporting the CEC-Tunneling-over-AUX feature of DisplayPort-to-HDMI adapters.

void drm_dp_cec_irq(struct drm_dp_aux *aux)

handle CEC interrupt, if any

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

Description

Should be called when handling an IRQ_HPD request. If CEC-tunneling-over-AUX is present, then it will check for a CEC_IRQ and handle it accordingly.

void drm_dp_cec_register_connector(struct drm_dp_aux *aux, struct drm_connector *connector)

register a new connector

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

struct drm_connector *connector

drm connector

Description

A new connector was registered with associated CEC adapter name and CEC adapter parent device. After registering the name and parent drm_dp_cec_set_edid() is called to check if the connector supports CEC and to register a CEC adapter if that is the case.

void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux)

unregister the CEC adapter, if any

Parameters

struct drm_dp_aux *aux

DisplayPort AUX channel

Display Port Dual Mode Adaptor Helper Functions Reference

Helper functions to deal with DP dual mode (aka. DP++) adaptors.

Type 1: Adaptor registers (if any) and the sink DDC bus may be accessed via I2C.

Type 2: Adaptor registers and sink DDC bus can be accessed either via I2C or I2C-over-AUX. Source devices may choose to implement either of these access methods.

enum drm_lspcon_mode

Constants

DRM_LSPCON_MODE_INVALID

No LSPCON.

DRM_LSPCON_MODE_LS

Level shifter mode of LSPCON which drives DP++ to HDMI 1.4 conversion.

DRM_LSPCON_MODE_PCON

Protocol converter mode of LSPCON which drives DP++ to HDMI 2.0 active conversion.

enum drm_dp_dual_mode_type

Type of the DP dual mode adaptor

Constants

DRM_DP_DUAL_MODE_NONE

No DP dual mode adaptor

DRM_DP_DUAL_MODE_UNKNOWN

Could be either none or type 1 DVI adaptor

DRM_DP_DUAL_MODE_TYPE1_DVI

Type 1 DVI adaptor

DRM_DP_DUAL_MODE_TYPE1_HDMI

Type 1 HDMI adaptor

DRM_DP_DUAL_MODE_TYPE2_DVI

Type 2 DVI adaptor

DRM_DP_DUAL_MODE_TYPE2_HDMI

Type 2 HDMI adaptor

DRM_DP_DUAL_MODE_LSPCON

Level shifter / protocol converter

ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter, u8 offset, void *buffer, size_t size)

Read from the DP dual mode adaptor register(s)

Parameters

struct i2c_adapter *adapter

I2C adapter for the DDC bus

u8 offset

register offset

void *buffer

buffer for return data

size_t size

size of the buffer

Description

Reads size bytes from the DP dual mode adaptor registers starting at offset.

Return

0 on success, negative error code on failure

ssize_t drm_dp_dual_mode_write(struct i2c_adapter *adapter, u8 offset, const void *buffer, size_t size)

Write to the DP dual mode adaptor register(s)

Parameters

struct i2c_adapter *adapter

I2C adapter for the DDC bus

u8 offset

register offset

const void *buffer

buffer for write data

size_t size

size of the buffer

Description

Writes size bytes to the DP dual mode adaptor registers starting at offset.

Return

0 on success, negative error code on failure

enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(const struct drm_device *dev, struct i2c_adapter *adapter)

Identify the DP dual mode adaptor

Parameters

const struct drm_device *dev

drm_device to use

struct i2c_adapter *adapter

I2C adapter for the DDC bus

Description

Attempt to identify the type of the DP dual mode adaptor used.

Note that when the answer is DRM_DP_DUAL_MODE_UNKNOWN it’s not certain whether we’re dealing with a native HDMI port or a type 1 DVI dual mode adaptor. The driver will have to use some other hardware/driver specific mechanism to make that distinction.

Return

The type of the DP dual mode adaptor used

int drm_dp_dual_mode_max_tmds_clock(const struct