As explained in DRM pipeline, DRM is configured by setting up framebuffers, CRTCs, planes, connectors and encoders.

Framebuffers have their own API discussed in DRM framebuffers. All other objects are configured through atomic interface, named thus as it provides an operation to apply a number of changes in atomic (all or none) manner1.


In atomic interface, DRM is configured through objects and properties. An object is framebuffer, CRTC, plane, connector or encoder. They all are indexed by a unique number, chosen by the kernel.

One can obtain the lists of framebuffers, CRTCs, connectors and encoders using DRM_IOCTL_MODE_GETRESOURCES. This returns lists of IDs of the corresponding objects. Planes are enumerated separately in a similar manner using DRM_IOCTL_MODE_GETPLANERESOURCES2.

To obtain information about object, one uses one of DRM_IOCTL_MODE_GETCRTC, DRM_IOCTL_MODE_GETPLANE, DRM_IOCTL_MODE_GETCONNECTOR, DRM_IOCTL_MODE_GETENCODER. However a lot of information, including all mutable information, is specified via properties.


CRTCs, planes and connectors have properties: mapping of string to value. Some values are read/only, some are read/write. Values of properties may be of several types:

  • integer
  • range (two unsigned integers)
  • enum (one of several string values)
  • blob (a bag of bytes)
  • bitmask (some bit flags)
  • object (DRM object ID)
  • signed range (two signed integers)

The list of properties is fixed during the lifetime of object, and can be queried using DRM_IOCTL_MODE_OBJ_GETPROPERTIES. This returns a list of property IDs (integers scoped to the object) and property values themeslves.

Property metadata (name, type, enum values) can be read using DRM_IOCTL_MODE_GETPROPERTY.


Blobs are a bit different from other properties, as they are not set directly. Instead, one creates a blob value using DRM_IOCTL_MODE_CREATEPROPBLOB, and uses returned ID as a value.

When a blob is no longer needed, it can removed using DRM_IOCTL_MODE_DESTROYPROPBLOB. Current value can be retrieved using DRM_IOCTL_MODE_GETPROPBLOB.



  • ACTIVE should the display of this CRTC be enabled
  • MODE_ID display mode
  • VRR_ENABLED VRR toggle
  • DEGAMMA_LUT, GAMMA_LUT, CTM color management properties


Every plane provides a set of compatible CRTCs.


  • FB_ID which framebuffer should be rendered
  • SRC_[XYWH] source rectangle on that framebuffer,
  • CRTC_[XYWH] destination rectangle on the CRTC,
  • CRTC_ID the target CRTC
  • (read-only) IN_FORMATS the list of supported pixel formats+modifiers
  • (read-only) type. Hint of plane usage, one of “primary”, “cursor” and “overlay”.

Some drivers provide more properties:

  • COLOR_ENCODING, COLOR_RANGE specification of the plane’s color space
  • alpha global plane opacity
  • pixel_blend_mode alpha blending mode
  • rotation plane rotation
  • zpos Z-order of plane within the planes stack on CRTC


Every connector provides:

  • type, e.g. VGA or eDP
  • physical size
  • subpixel order
  • a set of compatible encoders


  • CRTC_ID the target CRTC for the connector.
  • audio Configuration of audio on the connector.
  • (read-only) TILE Configuration of tiled displays.
  • (read-only) EDID EDID blob. Not always available.
  • (read-only) link-status Display connection status.
  • (read-only) max bpc Maximum supported bit depth of the display/connector.
  • (read-only) non-desktop 1 for connectors that are attached to displays not generally useful as regular desktop outputs (e.g. touchbar)
  • (read-only) subconnector Detailed connector type
  • (read-only) vrr_capable 1 if connector supports VRR


Every encoder provides:

  • type, e.g. DAC or LVDS
  • a set of compatible CRTCs
  • a set of encoders that can be set up as mirrors

Applying changes atomically

To apply changes to DRM objects, one creates a set of triples “object, property, new value” and passes it to DRM_IOCTL_MODE_ATOMIC. The changes are either applied all at once, or none and error is returned. For example, an error returns if the configuration of CRTCs/planes/encoders/connectors fails to satisfy compatibility rules.

There are several flags for this ioctl:

  • DRM_MODE_PAGE_FLIP_EVENT. Requests an “vblank” event to be reported by kernel whenever the requested changes begin to be displayed to the user.
  • DRM_MODE_ATOMIC_TEST_ONLY. Does not apply the changes, checks if the hardware actually supports whatever was specified.
  • DRM_MODE_ATOMIC_NONBLOCK. Do not wait for changes to be applied.
  • DRM_MODE_ATOMIC_ALLOW_MODESET. Without this flag, only changes that do not cause visual artifacts may be applied. Which changes cause artifacts depends on the hardware/driver3.


If requested, kernel notifies userspace when events happen. The events can be read from the DRM file descriptor as structs drm_event_*.

If DRM_MODE_PAGE_FLIP_EVENT is specified to DRM_IOCTL_MODE_ATOMIC, drm_event_vblank struct is sent to the fd whenever a “vblank” has happened. Other events are related to page flipping and will be discussed separately.



  1. There is another interface predating atomic that provided operations to apply changes piece by piece. It led to various races and display artifacts, so the atomic interface was invented. ↩︎

  2. Sigh. ↩︎

  3. Historically these were changes that caused a change of display mode, that’s the reason for the flag name. ↩︎