Kernel Mode Setting (KMS)¶
Mode Setting¶
Drivers must initialize the mode setting core by calling
drm_mode_config_init()
on the DRM device. The function
initializes the struct drm_device
mode_config field and never fails. Once done, mode configuration must
be setup by initializing the following fields.
- int min_width, min_height; int max_width, max_height; Minimum and maximum width and height of the frame buffers in pixel units.
- struct drm_mode_config_funcs *funcs; Mode setting functions.
Display Modes Function Reference¶
-
enum
drm_mode_status
¶ hardware support status of a mode
Constants
MODE_OK
- Mode OK
MODE_HSYNC
- hsync out of range
MODE_VSYNC
- vsync out of range
MODE_H_ILLEGAL
- mode has illegal horizontal timings
MODE_V_ILLEGAL
- mode has illegal horizontal timings
MODE_BAD_WIDTH
- requires an unsupported linepitch
MODE_NOMODE
- no mode with a matching name
MODE_NO_INTERLACE
- interlaced mode not supported
MODE_NO_DBLESCAN
- doublescan mode not supported
MODE_NO_VSCAN
- multiscan mode not supported
MODE_MEM
- insufficient video memory
MODE_VIRTUAL_X
- mode width too large for specified virtual size
MODE_VIRTUAL_Y
- mode height too large for specified virtual size
MODE_MEM_VIRT
- insufficient video memory given virtual size
MODE_NOCLOCK
- no fixed clock available
MODE_CLOCK_HIGH
- clock required is too high
MODE_CLOCK_LOW
- clock required is too low
MODE_CLOCK_RANGE
- clock/mode isn’t in a ClockRange
MODE_BAD_HVALUE
- horizontal timing was out of range
MODE_BAD_VVALUE
- vertical timing was out of range
MODE_BAD_VSCAN
- VScan value out of range
MODE_HSYNC_NARROW
- horizontal sync too narrow
MODE_HSYNC_WIDE
- horizontal sync too wide
MODE_HBLANK_NARROW
- horizontal blanking too narrow
MODE_HBLANK_WIDE
- horizontal blanking too wide
MODE_VSYNC_NARROW
- vertical sync too narrow
MODE_VSYNC_WIDE
- vertical sync too wide
MODE_VBLANK_NARROW
- vertical blanking too narrow
MODE_VBLANK_WIDE
- vertical blanking too wide
MODE_PANEL
- exceeds panel dimensions
MODE_INTERLACE_WIDTH
- width too large for interlaced mode
MODE_ONE_WIDTH
- only one width is supported
MODE_ONE_HEIGHT
- only one height is supported
MODE_ONE_SIZE
- only one resolution is supported
MODE_NO_REDUCED
- monitor doesn’t accept reduced blanking
MODE_NO_STEREO
- stereo modes not supported
MODE_STALE
- mode has become stale
MODE_BAD
- unspecified reason
MODE_ERROR
- error condition
Description
This enum is used to filter out modes not supported by the driver/hardware combination.
-
struct
drm_display_mode
¶ DRM kernel-internal display mode structure
Definition
struct drm_display_mode {
struct list_head head;
struct drm_mode_object base;
char name[DRM_DISPLAY_MODE_LEN];
enum drm_mode_status status;
unsigned int type;
int clock;
int hdisplay;
int hsync_start;
int hsync_end;
int htotal;
int hskew;
int vdisplay;
int vsync_start;
int vsync_end;
int vtotal;
int vscan;
unsigned int flags;
int width_mm;
int height_mm;
int crtc_clock;
int crtc_hdisplay;
int crtc_hblank_start;
int crtc_hblank_end;
int crtc_hsync_start;
int crtc_hsync_end;
int crtc_htotal;
int crtc_hskew;
int crtc_vdisplay;
int crtc_vblank_start;
int crtc_vblank_end;
int crtc_vsync_start;
int crtc_vsync_end;
int crtc_vtotal;
int * private;
int private_flags;
int vrefresh;
int hsync;
enum hdmi_picture_aspect picture_aspect_ratio;
};
Members
struct list_head head
- struct list_head for mode lists.
struct drm_mode_object base
A display mode is a normal modeset object, possibly including public userspace id.
FIXME:
This can probably be removed since the entire concept of userspace managing modes explicitly has never landed in upstream kernel mode setting support.
char name[DRM_DISPLAY_MODE_LEN]
- Human-readable name of the mode, filled out with
drm_mode_set_name()
. enum drm_mode_status status
- Status of the mode, used to filter out modes not supported by the
hardware. See enum
drm_mode_status
. unsigned int type
A bitmask of flags, mostly about the source of a mode. Possible flags are:
- DRM_MODE_TYPE_BUILTIN: Meant for hard-coded modes, effectively unused.
- DRM_MODE_TYPE_PREFERRED: Preferred mode, usually the native resolution of an LCD panel. There should only be one preferred mode per connector at any given time.
- DRM_MODE_TYPE_DRIVER: Mode created by the driver, which is all of them really. Drivers must set this bit for all modes they create and expose to userspace.
Plus a big list of flags which shouldn’t be used at all, but are still around since these flags are also used in the userspace ABI:
- DRM_MODE_TYPE_DEFAULT: Again a leftover, use DRM_MODE_TYPE_PREFERRED instead.
- DRM_MODE_TYPE_CLOCK_C and DRM_MODE_TYPE_CRTC_C: Define leftovers which are stuck around for hysterical raisins only. No one has an idea what they were meant for. Don’t use.
- DRM_MODE_TYPE_USERDEF: Mode defined by userspace, again a vestige from older kms designs where userspace had to first add a custom mode to the kernel’s mode list before it could use it. Don’t use.
int clock
- Pixel clock in kHz.
int hdisplay
- horizontal display size
int hsync_start
- horizontal sync start
int hsync_end
- horizontal sync end
int htotal
- horizontal total size
int hskew
- horizontal skew?!
int vdisplay
- vertical display size
int vsync_start
- vertical sync start
int vsync_end
- vertical sync end
int vtotal
- vertical total size
int vscan
- vertical scan?!
unsigned int flags
Sync and timing flags:
- DRM_MODE_FLAG_PHSYNC: horizontal sync is active high.
- DRM_MODE_FLAG_NHSYNC: horizontal sync is active low.
- DRM_MODE_FLAG_PVSYNC: vertical sync is active high.
- DRM_MODE_FLAG_NVSYNC: vertical sync is active low.
- DRM_MODE_FLAG_INTERLACE: mode is interlaced.
- DRM_MODE_FLAG_DBLSCAN: mode uses doublescan.
- DRM_MODE_FLAG_CSYNC: mode uses composite sync.
- DRM_MODE_FLAG_PCSYNC: composite sync is active high.
- DRM_MODE_FLAG_NCSYNC: composite sync is active low.
- DRM_MODE_FLAG_HSKEW: hskew provided (not used?).
- DRM_MODE_FLAG_BCAST: not used?
- DRM_MODE_FLAG_PIXMUX: not used?
- DRM_MODE_FLAG_DBLCLK: double-clocked mode.
- DRM_MODE_FLAG_CLKDIV2: half-clocked mode.
Additionally there’s flags to specify how 3D modes are packed:
- DRM_MODE_FLAG_3D_NONE: normal, non-3D mode.
- DRM_MODE_FLAG_3D_FRAME_PACKING: 2 full frames for left and right.
- DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE: interleaved like fields.
- DRM_MODE_FLAG_3D_LINE_ALTERNATIVE: interleaved lines.
- DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL: side-by-side full frames.
- DRM_MODE_FLAG_3D_L_DEPTH: ?
- DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH: ?
- DRM_MODE_FLAG_3D_TOP_AND_BOTTOM: frame split into top and bottom parts.
- DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF: frame split into left and right parts.
int width_mm
- Addressable size of the output in mm, projectors should set this to 0.
int height_mm
- Addressable size of the output in mm, projectors should set this to 0.
int crtc_clock
Actual pixel or dot clock in the hardware. This differs from the logical clock when e.g. using interlacing, double-clocking, stereo modes or other fancy stuff that changes the timings and signals actually sent over the wire.
This is again in kHz.
Note that with digital outputs like HDMI or DP there’s usually a massive confusion between the dot clock and the signal clock at the bit encoding level. Especially when a 8b/10b encoding is used and the difference is exactly a factor of 10.
int crtc_hdisplay
- hardware mode horizontal display size
int crtc_hblank_start
- hardware mode horizontal blank start
int crtc_hblank_end
- hardware mode horizontal blank end
int crtc_hsync_start
- hardware mode horizontal sync start
int crtc_hsync_end
- hardware mode horizontal sync end
int crtc_htotal
- hardware mode horizontal total size
int crtc_hskew
- hardware mode horizontal skew?!
int crtc_vdisplay
- hardware mode vertical display size
int crtc_vblank_start
- hardware mode vertical blank start
int crtc_vblank_end
- hardware mode vertical blank end
int crtc_vsync_start
- hardware mode vertical sync start
int crtc_vsync_end
- hardware mode vertical sync end
int crtc_vtotal
- hardware mode vertical total size
int * private
- Pointer for driver private data. This can only be used for mode objects passed to drivers in modeset operations. It shouldn’t be used by atomic drivers since they can store any additional data by subclassing state structures.
int private_flags
- Similar to private, but just an integer.
int vrefresh
Vertical refresh rate, for debug output in human readable form. Not used in a functional way.
This value is in Hz.
int hsync
Horizontal refresh rate, for debug output in human readable form. Not used in a functional way.
This value is in kHz.
enum hdmi_picture_aspect picture_aspect_ratio
- Field for setting the HDMI picture aspect ratio of a mode.
Description
The horizontal and vertical timings are defined per the following diagram.
Active Front Sync Back
Region Porch Porch
<-----------------------><----------------><-------------><-------------->
//////////////////////|
////////////////////// |
////////////////////// |.................. ................
_______________
<----- [hv]display ----->
<------------- [hv]sync_start ------------>
<--------------------- [hv]sync_end --------------------->
<-------------------------------- [hv]total ----------------------------->*
This structure contains two copies of timings. First are the plain timings,
which specify the logical mode, as it would be for a progressive 1:1 scanout
at the refresh rate userspace can observe through vblank timestamps. Then
there’s the hardware timings, which are corrected for interlacing,
double-clocking and similar things. They are provided as a convenience, and
can be appropriately computed using drm_mode_set_crtcinfo()
.
-
bool
drm_mode_is_stereo
(const struct drm_display_mode * mode)¶ check for stereo mode flags
Parameters
const struct drm_display_mode * mode
- drm_display_mode to check
Return
True if the mode is one of the stereo modes (like side-by-side), false if not.
-
void
drm_mode_debug_printmodeline
(const struct drm_display_mode * mode)¶ print a mode to dmesg
Parameters
const struct drm_display_mode * mode
- mode to print
Description
Describe mode using DRM_DEBUG.
-
struct drm_display_mode *
drm_mode_create
(struct drm_device * dev)¶ create a new display mode
Parameters
struct drm_device * dev
- DRM device
Description
Create a new, cleared drm_display_mode with kzalloc, allocate an ID for it and return it.
Return
Pointer to new mode on success, NULL on error.
-
void
drm_mode_destroy
(struct drm_device * dev, struct drm_display_mode * mode)¶ remove a mode
Parameters
struct drm_device * dev
- DRM device
struct drm_display_mode * mode
- mode to remove
Description
Release mode‘s unique ID, then free it mode structure itself using kfree.
-
void
drm_mode_probed_add
(struct drm_connector * connector, struct drm_display_mode * mode)¶ add a mode to a connector’s probed_mode list
Parameters
struct drm_connector * connector
- connector the new mode
struct drm_display_mode * mode
- mode data
Description
Add mode to connector‘s probed_mode list for later use. This list should then in a second step get filtered and all the modes actually supported by the hardware moved to the connector‘s modes list.
-
struct drm_display_mode *
drm_cvt_mode
(struct drm_device * dev, int hdisplay, int vdisplay, int vrefresh, bool reduced, bool interlaced, bool margins)¶ create a modeline based on the CVT algorithm
Parameters
struct drm_device * dev
- drm device
int hdisplay
- hdisplay size
int vdisplay
- vdisplay size
int vrefresh
- vrefresh rate
bool reduced
- whether to use reduced blanking
bool interlaced
- whether to compute an interlaced mode
bool margins
- whether to add margins (borders)
Description
This function is called to generate the modeline based on CVT algorithm according to the hdisplay, vdisplay, vrefresh. It is based from the VESA(TM) Coordinated Video Timing Generator by Graham Loveridge April 9, 2003 available at http://www.elo.utfsm.cl/~elo212/docs/CVTd6r1.xls
And it is copied from xf86CVTmode in xserver/hw/xfree86/modes/xf86cvt.c. What I have done is to translate it by using integer calculation.
Return
The modeline based on the CVT algorithm stored in a drm_display_mode object.
The display mode object is allocated with drm_mode_create()
. Returns NULL
when no mode could be allocated.
-
struct drm_display_mode *
drm_gtf_mode_complex
(struct drm_device * dev, int hdisplay, int vdisplay, int vrefresh, bool interlaced, int margins, int GTF_M, int GTF_2C, int GTF_K, int GTF_2J)¶ create the modeline based on the full GTF algorithm
Parameters
struct drm_device * dev
- drm device
int hdisplay
- hdisplay size
int vdisplay
- vdisplay size
int vrefresh
- vrefresh rate.
bool interlaced
- whether to compute an interlaced mode
int margins
- desired margin (borders) size
int GTF_M
- extended GTF formula parameters
int GTF_2C
- extended GTF formula parameters
int GTF_K
- extended GTF formula parameters
int GTF_2J
- extended GTF formula parameters
Description
GTF feature blocks specify C and J in multiples of 0.5, so we pass them in here multiplied by two. For a C of 40, pass in 80.
Return
The modeline based on the full GTF algorithm stored in a drm_display_mode object.
The display mode object is allocated with drm_mode_create()
. Returns NULL
when no mode could be allocated.
-
struct drm_display_mode *
drm_gtf_mode
(struct drm_device * dev, int hdisplay, int vdisplay, int vrefresh, bool interlaced, int margins)¶ create the modeline based on the GTF algorithm
Parameters
struct drm_device * dev
- drm device
int hdisplay
- hdisplay size
int vdisplay
- vdisplay size
int vrefresh
- vrefresh rate.
bool interlaced
- whether to compute an interlaced mode
int margins
- desired margin (borders) size
Description
return the modeline based on GTF algorithm
This function is to create the modeline based on the GTF algorithm. Generalized Timing Formula is derived from:
GTF Spreadsheet by Andy Morrish (1/5/97) available at http://www.vesa.org
And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c. What I have done is to translate it by using integer calculation. I also refer to the function of fb_get_mode in the file of drivers/video/fbmon.c
Standard GTF parameters:
M = 600
C = 40
K = 128
J = 20
Return
The modeline based on the GTF algorithm stored in a drm_display_mode object.
The display mode object is allocated with drm_mode_create()
. Returns NULL
when no mode could be allocated.
-
void
drm_display_mode_from_videomode
(const struct videomode * vm, struct drm_display_mode * dmode)¶ fill in dmode using vm,
Parameters
const struct videomode * vm
- videomode structure to use as source
struct drm_display_mode * dmode
- drm_display_mode structure to use as destination
Description
Fills out dmode using the display mode specified in vm.
-
void
drm_display_mode_to_videomode
(const struct drm_display_mode * dmode, struct videomode * vm)¶ fill in vm using dmode,
Parameters
const struct drm_display_mode * dmode
- drm_display_mode structure to use as source
struct videomode * vm
- videomode structure to use as destination
Description
Fills out vm using the display mode specified in dmode.
-
int
of_get_drm_display_mode
(struct device_node * np, struct drm_display_mode * dmode, int index)¶ get a drm_display_mode from devicetree
Parameters
struct device_node * np
- device_node with the timing specification
struct drm_display_mode * dmode
- will be set to the return value
int index
- index into the list of display timings in devicetree
Description
This function is expensive and should only be used, if only one mode is to be read from DT. To get multiple modes start with of_get_display_timings and work with that instead.
Return
0 on success, a negative errno code when no of videomode node was found.
-
void
drm_mode_set_name
(struct drm_display_mode * mode)¶ set the name on a mode
Parameters
struct drm_display_mode * mode
- name will be set in this mode
Description
Set the name of mode to a standard format which is <hdisplay>x<vdisplay> with an optional ‘i’ suffix for interlaced modes.
-
int
drm_mode_hsync
(const struct drm_display_mode * mode)¶ get the hsync of a mode
Parameters
const struct drm_display_mode * mode
- mode
Return
modes‘s hsync rate in kHz, rounded to the nearest integer. Calculates the value first if it is not yet set.
-
int
drm_mode_vrefresh
(const struct drm_display_mode * mode)¶ get the vrefresh of a mode
Parameters
const struct drm_display_mode * mode
- mode
Return
modes‘s vrefresh rate in Hz, rounded to the nearest integer. Calculates the value first if it is not yet set.
-
void
drm_mode_set_crtcinfo
(struct drm_display_mode * p, int adjust_flags)¶ set CRTC modesetting timing parameters
Parameters
struct drm_display_mode * p
- mode
int adjust_flags
- a combination of adjustment flags
Description
Setup the CRTC modesetting timing parameters for p, adjusting if necessary.
- The CRTC_INTERLACE_HALVE_V flag can be used to halve vertical timings of interlaced modes.
- The CRTC_STEREO_DOUBLE flag can be used to compute the timings for buffers containing two eyes (only adjust the timings when needed, eg. for “frame packing” or “side by side full”).
- The CRTC_NO_DBLSCAN and CRTC_NO_VSCAN flags request that adjustment not be performed for doublescan and vscan > 1 modes respectively.
-
void
drm_mode_copy
(struct drm_display_mode * dst, const struct drm_display_mode * src)¶ copy the mode
Parameters
struct drm_display_mode * dst
- mode to overwrite
const struct drm_display_mode * src
- mode to copy
Description
Copy an existing mode into another mode, preserving the object id and list head of the destination mode.
-
struct drm_display_mode *
drm_mode_duplicate
(struct drm_device * dev, const struct drm_display_mode * mode)¶ allocate and duplicate an existing mode
Parameters
struct drm_device * dev
- drm_device to allocate the duplicated mode for
const struct drm_display_mode * mode
- mode to duplicate
Description
Just allocate a new mode, copy the existing mode into it, and return a pointer to it. Used to create new instances of established modes.
Return
Pointer to duplicated mode on success, NULL on error.
-
bool
drm_mode_equal
(const struct drm_display_mode * mode1, const struct drm_display_mode * mode2)¶ test modes for equality
Parameters
const struct drm_display_mode * mode1
- first mode
const struct drm_display_mode * mode2
- second mode
Description
Check to see if mode1 and mode2 are equivalent.
Return
True if the modes are equal, false otherwise.
-
bool
drm_mode_equal_no_clocks
(const struct drm_display_mode * mode1, const struct drm_display_mode * mode2)¶ test modes for equality
Parameters
const struct drm_display_mode * mode1
- first mode
const struct drm_display_mode * mode2
- second mode
Description
Check to see if mode1 and mode2 are equivalent, but don’t check the pixel clocks.
Return
True if the modes are equal, false otherwise.
-
bool
drm_mode_equal_no_clocks_no_stereo
(const struct drm_display_mode * mode1, const struct drm_display_mode * mode2)¶ test modes for equality
Parameters
const struct drm_display_mode * mode1
- first mode
const struct drm_display_mode * mode2
- second mode
Description
Check to see if mode1 and mode2 are equivalent, but don’t check the pixel clocks nor the stereo layout.
Return
True if the modes are equal, false otherwise.
-
enum drm_mode_status
drm_mode_validate_basic
(const struct drm_display_mode * mode)¶ make sure the mode is somewhat sane
Parameters
const struct drm_display_mode * mode
- mode to check
Description
Check that the mode timings are at least somewhat reasonable. Any hardware specific limits are left up for each driver to check.
Return
The mode status
-
enum drm_mode_status
drm_mode_validate_size
(const struct drm_display_mode * mode, int maxX, int maxY)¶ make sure modes adhere to size constraints
Parameters
const struct drm_display_mode * mode
- mode to check
int maxX
- maximum width
int maxY
- maximum height
Description
This function is a helper which can be used to validate modes against size limitations of the DRM device/connector. If a mode is too big its status member is updated with the appropriate validation failure code. The list itself is not changed.
Return
The mode status
-
void
drm_mode_prune_invalid
(struct drm_device * dev, struct list_head * mode_list, bool verbose)¶ remove invalid modes from mode list
Parameters
struct drm_device * dev
- DRM device
struct list_head * mode_list
- list of modes to check
bool verbose
- be verbose about it
Description
This helper function can be used to prune a display mode list after validation has been completed. All modes who’s status is not MODE_OK will be removed from the list, and if verbose the status code and mode name is also printed to dmesg.
-
void
drm_mode_sort
(struct list_head * mode_list)¶ sort mode list
Parameters
struct list_head * mode_list
- list of drm_display_mode structures to sort
Description
Sort mode_list by favorability, moving good modes to the head of the list.
-
void
drm_mode_connector_list_update
(struct drm_connector * connector)¶ update the mode list for the connector
Parameters
struct drm_connector * connector
- the connector to update
Description
This moves the modes from the connector probed_modes list to the actual mode list. It compares the probed mode against the current list and only adds different/new modes.
This is just a helper functions doesn’t validate any modes itself and also doesn’t prune any invalid modes. Callers need to do that themselves.
-
bool
drm_mode_parse_command_line_for_connector
(const char * mode_option, struct drm_connector * connector, struct drm_cmdline_mode * mode)¶ parse command line modeline for connector
Parameters
const char * mode_option
- optional per connector mode option
struct drm_connector * connector
- connector to parse modeline for
struct drm_cmdline_mode * mode
- preallocated drm_cmdline_mode structure to fill out
Description
This parses mode_option command line modeline for modes and options to configure the connector. If mode_option is NULL the default command line modeline in fb_mode_option will be parsed instead.
This uses the same parameters as the fb modedb.c, except for an extra force-enable, force-enable-digital and force-disable bit at the end:
<xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
The intermediate drm_cmdline_mode structure is required to store additional options from the command line modline like the force-enable/disable flag.
Return
True if a valid modeline has been parsed, false otherwise.
-
struct drm_display_mode *
drm_mode_create_from_cmdline_mode
(struct drm_device * dev, struct drm_cmdline_mode * cmd)¶ convert a command line modeline into a DRM display mode
Parameters
struct drm_device * dev
- DRM device to create the new mode for
struct drm_cmdline_mode * cmd
- input command line modeline
Return
Pointer to converted mode on success, NULL on error.
Atomic Mode Setting Function Reference¶
-
void
drm_atomic_state_default_release
(struct drm_atomic_state * state)¶ release memory initialized by drm_atomic_state_init
Parameters
struct drm_atomic_state * state
- atomic state
Description
Free all the memory allocated by drm_atomic_state_init. This is useful for drivers that subclass the atomic state.
-
int
drm_atomic_state_init
(struct drm_device * dev, struct drm_atomic_state * state)¶ init new atomic state
Parameters
struct drm_device * dev
- DRM device
struct drm_atomic_state * state
- atomic state
Description
Default implementation for filling in a new atomic state. This is useful for drivers that subclass the atomic state.
-
struct drm_atomic_state *
drm_atomic_state_alloc
(struct drm_device * dev)¶ allocate atomic state
Parameters
struct drm_device * dev
- DRM device
Description
This allocates an empty atomic state to track updates.
-
void
drm_atomic_state_default_clear
(struct drm_atomic_state * state)¶ clear base atomic state
Parameters
struct drm_atomic_state * state
- atomic state
Description
Default implementation for clearing atomic state. This is useful for drivers that subclass the atomic state.
-
void
drm_atomic_state_clear
(struct drm_atomic_state * state)¶ clear state object
Parameters
struct drm_atomic_state * state
- atomic state
Description
When the w/w mutex algorithm detects a deadlock we need to back off and drop all locks. So someone else could sneak in and change the current modeset configuration. Which means that all the state assembled in state is no longer an atomic update to the current state, but to some arbitrary earlier state. Which could break assumptions the driver’s ->atomic_check likely relies on.
Hence we must clear all cached state and completely start over, using this function.
-
void
drm_atomic_state_free
(struct drm_atomic_state * state)¶ free all memory for an atomic state
Parameters
struct drm_atomic_state * state
- atomic state to deallocate
Description
This frees all memory associated with an atomic state, including all the per-object state for planes, crtcs and connectors.
-
struct drm_crtc_state *
drm_atomic_get_crtc_state
(struct drm_atomic_state * state, struct drm_crtc * crtc)¶ get crtc state
Parameters
struct drm_atomic_state * state
- global atomic state object
struct drm_crtc * crtc
- crtc to get state object for
Description
This function returns the crtc state for the given crtc, allocating it if needed. It will also grab the relevant crtc lock to make sure that the state is consistent.
Return
Either the allocated state or the error code encoded into the pointer. When the error is EDEADLK then the w/w mutex code has detected a deadlock and the entire atomic sequence must be restarted. All other errors are fatal.
-
int
drm_atomic_set_mode_for_crtc
(struct drm_crtc_state * state, struct drm_display_mode * mode)¶ set mode for CRTC
Parameters
struct drm_crtc_state * state
- the CRTC whose incoming state to update
struct drm_display_mode * mode
- kernel-internal mode to use for the CRTC, or NULL to disable
Description
Set a mode (originating from the kernel) on the desired CRTC state. Does not change any other state properties, including enable, active, or mode_changed.
Return
Zero on success, error code on failure. Cannot return -EDEADLK.
-
int
drm_atomic_set_mode_prop_for_crtc
(struct drm_crtc_state * state, struct drm_property_blob * blob)¶ set mode for CRTC
Parameters
struct drm_crtc_state * state
- the CRTC whose incoming state to update
struct drm_property_blob * blob
- pointer to blob property to use for mode
Description
Set a mode (originating from a blob property) on the desired CRTC state. This function will take a reference on the blob property for the CRTC state, and release the reference held on the state’s existing mode property, if any was set.
Return
Zero on success, error code on failure. Cannot return -EDEADLK.
-
int
drm_atomic_crtc_set_property
(struct drm_crtc * crtc, struct drm_crtc_state * state, struct drm_property * property, uint64_t val)¶ set property on CRTC
Parameters
struct drm_crtc * crtc
- the drm CRTC to set a property on
struct drm_crtc_state * state
- the state object to update with the new property value
struct drm_property * property
- the property to set
uint64_t val
- the new property value
Description
Use this instead of calling crtc->atomic_set_property directly. This function handles generic/core properties and calls out to driver’s ->:c:func:atomic_set_property() for driver properties. To ensure consistent behavior you must call this function rather than the driver hook directly.
Return
Zero on success, error code on failure
-
struct drm_plane_state *
drm_atomic_get_plane_state
(struct drm_atomic_state * state, struct drm_plane * plane)¶ get plane state
Parameters
struct drm_atomic_state * state
- global atomic state object
struct drm_plane * plane
- plane to get state object for
Description
This function returns the plane state for the given plane, allocating it if needed. It will also grab the relevant plane lock to make sure that the state is consistent.
Return
Either the allocated state or the error code encoded into the pointer. When the error is EDEADLK then the w/w mutex code has detected a deadlock and the entire atomic sequence must be restarted. All other errors are fatal.
-
int
drm_atomic_plane_set_property
(struct drm_plane * plane, struct drm_plane_state * state, struct drm_property * property, uint64_t val)¶ set property on plane
Parameters
struct drm_plane * plane
- the drm plane to set a property on
struct drm_plane_state * state
- the state object to update with the new property value
struct drm_property * property
- the property to set
uint64_t val
- the new property value
Description
Use this instead of calling plane->atomic_set_property directly. This function handles generic/core properties and calls out to driver’s ->:c:func:atomic_set_property() for driver properties. To ensure consistent behavior you must call this function rather than the driver hook directly.
Return
Zero on success, error code on failure
-
struct drm_connector_state *
drm_atomic_get_connector_state
(struct drm_atomic_state * state, struct drm_connector * connector)¶ get connector state
Parameters
struct drm_atomic_state * state
- global atomic state object
struct drm_connector * connector
- connector to get state object for
Description
This function returns the connector state for the given connector, allocating it if needed. It will also grab the relevant connector lock to make sure that the state is consistent.
Return
Either the allocated state or the error code encoded into the pointer. When the error is EDEADLK then the w/w mutex code has detected a deadlock and the entire atomic sequence must be restarted. All other errors are fatal.
-
int
drm_atomic_connector_set_property
(struct drm_connector * connector, struct drm_connector_state * state, struct drm_property * property, uint64_t val)¶ set property on connector.
Parameters
struct drm_connector * connector
- the drm connector to set a property on
struct drm_connector_state * state
- the state object to update with the new property value
struct drm_property * property
- the property to set
uint64_t val
- the new property value
Description
Use this instead of calling connector->atomic_set_property directly. This function handles generic/core properties and calls out to driver’s ->:c:func:atomic_set_property() for driver properties. To ensure consistent behavior you must call this function rather than the driver hook directly.
Return
Zero on success, error code on failure
-
int
drm_atomic_set_crtc_for_plane
(struct drm_plane_state * plane_state, struct drm_crtc * crtc)¶ set crtc for plane
Parameters
struct drm_plane_state * plane_state
- the plane whose incoming state to update
struct drm_crtc * crtc
- crtc to use for the plane
Description
Changing the assigned crtc for a plane requires us to grab the lock and state for the new crtc, as needed. This function takes care of all these details besides updating the pointer in the state object itself.
Return
0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK then the w/w mutex code has detected a deadlock and the entire atomic sequence must be restarted. All other errors are fatal.
-
void
drm_atomic_set_fb_for_plane
(struct drm_plane_state * plane_state, struct drm_framebuffer * fb)¶ set framebuffer for plane
Parameters
struct drm_plane_state * plane_state
- atomic state object for the plane
struct drm_framebuffer * fb
- fb to use for the plane
Description
Changing the assigned framebuffer for a plane requires us to grab a reference to the new fb and drop the reference to the old fb, if there is one. This function takes care of all these details besides updating the pointer in the state object itself.
-
int
drm_atomic_set_crtc_for_connector
(struct drm_connector_state * conn_state, struct drm_crtc * crtc)¶ set crtc for connector
Parameters
struct drm_connector_state * conn_state
- atomic state object for the connector
struct drm_crtc * crtc
- crtc to use for the connector
Description
Changing the assigned crtc for a connector requires us to grab the lock and state for the new crtc, as needed. This function takes care of all these details besides updating the pointer in the state object itself.
Return
0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK then the w/w mutex code has detected a deadlock and the entire atomic sequence must be restarted. All other errors are fatal.
-
int
drm_atomic_add_affected_connectors
(struct drm_atomic_state * state, struct drm_crtc * crtc)¶ add connectors for crtc
Parameters
struct drm_atomic_state * state
- atomic state
struct drm_crtc * crtc
- DRM crtc
Description
This function walks the current configuration and adds all connectors currently using crtc to the atomic configuration state. Note that this function must acquire the connection mutex. This can potentially cause unneeded seralization if the update is just for the planes on one crtc. Hence drivers and helpers should only call this when really needed (e.g. when a full modeset needs to happen due to some change).
Return
0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK then the w/w mutex code has detected a deadlock and the entire atomic sequence must be restarted. All other errors are fatal.
-
int
drm_atomic_add_affected_planes
(struct drm_atomic_state * state, struct drm_crtc * crtc)¶ add planes for crtc
Parameters
struct drm_atomic_state * state
- atomic state
struct drm_crtc * crtc
- DRM crtc
Description
This function walks the current configuration and adds all planes currently used by crtc to the atomic configuration state. This is useful when an atomic commit also needs to check all currently enabled plane on crtc, e.g. when changing the mode. It’s also useful when re-enabling a CRTC to avoid special code to force-enable all planes.
Since acquiring a plane state will always also acquire the w/w mutex of the current CRTC for that plane (if there is any) adding all the plane states for a CRTC will not reduce parallism of atomic updates.
Return
0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK then the w/w mutex code has detected a deadlock and the entire atomic sequence must be restarted. All other errors are fatal.
-
void
drm_atomic_legacy_backoff
(struct drm_atomic_state * state)¶ locking backoff for legacy ioctls
Parameters
struct drm_atomic_state * state
- atomic state
Description
This function should be used by legacy entry points which don’t understand -EDEADLK semantics. For simplicity this one will grab all modeset locks after the slowpath completed.
-
int
drm_atomic_check_only
(struct drm_atomic_state * state)¶ check whether a given config would work
Parameters
struct drm_atomic_state * state
- atomic configuration to check
Description
Note that this function can return -EDEADLK if the driver needed to acquire more locks but encountered a deadlock. The caller must then do the usual w/w backoff dance and restart. All other errors are fatal.
Return
0 on success, negative error code on failure.
-
int
drm_atomic_commit
(struct drm_atomic_state * state)¶ commit configuration atomically
Parameters
struct drm_atomic_state * state
- atomic configuration to check
Description
Note that this function can return -EDEADLK if the driver needed to acquire more locks but encountered a deadlock. The caller must then do the usual w/w backoff dance and restart. All other errors are fatal.
Also note that on successful execution ownership of state is transferred from the caller of this function to the function itself. The caller must not free or in any other way access state. If the function fails then the caller must clean up state itself.
Return
0 on success, negative error code on failure.
-
int
drm_atomic_nonblocking_commit
(struct drm_atomic_state * state)¶ atomic:c:type:nonblocking configuration commit
Parameters
struct drm_atomic_state * state
- atomic configuration to check
Description
Note that this function can return -EDEADLK if the driver needed to acquire more locks but encountered a deadlock. The caller must then do the usual w/w backoff dance and restart. All other errors are fatal.
Also note that on successful execution ownership of state is transferred from the caller of this function to the function itself. The caller must not free or in any other way access state. If the function fails then the caller must clean up state itself.
Return
0 on success, negative error code on failure.
-
void
drm_atomic_clean_old_fb
(struct drm_device * dev, unsigned plane_mask, int ret)¶ - Unset old_fb pointers and set plane->fb pointers.
Parameters
struct drm_device * dev
- drm device to check.
unsigned plane_mask
- plane mask for planes that were updated.
int ret
- return value, can be -EDEADLK for a retry.
Description
Before doing an update plane->old_fb is set to plane->fb, but before dropping the locks old_fb needs to be set to NULL and plane->fb updated. This is a common operation for each atomic update, so this call is split off as a helper.
-
void
drm_atomic_replace_property_blob
(struct drm_property_blob ** blob, struct drm_property_blob * new_blob, bool * replaced)¶ replace a blob property
Parameters
struct drm_property_blob ** blob
- a pointer to the member blob to be replaced
struct drm_property_blob * new_blob
- the new blob to replace with
bool * replaced
- whether the blob has been replaced
Return
Zero on success, error code on failure
-
int
drm_atomic_crtc_get_property
(struct drm_crtc * crtc, const struct drm_crtc_state * state, struct drm_property * property, uint64_t * val)¶ get property value from CRTC state
Parameters
struct drm_crtc * crtc
- the drm CRTC to set a property on
const struct drm_crtc_state * state
- the state object to get the property value from
struct drm_property * property
- the property to set
uint64_t * val
- return location for the property value
Description
This function handles generic/core properties and calls out to driver’s ->:c:func:atomic_get_property() for driver properties. To ensure consistent behavior you must call this function rather than the driver hook directly.
Return
Zero on success, error code on failure
-
int
drm_atomic_crtc_check
(struct drm_crtc * crtc, struct drm_crtc_state * state)¶ check crtc state
Parameters
struct drm_crtc * crtc
- crtc to check
struct drm_crtc_state * state
- crtc state to check
Description
Provides core sanity checks for crtc state.
Return
Zero on success, error code on failure
-
int
drm_atomic_plane_get_property
(struct drm_plane * plane, const struct drm_plane_state * state, struct drm_property * property, uint64_t * val)¶ get property value from plane state
Parameters
struct drm_plane * plane
- the drm plane to set a property on
const struct drm_plane_state * state
- the state object to get the property value from
struct drm_property * property
- the property to set
uint64_t * val
- return location for the property value
Description
This function handles generic/core properties and calls out to driver’s ->:c:func:atomic_get_property() for driver properties. To ensure consistent behavior you must call this function rather than the driver hook directly.
Return
Zero on success, error code on failure
-
int
drm_atomic_plane_check
(struct drm_plane * plane, struct drm_plane_state * state)¶ check plane state
Parameters
struct drm_plane * plane
- plane to check
struct drm_plane_state * state
- plane state to check
Description
Provides core sanity checks for plane state.
Return
Zero on success, error code on failure
-
int
drm_atomic_connector_get_property
(struct drm_connector * connector, const struct drm_connector_state * state, struct drm_property * property, uint64_t * val)¶ get property value from connector state
Parameters
struct drm_connector * connector
- the drm connector to set a property on
const struct drm_connector_state * state
- the state object to get the property value from
struct drm_property * property
- the property to set
uint64_t * val
- return location for the property value
Description
This function handles generic/core properties and calls out to driver’s ->:c:func:atomic_get_property() for driver properties. To ensure consistent behavior you must call this function rather than the driver hook directly.
Return
Zero on success, error code on failure
Frame Buffer Abstraction¶
Frame buffers are abstract memory objects that provide a source of pixels to scanout to a CRTC. Applications explicitly request the creation of frame buffers through the DRM_IOCTL_MODE_ADDFB(2) ioctls and receive an opaque handle that can be passed to the KMS CRTC control, plane configuration and page flip functions.
Frame buffers rely on the underneath memory manager for low-level memory
operations. When creating a frame buffer applications pass a memory
handle (or a list of memory handles for multi-planar formats) through
the drm_mode_fb_cmd2
argument. For drivers using GEM as their
userspace buffer management interface this would be a GEM handle.
Drivers are however free to use their own backing storage object
handles, e.g. vmwgfx directly exposes special TTM handles to userspace
and so expects TTM handles in the create ioctl and not GEM handles.
The lifetime of a drm framebuffer is controlled with a reference count,
drivers can grab additional references with
drm_framebuffer_reference()`and drop them again with
:c:func:`drm_framebuffer_unreference()
. For driver-private
framebuffers for which the last reference is never dropped (e.g. for the
fbdev framebuffer when the struct struct drm_framebuffer
is embedded into the fbdev helper struct)
drivers can manually clean up a framebuffer at module unload time with
drm_framebuffer_unregister_private()
.
DRM Format Handling¶
-
const char *
drm_get_format_name
(uint32_t format)¶ return a string for drm fourcc format
Parameters
uint32_t format
- format to compute name of
Description
Note that the buffer used by this function is globally shared and owned by the function itself.
FIXME: This isn’t really multithreading safe.
-
void
drm_fb_get_bpp_depth
(uint32_t format, unsigned int * depth, int * bpp)¶ get the bpp/depth values for format
Parameters
uint32_t format
- pixel format (DRM_FORMAT_*)
unsigned int * depth
- storage for the depth value
int * bpp
- storage for the bpp value
Description
This only supports RGB formats here for compat with code that doesn’t use pixel formats directly yet.
-
int
drm_format_num_planes
(uint32_t format)¶ get the number of planes for format
Parameters
uint32_t format
- pixel format (DRM_FORMAT_*)
Return
The number of planes used by the specified pixel format.
-
int
drm_format_plane_cpp
(uint32_t format, int plane)¶ determine the bytes per pixel value
Parameters
uint32_t format
- pixel format (DRM_FORMAT_*)
int plane
- plane index
Return
The bytes per pixel value for the specified plane.
-
int
drm_format_horz_chroma_subsampling
(uint32_t format)¶ get the horizontal chroma subsampling factor
Parameters
uint32_t format
- pixel format (DRM_FORMAT_*)
Return
The horizontal chroma subsampling factor for the specified pixel format.
-
int
drm_format_vert_chroma_subsampling
(uint32_t format)¶ get the vertical chroma subsampling factor
Parameters
uint32_t format
- pixel format (DRM_FORMAT_*)
Return
The vertical chroma subsampling factor for the specified pixel format.
-
int
drm_format_plane_width
(int width, uint32_t format, int plane)¶ width of the plane given the first plane
Parameters
int width
- width of the first plane
uint32_t format
- pixel format
int plane
- plane index
Return
The width of plane, given that the width of the first plane is width.
-
int
drm_format_plane_height
(int height, uint32_t format, int plane)¶ height of the plane given the first plane
Parameters
int height
- height of the first plane
uint32_t format
- pixel format
int plane
- plane index
Return
The height of plane, given that the height of the first plane is height.
Dumb Buffer Objects¶
The KMS API doesn’t standardize backing storage object creation and leaves it to driver-specific ioctls. Furthermore actually creating a buffer object even for GEM-based drivers is done through a driver-specific ioctl - GEM only has a common userspace interface for sharing and destroying objects. While not an issue for full-fledged graphics stacks that include device-specific userspace components (in libdrm for instance), this limit makes DRM-based early boot graphics unnecessarily complex.
Dumb objects partly alleviate the problem by providing a standard API to create dumb buffers suitable for scanout, which can then be used to create KMS frame buffers.
To support dumb objects drivers must implement the dumb_create, dumb_destroy and dumb_map_offset operations.
- int (*dumb_create)(struct drm_file *file_priv, struct
drm_device *dev, struct drm_mode_create_dumb *args);
The dumb_create operation creates a driver object (GEM or TTM
handle) suitable for scanout based on the width, height and depth
from the struct
struct drm_mode_create_dumb
argument. It fills the argument’s handle, pitch and size fields with a handle for the newly created object and its line pitch and size in bytes. - int (*dumb_destroy)(struct drm_file *file_priv, struct drm_device *dev, uint32_t handle); The dumb_destroy operation destroys a dumb object created by dumb_create.
- int (*dumb_map_offset)(struct drm_file *file_priv, struct
drm_device *dev, uint32_t handle, uint64_t *offset);
The dumb_map_offset operation associates an mmap fake offset with
the object given by the handle and returns it. Drivers must use the
drm_gem_create_mmap_offset()
function to associate the fake offset as described in ?.
Note that dumb objects may not be used for gpu acceleration, as has been attempted on some ARM embedded platforms. Such drivers really must have a hardware-specific ioctl to allocate suitable buffer objects.
Output Polling¶
void (*output_poll_changed)(struct drm_device *dev);
This operation notifies the driver that the status of one or more
connectors has changed. Drivers that use the fb helper can just call the
drm_fb_helper_hotplug_event()
function to handle this
operation.
KMS Initialization and Cleanup¶
A KMS device is abstracted and exposed as a set of planes, CRTCs, encoders and connectors. KMS drivers must thus create and initialize all those objects at load time after initializing mode setting.
CRTCs (struct drm_crtc
)¶
A CRTC is an abstraction representing a part of the chip that contains a pointer to a scanout buffer. Therefore, the number of CRTCs available determines how many independent scanout buffers can be active at any given time. The CRTC structure contains several fields to support this: a pointer to some video memory (abstracted as a frame buffer object), a display mode, and an (x, y) offset into the video memory to support panning or configurations where one piece of video memory spans multiple CRTCs.
CRTC Initialization¶
A KMS device must create and register at least one struct
struct drm_crtc
instance. The instance is
allocated and zeroed by the driver, possibly as part of a larger
structure, and registered with a call to drm_crtc_init()
with a pointer to CRTC functions.
Planes (struct drm_plane
)¶
A plane represents an image source that can be blended with or overlayed on top of a CRTC during the scanout process. Planes are associated with a frame buffer to crop a portion of the image memory (source) and optionally scale it to a destination size. The result is then blended with or overlayed on top of a CRTC.
The DRM core recognizes three types of planes:
- DRM_PLANE_TYPE_PRIMARY represents a “main” plane for a CRTC.
Primary planes are the planes operated upon by CRTC modesetting and
flipping operations described in the page_flip hook in
struct drm_crtc_funcs
. - DRM_PLANE_TYPE_CURSOR represents a “cursor” plane for a CRTC. Cursor planes are the planes operated upon by the DRM_IOCTL_MODE_CURSOR and DRM_IOCTL_MODE_CURSOR2 ioctls.
- DRM_PLANE_TYPE_OVERLAY represents all non-primary, non-cursor planes. Some drivers refer to these types of planes as “sprites” internally.
For compatibility with legacy userspace, only overlay planes are made available to userspace by default. Userspace clients may set the DRM_CLIENT_CAP_UNIVERSAL_PLANES client capability bit to indicate that they wish to receive a universal plane list containing all plane types.
Plane Initialization¶
To create a plane, a KMS drivers allocates and zeroes an instances of
struct drm_plane
(possibly as part of a
larger structure) and registers it with a call to
drm_universal_plane_init()
. The function takes a
bitmask of the CRTCs that can be associated with the plane, a pointer to
the plane functions, a list of format supported formats, and the type of
plane (primary, cursor, or overlay) being initialized.
Cursor and overlay planes are optional. All drivers should provide one primary plane per CRTC (although this requirement may change in the future); drivers that do not wish to provide special handling for primary planes may make use of the helper functions described in ? to create and register a primary plane with standard capabilities.
Encoders (struct drm_encoder
)¶
An encoder takes pixel data from a CRTC and converts it to a format suitable for any attached connectors. On some devices, it may be possible to have a CRTC send data to more than one encoder. In that case, both encoders would receive data from the same scanout buffer, resulting in a “cloned” display configuration across the connectors attached to each encoder.
Encoder Initialization¶
As for CRTCs, a KMS driver must create, initialize and register at least
one struct drm_encoder
instance. The
instance is allocated and zeroed by the driver, possibly as part of a
larger structure.
Drivers must initialize the struct drm_encoder
possible_crtcs and possible_clones fields before
registering the encoder. Both fields are bitmasks of respectively the
CRTCs that the encoder can be connected to, and sibling encoders
candidate for cloning.
After being initialized, the encoder must be registered with a call to
drm_encoder_init()
. The function takes a pointer to the
encoder functions and an encoder type. Supported types are
- DRM_MODE_ENCODER_DAC for VGA and analog on DVI-I/DVI-A
- DRM_MODE_ENCODER_TMDS for DVI, HDMI and (embedded) DisplayPort
- DRM_MODE_ENCODER_LVDS for display panels
- DRM_MODE_ENCODER_TVDAC for TV output (Composite, S-Video, Component, SCART)
- DRM_MODE_ENCODER_VIRTUAL for virtual machine displays
Encoders must be attached to a CRTC to be used. DRM drivers leave encoders unattached at initialization time. Applications (or the fbdev compatibility layer when implemented) are responsible for attaching the encoders they want to use to a CRTC.
Connectors (struct drm_connector
)¶
A connector is the final destination for pixel data on a device, and usually connects directly to an external display device like a monitor or laptop panel. A connector can only be attached to one encoder at a time. The connector is also the structure where information about the attached display is kept, so it contains fields for display data, EDID data, DPMS & connection status, and information about modes supported on the attached displays.
Connector Initialization¶
Finally a KMS driver must create, initialize, register and attach at
least one struct drm_connector
instance. The instance is created as other KMS objects and initialized
by setting the following fields.
- interlace_allowed
- Whether the connector can handle interlaced modes.
- doublescan_allowed
- Whether the connector can handle doublescan.
- display_info
- Display information is filled from EDID information when a display is detected. For non hot-pluggable displays such as flat panels in embedded systems, the driver should initialize the display_info.width_mm and display_info.height_mm fields with the physical size of the display.
- polled
Connector polling mode, a combination of
- DRM_CONNECTOR_POLL_HPD
- The connector generates hotplug events and doesn’t need to be periodically polled. The CONNECT and DISCONNECT flags must not be set together with the HPD flag.
- DRM_CONNECTOR_POLL_CONNECT
- Periodically poll the connector for connection.
- DRM_CONNECTOR_POLL_DISCONNECT
- Periodically poll the connector for disconnection.
Set to 0 for connectors that don’t support connection status discovery.
The connector is then registered with a call to
drm_connector_init()
with a pointer to the connector
functions and a connector type, and exposed through sysfs with a call to
drm_connector_register()
.
Supported connector types are
- DRM_MODE_CONNECTOR_VGA
- DRM_MODE_CONNECTOR_DVII
- DRM_MODE_CONNECTOR_DVID
- DRM_MODE_CONNECTOR_DVIA
- DRM_MODE_CONNECTOR_Composite
- DRM_MODE_CONNECTOR_SVIDEO
- DRM_MODE_CONNECTOR_LVDS
- DRM_MODE_CONNECTOR_Component
- DRM_MODE_CONNECTOR_9PinDIN
- DRM_MODE_CONNECTOR_DisplayPort
- DRM_MODE_CONNECTOR_HDMIA
- DRM_MODE_CONNECTOR_HDMIB
- DRM_MODE_CONNECTOR_TV
- DRM_MODE_CONNECTOR_eDP
- DRM_MODE_CONNECTOR_VIRTUAL
Connectors must be attached to an encoder to be used. For devices that
map connectors to encoders 1:1, the connector should be attached at
initialization time with a call to
drm_mode_connector_attach_encoder()
. The driver must
also set the struct drm_connector
encoder field to point to the attached encoder.
Finally, drivers must initialize the connectors state change detection
with a call to drm_kms_helper_poll_init()
. If at least
one connector is pollable but can’t generate hotplug interrupts
(indicated by the DRM_CONNECTOR_POLL_CONNECT and
DRM_CONNECTOR_POLL_DISCONNECT connector flags), a delayed work will
automatically be queued to periodically poll for changes. Connectors
that can generate hotplug interrupts must be marked with the
DRM_CONNECTOR_POLL_HPD flag instead, and their interrupt handler must
call drm_helper_hpd_irq_event()
. The function will
queue a delayed work to check the state of all connectors, but no
periodic polling will be done.
Connector Operations¶
Note
Unless otherwise state, all operations are mandatory.
DPMS¶
void (*dpms)(struct drm_connector *connector, int mode); The DPMS operation sets the power state of a connector. The mode argument is one of
- DRM_MODE_DPMS_ON
- DRM_MODE_DPMS_STANDBY
- DRM_MODE_DPMS_SUSPEND
- DRM_MODE_DPMS_OFF
In all but DPMS_ON mode the encoder to which the connector is attached should put the display in low-power mode by driving its signals appropriately. If more than one connector is attached to the encoder care should be taken not to change the power state of other displays as a side effect. Low-power mode should be propagated to the encoders and CRTCs when all related connectors are put in low-power mode.
Modes¶
int (*fill_modes)(struct drm_connector *connector, uint32_t
max_width, uint32_t max_height);
Fill the mode list with all supported modes for the connector. If the
max_width
and max_height
arguments are non-zero, the
implementation must ignore all modes wider than max_width
or higher
than max_height
.
The connector must also fill in this operation its display_info width_mm and height_mm fields with the connected display physical size in millimeters. The fields should be set to 0 if the value isn’t known or is not applicable (for instance for projector devices).
Connection Status¶
The connection status is updated through polling or hotplug events when
supported (see ?). The status value is reported to userspace through
ioctls and must not be used inside the driver, as it only gets
initialized by a call to drm_mode_getconnector()
from
userspace.
enum drm_connector_status (*detect)(struct drm_connector
*connector, bool force);
Check to see if anything is attached to the connector. The force
parameter is set to false whilst polling or to true when checking the
connector due to user request. force
can be used by the driver to
avoid expensive, destructive operations during automated probing.
Return connector_status_connected if something is connected to the connector, connector_status_disconnected if nothing is connected and connector_status_unknown if the connection state isn’t known.
Drivers should only return connector_status_connected if the connection status has really been probed as connected. Connectors that can’t detect the connection status, or failed connection status probes, should return connector_status_unknown.
Cleanup¶
The DRM core manages its objects’ lifetime. When an object is not needed
anymore the core calls its destroy function, which must clean up and
free every resource allocated for the object. Every
drm_*_init()
call must be matched with a corresponding
drm_*_cleanup()
call to cleanup CRTCs
(drm_crtc_cleanup()
), planes
(drm_plane_cleanup()
), encoders
(drm_encoder_cleanup()
) and connectors
(drm_connector_cleanup()
). Furthermore, connectors that
have been added to sysfs must be removed by a call to
drm_connector_unregister()
before calling
drm_connector_cleanup()
.
Connectors state change detection must be cleanup up with a call to
drm_kms_helper_poll_fini()
.
Output discovery and initialization example¶
void intel_crt_init(struct drm_device *dev)
{
struct drm_connector *connector;
struct intel_output *intel_output;
intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
if (!intel_output)
return;
connector = &intel_output->base;
drm_connector_init(dev, &intel_output->base,
&intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs,
DRM_MODE_ENCODER_DAC);
drm_mode_connector_attach_encoder(&intel_output->base,
&intel_output->enc);
/* Set up the DDC bus. */
intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A");
if (!intel_output->ddc_bus) {
dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
"failed.\n");
return;
}
intel_output->type = INTEL_OUTPUT_ANALOG;
connector->interlace_allowed = 0;
connector->doublescan_allowed = 0;
drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs);
drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
drm_connector_register(connector);
}
In the example above (taken from the i915 driver), a CRTC, connector and encoder combination is created. A device-specific i2c bus is also created for fetching EDID data and performing monitor detection. Once the process is complete, the new connector is registered with sysfs to make its properties available to applications.
KMS API Functions¶
-
const char *
drm_get_connector_status_name
(enum drm_connector_status status)¶ return a string for connector status
Parameters
enum drm_connector_status status
- connector status to compute name of
Description
In contrast to the other drm_get_*_name functions this one here returns a const pointer and hence is threadsafe.
-
const char *
drm_get_subpixel_order_name
(enum subpixel_order order)¶ return a string for a given subpixel enum
Parameters
enum subpixel_order order
- enum of subpixel_order
Description
Note you could abuse this and return something out of bounds, but that would be a caller error. No unscrubbed user data should make it here.
-
struct drm_mode_object *
drm_mode_object_find
(struct drm_device * dev, uint32_t id, uint32_t type)¶ look up a drm object with static lifetime
Parameters
struct drm_device * dev
- drm device
uint32_t id
- id of the mode object
uint32_t type
- type of the mode object
Description
This function is used to look up a modeset object. It will acquire a
reference for reference counted objects. This reference must be dropped again
by callind drm_mode_object_unreference()
.
-
void
drm_mode_object_unreference
(struct drm_mode_object * obj)¶ decr the object refcnt
Parameters
struct drm_mode_object * obj
- mode_object
Description
This functions decrements the object’s refcount if it is a refcounted modeset
object. It is a no-op on any other object. This is used to drop references
acquired with drm_mode_object_reference()
.
-
void
drm_mode_object_reference
(struct drm_mode_object * obj)¶ incr the object refcnt
Parameters
struct drm_mode_object * obj
- mode_object
Description
This functions increments the object’s refcount if it is a refcounted modeset
object. It is a no-op on any other object. References should be dropped again
by calling drm_mode_object_unreference()
.
Parameters
struct drm_crtc * crtc
- CRTC to turn off
Return
Zero on success, error code on failure.
-
int
drm_crtc_force_disable_all
(struct drm_device * dev)¶ Forcibly turn off all enabled CRTCs
Parameters
struct drm_device * dev
- DRM device whose CRTCs to turn off
Description
Drivers may want to call this on unload to ensure that all displays are unlit and the GPU is in a consistent, low power state. Takes modeset locks.
Return
Zero on success, error code on failure.
-
int
drm_framebuffer_init
(struct drm_device * dev, struct drm_framebuffer * fb, const struct drm_framebuffer_funcs * funcs)¶ initialize a framebuffer
Parameters
struct drm_device * dev
- DRM device
struct drm_framebuffer * fb
- framebuffer to be initialized
const struct drm_framebuffer_funcs * funcs
- ... with these functions
Description
Allocates an ID for the framebuffer’s parent mode object, sets its mode functions & device file and adds it to the master fd list.
IMPORTANT: This functions publishes the fb and makes it available for concurrent access by other users. Which means by this point the fb _must_ be fully set up - since all the fb attributes are invariant over its lifetime, no further locking but only correct reference counting is required.
Return
Zero on success, error code on failure.
-
struct drm_framebuffer *
drm_framebuffer_lookup
(struct drm_device * dev, uint32_t id)¶ look up a drm framebuffer and grab a reference
Parameters
struct drm_device * dev
- drm device
uint32_t id
- id of the fb object
Description
If successful, this grabs an additional reference to the framebuffer - callers need to make sure to eventually unreference the returned framebuffer again, using drm_framebuffer_unreference.
-
void
drm_framebuffer_unregister_private
(struct drm_framebuffer * fb)¶ unregister a private fb from the lookup idr
Parameters
struct drm_framebuffer * fb
- fb to unregister
Description
Drivers need to call this when cleaning up driver-private framebuffers, e.g. those used for fbdev. Note that the caller must hold a reference of it’s own, i.e. the object may not be destroyed through this call (since it’ll lead to a locking inversion).
-
void
drm_framebuffer_cleanup
(struct drm_framebuffer * fb)¶ remove a framebuffer object
Parameters
struct drm_framebuffer * fb
- framebuffer to remove
Description
Cleanup framebuffer. This function is intended to be used from the drivers ->destroy callback. It can also be used to clean up driver private framebuffers embedded into a larger structure.
Note that this function does not remove the fb from active usuage - if it is still used anywhere, hilarity can ensue since userspace could call getfb on the id and get back -EINVAL. Obviously no concern at driver unload time.
Also, the framebuffer will not be removed from the lookup idr - for user-created framebuffers this will happen in in the rmfb ioctl. For driver-private objects (e.g. for fbdev) drivers need to explicitly call drm_framebuffer_unregister_private.
-
void
drm_framebuffer_remove
(struct drm_framebuffer * fb)¶ remove and unreference a framebuffer object
Parameters
struct drm_framebuffer * fb
- framebuffer to remove
Description
Scans all the CRTCs and planes in dev‘s mode_config. If they’re using fb, removes it, setting it to NULL. Then drops the reference to the passed-in framebuffer. Might take the modeset locks.
Note that this function optimizes the cleanup away if the caller holds the last reference to the framebuffer. It is also guaranteed to not take the modeset locks in this case.
-
int
drm_crtc_init_with_planes
(struct drm_device * dev, struct drm_crtc * crtc, struct drm_plane * primary, struct drm_plane * cursor, const struct drm_crtc_funcs * funcs, const char * name, ...)¶ Initialise a new CRTC object with specified primary and cursor planes.
Parameters
struct drm_device * dev
- DRM device
struct drm_crtc * crtc
- CRTC object to init
struct drm_plane * primary
- Primary plane for CRTC
struct drm_plane * cursor
- Cursor plane for CRTC
const struct drm_crtc_funcs * funcs
- callbacks for the new CRTC
const char * name
- printf style format string for the CRTC name, or NULL for default name
...
- variable arguments
Description
Inits a new object created as base part of a driver crtc object.
Return
Zero on success, error code on failure.
Parameters
struct drm_crtc * crtc
- CRTC to cleanup
Description
This function cleans up crtc and removes it from the DRM mode setting core. Note that the function does not free the crtc structure itself, this is the responsibility of the caller.
-
int
drm_display_info_set_bus_formats
(struct drm_display_info * info, const u32 * formats, unsigned int num_formats)¶ set the supported bus formats
Parameters
struct drm_display_info * info
- display info to store bus formats in
const u32 * formats
- array containing the supported bus formats
unsigned int num_formats
- the number of entries in the fmts array
Description
Store the supported bus formats in display info structure. See MEDIA_BUS_FMT_* definitions in include/uapi/linux/media-bus-format.h for a full list of available formats.
-
int
drm_connector_init
(struct drm_device * dev, struct drm_connector * connector, const struct drm_connector_funcs * funcs, int connector_type)¶ Init a preallocated connector
Parameters
struct drm_device * dev
- DRM device
struct drm_connector * connector
- the connector to init
const struct drm_connector_funcs * funcs
- callbacks for this connector
int connector_type
- user visible type of the connector
Description
Initialises a preallocated connector. Connectors should be subclassed as part of driver connector objects.
Return
Zero on success, error code on failure.
-
void
drm_connector_cleanup
(struct drm_connector * connector)¶ cleans up an initialised connector
Parameters
struct drm_connector * connector
- connector to cleanup
Description
Cleans up the connector but doesn’t free the object.
-
int
drm_connector_register
(struct drm_connector * connector)¶ register a connector
Parameters
struct drm_connector * connector
- the connector to register
Description
Register userspace interfaces for a connector
Return
Zero on success, error code on failure.
-
void
drm_connector_unregister
(struct drm_connector * connector)¶ unregister a connector
Parameters
struct drm_connector * connector
- the connector to unregister
Description
Unregister userspace interfaces for a connector
-
int
drm_encoder_init
(struct drm_device * dev, struct drm_encoder * encoder, const struct drm_encoder_funcs * funcs, int encoder_type, const char * name, ...)¶ Init a preallocated encoder
Parameters
struct drm_device * dev
- drm device
struct drm_encoder * encoder
- the encoder to init
const struct drm_encoder_funcs * funcs
- callbacks for this encoder
int encoder_type
- user visible type of the encoder
const char * name
- printf style format string for the encoder name, or NULL for default name
...
- variable arguments
Description
Initialises a preallocated encoder. Encoder should be subclassed as part of driver encoder objects.
Return
Zero on success, error code on failure.
-
void
drm_encoder_cleanup
(struct drm_encoder * encoder)¶ cleans up an initialised encoder
Parameters
struct drm_encoder * encoder
- encoder to cleanup
Description
Cleans up the encoder but doesn’t free the object.
-
int
drm_universal_plane_init
(struct drm_device * dev, struct drm_plane * plane, unsigned long possible_crtcs, const struct drm_plane_funcs * funcs, const uint32_t * formats, unsigned int format_count, enum drm_plane_type type, const char * name, ...)¶ Initialize a new universal plane object
Parameters
struct drm_device * dev
- DRM device
struct drm_plane * plane
- plane object to init
unsigned long possible_crtcs
- bitmask of possible CRTCs
const struct drm_plane_funcs * funcs
- callbacks for the new plane
const uint32_t * formats
- array of supported formats (``DRM_FORMAT_``*)
unsigned int format_count
- number of elements in formats
enum drm_plane_type type
- type of plane (overlay, primary, cursor)
const char * name
- printf style format string for the plane name, or NULL for default name
...
- variable arguments
Description
Initializes a plane object of type type.
Return
Zero on success, error code on failure.
-
int
drm_plane_init
(struct drm_device * dev, struct drm_plane * plane, unsigned long possible_crtcs, const struct drm_plane_funcs * funcs, const uint32_t * formats, unsigned int format_count, bool is_primary)¶ Initialize a legacy plane
Parameters
struct drm_device * dev
- DRM device
struct drm_plane * plane
- plane object to init
unsigned long possible_crtcs
- bitmask of possible CRTCs
const struct drm_plane_funcs * funcs
- callbacks for the new plane
const uint32_t * formats
- array of supported formats (``DRM_FORMAT_``*)
unsigned int format_count
- number of elements in formats
bool is_primary
- plane type (primary vs overlay)
Description
Legacy API to initialize a DRM plane.
New drivers should call drm_universal_plane_init()
instead.
Return
Zero on success, error code on failure.
Parameters
struct drm_plane * plane
- plane to cleanup
Description
This function cleans up plane and removes it from the DRM mode setting core. Note that the function does not free the plane structure itself, this is the responsibility of the caller.
-
struct drm_plane *
drm_plane_from_index
(struct drm_device * dev, int idx)¶ find the registered plane at an index
Parameters
struct drm_device * dev
- DRM device
int idx
- index of registered plane to find for
Description
Given a plane index, return the registered plane from DRM device’s list of planes with matching index.
Parameters
struct drm_plane * plane
- plane to disable
Description
Forces the plane to be disabled.
Used when the plane’s current framebuffer is destroyed, and when restoring fbdev mode.
-
int
drm_mode_create_dvi_i_properties
(struct drm_device * dev)¶ create DVI-I specific connector properties
Parameters
struct drm_device * dev
- DRM device
Description
Called by a driver the first time a DVI-I connector is made.
-
int
drm_mode_create_tv_properties
(struct drm_device * dev, unsigned int num_modes, const char *const modes[])¶ create TV specific connector properties
Parameters
struct drm_device * dev
- DRM device
unsigned int num_modes
- number of different TV formats (modes) supported
const char *const modes[]
- undescribed
Description
Called by a driver’s TV initialization routine, this function creates the TV specific connector properties for a given device. Caller is responsible for allocating a list of format names and passing them to this routine.
-
int
drm_mode_create_scaling_mode_property
(struct drm_device * dev)¶ create scaling mode property
Parameters
struct drm_device * dev
- DRM device
Description
Called by a driver the first time it’s needed, must be attached to desired connectors.
-
int
drm_mode_create_aspect_ratio_property
(struct drm_device * dev)¶ create aspect ratio property
Parameters
struct drm_device * dev
- DRM device
Description
Called by a driver the first time it’s needed, must be attached to desired connectors.
Return
Zero on success, negative errno on failure.
-
int
drm_mode_create_dirty_info_property
(struct drm_device * dev)¶ create dirty property
Parameters
struct drm_device * dev
- DRM device
Description
Called by a driver the first time it’s needed, must be attached to desired connectors.
-
int
drm_mode_create_suggested_offset_properties
(struct drm_device * dev)¶ create suggests offset properties
Parameters
struct drm_device * dev
- DRM device
Description
Create the the suggested x/y offset property for connectors.
-
int
drm_mode_set_config_internal
(struct drm_mode_set * set)¶ helper to call ->set_config
Parameters
struct drm_mode_set * set
- modeset config to set
Description
This is a little helper to wrap internal calls to the ->set_config driver interface. The only thing it adds is correct refcounting dance.
Return
Zero on success, negative errno on failure.
-
void
drm_crtc_get_hv_timing
(const struct drm_display_mode * mode, int * hdisplay, int * vdisplay)¶ Fetches hdisplay/vdisplay for given mode
Parameters
const struct drm_display_mode * mode
- mode to query
int * hdisplay
- hdisplay value to fill in
int * vdisplay
- vdisplay value to fill in
Description
The vdisplay value will be doubled if the specified mode is a stereo mode of the appropriate layout.
-
int
drm_crtc_check_viewport
(const struct drm_crtc * crtc, int x, int y, const struct drm_display_mode * mode, const struct drm_framebuffer * fb)¶ Checks that a framebuffer is big enough for the CRTC viewport
Parameters
const struct drm_crtc * crtc
- CRTC that framebuffer will be displayed on
int x
- x panning
int y
- y panning
const struct drm_display_mode * mode
- mode that framebuffer will be displayed under
const struct drm_framebuffer * fb
- framebuffer to check size of
-
uint32_t
drm_mode_legacy_fb_format
(uint32_t bpp, uint32_t depth)¶ compute drm fourcc code from legacy description
Parameters
uint32_t bpp
- bits per pixels
uint32_t depth
- bit depth per pixel
Description
Computes a drm fourcc pixel format code for the given bpp/depth values. Useful in fbdev emulation code, since that deals in those values.
-
struct drm_property *
drm_property_create
(struct drm_device * dev, int flags, const char * name, int num_values)¶ create a new property type
Parameters
struct drm_device * dev
- drm device
int flags
- flags specifying the property type
const char * name
- name of the property
int num_values
- number of pre-defined values
Description
This creates a new generic drm property which can then be attached to a drm object with drm_object_attach_property. The returned property object must be freed with drm_property_destroy.
Note that the DRM core keeps a per-device list of properties and that, if
drm_mode_config_cleanup()
is called, it will destroy all properties created
by the driver.
Return
A pointer to the newly created property on success, NULL on failure.
-
struct drm_property *
drm_property_create_enum
(struct drm_device * dev, int flags, const char * name, const struct drm_prop_enum_list * props, int num_values)¶ create a new enumeration property type
Parameters
struct drm_device * dev
- drm device
int flags
- flags specifying the property type
const char * name
- name of the property
const struct drm_prop_enum_list * props
- enumeration lists with property values
int num_values
- number of pre-defined values
Description
This creates a new generic drm property which can then be attached to a drm object with drm_object_attach_property. The returned property object must be freed with drm_property_destroy.
Userspace is only allowed to set one of the predefined values for enumeration properties.
Return
A pointer to the newly created property on success, NULL on failure.
-
struct drm_property *
drm_property_create_bitmask
(struct drm_device * dev, int flags, const char * name, const struct drm_prop_enum_list * props, int num_props, uint64_t supported_bits)¶ create a new bitmask property type
Parameters
struct drm_device * dev
- drm device
int flags
- flags specifying the property type
const char * name
- name of the property
const struct drm_prop_enum_list * props
- enumeration lists with property bitflags
int num_props
- size of the props array
uint64_t supported_bits
- bitmask of all supported enumeration values
Description
This creates a new bitmask drm property which can then be attached to a drm object with drm_object_attach_property. The returned property object must be freed with drm_property_destroy.
Compared to plain enumeration properties userspace is allowed to set any or’ed together combination of the predefined property bitflag values
Return
A pointer to the newly created property on success, NULL on failure.
-
struct drm_property *
drm_property_create_range
(struct drm_device * dev, int flags, const char * name, uint64_t min, uint64_t max)¶ create a new unsigned ranged property type
Parameters
struct drm_device * dev
- drm device
int flags
- flags specifying the property type
const char * name
- name of the property
uint64_t min
- minimum value of the property
uint64_t max
- maximum value of the property
Description
This creates a new generic drm property which can then be attached to a drm object with drm_object_attach_property. The returned property object must be freed with drm_property_destroy.
Userspace is allowed to set any unsigned integer value in the (min, max) range inclusive.
Return
A pointer to the newly created property on success, NULL on failure.
-
struct drm_property *
drm_property_create_signed_range
(struct drm_device * dev, int flags, const char * name, int64_t min, int64_t max)¶ create a new signed ranged property type
Parameters
struct drm_device * dev
- drm device
int flags
- flags specifying the property type
const char * name
- name of the property
int64_t min
- minimum value of the property
int64_t max
- maximum value of the property
Description
This creates a new generic drm property which can then be attached to a drm object with drm_object_attach_property. The returned property object must be freed with drm_property_destroy.
Userspace is allowed to set any signed integer value in the (min, max) range inclusive.
Return
A pointer to the newly created property on success, NULL on failure.
-
struct drm_property *
drm_property_create_object
(struct drm_device * dev, int flags, const char * name, uint32_t type)¶ create a new object property type
Parameters
struct drm_device * dev
- drm device
int flags
- flags specifying the property type
const char * name
- name of the property
uint32_t type
- object type from DRM_MODE_OBJECT_* defines
Description
This creates a new generic drm property which can then be attached to a drm object with drm_object_attach_property. The returned property object must be freed with drm_property_destroy.
Userspace is only allowed to set this to any property value of the given type. Only useful for atomic properties, which is enforced.
Return
A pointer to the newly created property on success, NULL on failure.
-
struct drm_property *
drm_property_create_bool
(struct drm_device * dev, int flags, const char * name)¶ create a new boolean property type
Parameters
struct drm_device * dev
- drm device
int flags
- flags specifying the property type
const char * name
- name of the property
Description
This creates a new generic drm property which can then be attached to a drm object with drm_object_attach_property. The returned property object must be freed with drm_property_destroy.
This is implemented as a ranged property with only {0, 1} as valid values.
Return
A pointer to the newly created property on success, NULL on failure.
-
int
drm_property_add_enum
(struct drm_property * property, int index, uint64_t value, const char * name)¶ add a possible value to an enumeration property
Parameters
struct drm_property * property
- enumeration property to change
int index
- index of the new enumeration
uint64_t value
- value of the new enumeration
const char * name
- symbolic name of the new enumeration
Description
This functions adds enumerations to a property.
It’s use is deprecated, drivers should use one of the more specific helpers to directly create the property with all enumerations already attached.
Return
Zero on success, error code on failure.
-
void
drm_property_destroy
(struct drm_device * dev, struct drm_property * property)¶ destroy a drm property
Parameters
struct drm_device * dev
- drm device
struct drm_property * property
- property to destry
Description
This function frees a property including any attached resources like enumeration values.
-
void
drm_object_attach_property
(struct drm_mode_object * obj, struct drm_property * property, uint64_t init_val)¶ attach a property to a modeset object
Parameters
struct drm_mode_object * obj
- drm modeset object
struct drm_property * property
- property to attach
uint64_t init_val
- initial value of the property
Description
This attaches the given property to the modeset object with the given initial value. Currently this function cannot fail since the properties are stored in a statically sized array.
-
int
drm_object_property_set_value
(struct drm_mode_object * obj, struct drm_property * property, uint64_t val)¶ set the value of a property
Parameters
struct drm_mode_object * obj
- drm mode object to set property value for
struct drm_property * property
- property to set
uint64_t val
- value the property should be set to
Description
This functions sets a given property on a given object. This function only changes the software state of the property, it does not call into the driver’s ->set_property callback.
Return
Zero on success, error code on failure.
-
int
drm_object_property_get_value
(struct drm_mode_object * obj, struct drm_property * property, uint64_t * val)¶ retrieve the value of a property
Parameters
struct drm_mode_object * obj
- drm mode object to get property value from
struct drm_property * property
- property to retrieve
uint64_t * val
- storage for the property value
Description
This function retrieves the softare state of the given property for the given property. Since there is no driver callback to retrieve the current property value this might be out of sync with the hardware, depending upon the driver and property.
Return
Zero on success, error code on failure.
-
struct drm_property_blob *
drm_property_create_blob
(struct drm_device * dev, size_t length, const void * data)¶ Create new blob property
Parameters
struct drm_device * dev
- DRM device to create property for
size_t length
- Length to allocate for blob data
const void * data
- If specified, copies data into blob
Description
Creates a new blob property for a specified DRM device, optionally copying data.
Return
New blob property with a single reference on success, or an ERR_PTR value on failure.
-
void
drm_property_unreference_blob
(struct drm_property_blob * blob)¶ Unreference a blob property
Parameters
struct drm_property_blob * blob
- Pointer to blob property
Description
Drop a reference on a blob property. May free the object.
-
struct drm_property_blob *
drm_property_reference_blob
(struct drm_property_blob * blob)¶ Take a reference on an existing property
Parameters
struct drm_property_blob * blob
- Pointer to blob property
Description
Take a new reference on an existing blob property.
-
struct drm_property_blob *
drm_property_lookup_blob
(struct drm_device * dev, uint32_t id)¶ look up a blob property and take a reference
Parameters
struct drm_device * dev
- drm device
uint32_t id
- id of the blob property
Description
If successful, this takes an additional reference to the blob property. callers need to make sure to eventually unreference the returned property again, using drm_property_unreference_blob.
-
int
drm_mode_connector_set_path_property
(struct drm_connector * connector, const char * path)¶ set tile property on connector
Parameters
struct drm_connector * connector
- connector to set property on.
const char * path
- path to use for property; must not be NULL.
Description
This creates a property to expose to userspace to specify a connector path. This is mainly used for DisplayPort MST where connectors have a topology and we want to allow userspace to give them more meaningful names.
Return
Zero on success, negative errno on failure.
-
int
drm_mode_connector_set_tile_property
(struct drm_connector * connector)¶ set tile property on connector
Parameters
struct drm_connector * connector
- connector to set property on.
Description
This looks up the tile information for a connector, and creates a property for userspace to parse if it exists. The property is of the form of 8 integers using ‘:’ as a separator.
Return
Zero on success, errno on failure.
-
int
drm_mode_connector_update_edid_property
(struct drm_connector * connector, const struct edid * edid)¶ update the edid property of a connector
Parameters
struct drm_connector * connector
- drm connector
const struct edid * edid
- new value of the edid property
Description
This function creates a new blob modeset object and assigns its id to the connector’s edid property.
Return
Zero on success, negative errno on failure.
-
int
drm_mode_plane_set_obj_prop
(struct drm_plane * plane, struct drm_property * property, uint64_t value)¶ set the value of a property
Parameters
struct drm_plane * plane
- drm plane object to set property value for
struct drm_property * property
- property to set
uint64_t value
- value the property should be set to
Description
This functions sets a given property on a given plane object. This function calls the driver’s ->set_property callback and changes the software state of the property if the callback succeeds.
Return
Zero on success, error code on failure.
-
int
drm_mode_connector_attach_encoder
(struct drm_connector * connector, struct drm_encoder * encoder)¶ attach a connector to an encoder
Parameters
struct drm_connector * connector
- connector to attach
struct drm_encoder * encoder
- encoder to attach connector to
Description
This function links up a connector to an encoder. Note that the routing restrictions between encoders and crtcs are exposed to userspace through the possible_clones and possible_crtcs bitmasks.
Return
Zero on success, negative errno on failure.
Parameters
struct drm_crtc * crtc
- CRTC to set the gamma table size for
int gamma_size
- size of the gamma table
Description
Drivers which support gamma tables should set this to the supported gamma table size when initializing the CRTC. Currently the drm core only supports a fixed gamma table size.
Return
Zero on success, negative errno on failure.
-
void
drm_mode_config_reset
(struct drm_device * dev)¶ call ->reset callbacks
Parameters
struct drm_device * dev
- drm device
Description
This functions calls all the crtc’s, encoder’s and connector’s ->reset callback. Drivers can use this in e.g. their driver load or resume code to reset hardware and software state.
-
unsigned int
drm_rotation_simplify
(unsigned int rotation, unsigned int supported_rotations)¶ Try to simplify the rotation
Parameters
unsigned int rotation
- Rotation to be simplified
unsigned int supported_rotations
- Supported rotations
Description
Attempt to simplify the rotation to a form that is supported. Eg. if the hardware supports everything except DRM_REFLECT_X one could call this function like this:
- drm_rotation_simplify(rotation, BIT(DRM_ROTATE_0) |
- BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_180) | BIT(DRM_ROTATE_270) | BIT(DRM_REFLECT_Y));
to eliminate the DRM_ROTATE_X flag. Depending on what kind of transforms the hardware supports, this function may not be able to produce a supported transform, so the caller should check the result afterwards.
-
void
drm_mode_config_init
(struct drm_device * dev)¶ initialize DRM mode_configuration structure
Parameters
struct drm_device * dev
- DRM device
Description
Initialize dev‘s mode_config structure, used for tracking the graphics configuration of dev.
Since this initializes the modeset locks, no locking is possible. Which is no problem, since this should happen single threaded at init time. It is the driver’s problem to ensure this guarantee.
-
void
drm_mode_config_cleanup
(struct drm_device * dev)¶ free up DRM mode_config info
Parameters
struct drm_device * dev
- DRM device
Description
Free up all the connectors and CRTCs associated with this DRM device, then free up the framebuffers and associated buffer objects.
Note that since this /should/ happen single-threaded at driver/device teardown time, no locking is required. It’s the driver’s job to ensure that this guarantee actually holds true.
FIXME: cleanup any dangling user buffer objects too
-
struct drm_tile_group *
drm_mode_get_tile_group
(struct drm_device * dev, char topology[8])¶ get a reference to an existing tile group
Parameters
struct drm_device * dev
- DRM device
char topology[8]
- undescribed
Description
Use the unique bytes to get a reference to an existing tile group.
Return
tile group or NULL if not found.
-
struct drm_tile_group *
drm_mode_create_tile_group
(struct drm_device * dev, char topology[8])¶ create a tile group from a displayid description
Parameters
struct drm_device * dev
- DRM device
char topology[8]
- undescribed
Description
Create a tile group for the unique monitor, and get a unique identifier for the tile group.
Return
new tile group or error.
-
void
drm_crtc_enable_color_mgmt
(struct drm_crtc * crtc, uint degamma_lut_size, bool has_ctm, uint gamma_lut_size)¶ enable color management properties
Parameters
struct drm_crtc * crtc
- DRM CRTC
uint degamma_lut_size
- the size of the degamma lut (before CSC)
bool has_ctm
- whether to attach ctm_property for CSC matrix
uint gamma_lut_size
- the size of the gamma lut (after CSC)
Description
This function lets the driver enable the color correction properties on a CRTC. This includes 3 degamma, csc and gamma properties that userspace can set and 2 size properties to inform the userspace of the lut sizes. Each of the properties are optional. The gamma and degamma properties are only attached if their size is not 0 and ctm_property is only attached if has_ctm is true.
KMS Data Structures¶
-
struct
drm_framebuffer_funcs
¶ framebuffer hooks
Definition
struct drm_framebuffer_funcs {
void (* destroy) (struct drm_framebuffer *framebuffer);
int (* create_handle) (struct drm_framebuffer *fb,struct drm_file *file_priv,unsigned int *handle);
int (* dirty) (struct drm_framebuffer *framebuffer,struct drm_file *file_priv, unsigned flags,unsigned color, struct drm_clip_rect *clips,unsigned num_clips);
};
Members
void (*)(struct drm_framebuffer *framebuffer) destroy
- Clean up framebuffer resources, specifically also unreference the
backing storage. The core guarantees to call this function for every
framebuffer successfully created by ->:c:func:fb_create() in
drm_mode_config_funcs
. Drivers must also calldrm_framebuffer_cleanup()
to release DRM core resources for this framebuffer. int (*)(struct drm_framebuffer *fb,struct drm_file *file_priv,unsigned int *handle) create_handle
Create a buffer handle in the driver-specific buffer manager (either GEM or TTM) valid for the passed-in struct
drm_file
. This is used by the core to implement the GETFB IOCTL, which returns (for sufficiently priviledged user) also a native buffer handle. This can be used for seamless transitions between modesetting clients by copying the current screen contents to a private buffer and blending between that and the new contents.GEM based drivers should call
drm_gem_handle_create()
to create the handle.RETURNS:
0 on success or a negative error code on failure.
int (*)(struct drm_framebuffer *framebuffer,struct drm_file *file_priv, unsigned flags,unsigned color, struct drm_clip_rect *clips,unsigned num_clips) dirty
Optional callback for the dirty fb IOCTL.
Userspace can notify the driver via this callback that an area of the framebuffer has changed and should be flushed to the display hardware. This can also be used internally, e.g. by the fbdev emulation, though that’s not the case currently.
See documentation in drm_mode.h for the struct drm_mode_fb_dirty_cmd for more information as all the semantics and arguments have a one to one mapping on this function.
RETURNS:
0 on success or a negative error code on failure.
-
struct
drm_crtc_state
¶ mutable CRTC state
Definition
struct drm_crtc_state {
struct drm_crtc * crtc;
bool enable;
bool active;
bool planes_changed:1;
bool mode_changed:1;
bool active_changed:1;
bool connectors_changed:1;
bool zpos_changed:1;
bool color_mgmt_changed:1;
u32 plane_mask;
u32 connector_mask;
u32 encoder_mask;
u32 last_vblank_count;
struct drm_display_mode adjusted_mode;
struct drm_display_mode mode;
struct drm_property_blob * mode_blob;
struct drm_property_blob * degamma_lut;
struct drm_property_blob * ctm;
struct drm_property_blob * gamma_lut;
struct drm_pending_vblank_event * event;
struct drm_atomic_state * state;
};
Members
struct drm_crtc * crtc
- backpointer to the CRTC
bool enable
- whether the CRTC should be enabled, gates all other state
bool active
- whether the CRTC is actively displaying (used for DPMS)
bool:1 planes_changed
- planes on this crtc are updated
bool:1 mode_changed
- crtc_state->mode or crtc_state->enable has been changed
bool:1 active_changed
- crtc_state->active has been toggled.
bool:1 connectors_changed
- connectors to this crtc have been updated
bool:1 zpos_changed
- zpos values of planes on this crtc have been updated
bool:1 color_mgmt_changed
- color management properties have changed (degamma or gamma LUT or CSC matrix)
u32 plane_mask
- bitmask of (1 << drm_plane_index(plane)) of attached planes
u32 connector_mask
- bitmask of (1 << drm_connector_index(connector)) of attached connectors
u32 encoder_mask
- bitmask of (1 << drm_encoder_index(encoder)) of attached encoders
u32 last_vblank_count
- for helpers and drivers to capture the vblank of the update to ensure framebuffer cleanup isn’t done too early
struct drm_display_mode adjusted_mode
- for use by helpers and drivers to compute adjusted mode timings
struct drm_display_mode mode
- current mode timings
struct drm_property_blob * mode_blob
drm_property_blob
for modestruct drm_property_blob * degamma_lut
- Lookup table for converting framebuffer pixel data before apply the conversion matrix
struct drm_property_blob * ctm
- Transformation matrix
struct drm_property_blob * gamma_lut
- Lookup table for converting pixel data after the conversion matrix
struct drm_pending_vblank_event * event
- optional pointer to a DRM event to signal upon completion of the state update
struct drm_atomic_state * state
- backpointer to global drm_atomic_state
Description
Note that the distinction between enable and active is rather subtile: Flipping active while enable is set without changing anything else may never return in a failure from the ->atomic_check callback. Userspace assumes that a DPMS On will always succeed. In other words: enable controls resource assignment, active controls the actual hardware state.
-
struct
drm_crtc_funcs
¶ control CRTCs for a given device
Definition
struct drm_crtc_funcs {
void (* reset) (struct drm_crtc *crtc);
int (* cursor_set) (struct drm_crtc *crtc, struct drm_file *file_priv,uint32_t handle, uint32_t width, uint32_t height);
int (* cursor_set2) (struct drm_crtc *crtc, struct drm_file *file_priv,uint32_t handle, uint32_t width, uint32_t height,int32_t hot_x, int32_t hot_y);
int (* cursor_move) (struct drm_crtc *crtc, int x, int y);
int (* gamma_set) (struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,uint32_t size);
void (* destroy) (struct drm_crtc *crtc);
int (* set_config) (struct drm_mode_set *set);
int (* page_flip) (struct drm_crtc *crtc,struct drm_framebuffer *fb,struct drm_pending_vblank_event *event,uint32_t flags);
int (* set_property) (struct drm_crtc *crtc,struct drm_property *property, uint64_t val);
struct drm_crtc_state *(* atomic_duplicate_state) (struct drm_crtc *crtc);
void (* atomic_destroy_state) (struct drm_crtc *crtc,struct drm_crtc_state *state);
int (* atomic_set_property) (struct drm_crtc *crtc,struct drm_crtc_state *state,struct drm_property *property,uint64_t val);
int (* atomic_get_property) (struct drm_crtc *crtc,const struct drm_crtc_state *state,struct drm_property *property,uint64_t *val);
int (* late_register) (struct drm_crtc *crtc);
void (* early_unregister) (struct drm_crtc *crtc);
};
Members
void (*)(struct drm_crtc *crtc) reset
Reset CRTC hardware and software state to off. This function isn’t called by the core directly, only through
drm_mode_config_reset()
. It’s not a helper hook only for historical reasons.Atomic drivers can use
drm_atomic_helper_crtc_reset()
to reset atomic state using this hook.int (*)(struct drm_crtc *crtc, struct drm_file *file_priv,uint32_t handle, uint32_t width, uint32_t height) cursor_set
Update the cursor image. The cursor position is relative to the CRTC and can be partially or fully outside of the visible area.
Note that contrary to all other KMS functions the legacy cursor entry points don’t take a framebuffer object, but instead take directly a raw buffer object id from the driver’s buffer manager (which is either GEM or TTM for current drivers).
This entry point is deprecated, drivers should instead implement universal plane support and register a proper cursor plane using
drm_crtc_init_with_planes()
.This callback is optional
RETURNS:
0 on success or a negative error code on failure.
int (*)(struct drm_crtc *crtc, struct drm_file *file_priv,uint32_t handle, uint32_t width, uint32_t height,int32_t hot_x, int32_t hot_y) cursor_set2
Update the cursor image, including hotspot information. The hotspot must not affect the cursor position in CRTC coordinates, but is only meant as a hint for virtualized display hardware to coordinate the guests and hosts cursor position. The cursor hotspot is relative to the cursor image. Otherwise this works exactly like cursor_set.
This entry point is deprecated, drivers should instead implement universal plane support and register a proper cursor plane using
drm_crtc_init_with_planes()
.This callback is optional.
RETURNS:
0 on success or a negative error code on failure.
int (*)(struct drm_crtc *crtc, int x, int y) cursor_move
Update the cursor position. The cursor does not need to be visible when this hook is called.
This entry point is deprecated, drivers should instead implement universal plane support and register a proper cursor plane using
drm_crtc_init_with_planes()
.This callback is optional.
RETURNS:
0 on success or a negative error code on failure.
int (*)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,uint32_t size) gamma_set
Set gamma on the CRTC.
This callback is optional.
NOTE:
Drivers that support gamma tables and also fbdev emulation through the provided helper library need to take care to fill out the gamma hooks for both. Currently there’s a bit an unfortunate duplication going on, which should eventually be unified to just one set of hooks.
void (*)(struct drm_crtc *crtc) destroy
- Clean up plane resources. This is only called at driver unload time
through
drm_mode_config_cleanup()
since a CRTC cannot be hotplugged in DRM. int (*)(struct drm_mode_set *set) set_config
This is the main legacy entry point to change the modeset state on a CRTC. All the details of the desired configuration are passed in a struct
drm_mode_set
- see there for details.Drivers implementing atomic modeset should use
drm_atomic_helper_set_config()
to implement this hook.RETURNS:
0 on success or a negative error code on failure.
int (*)(struct drm_crtc *crtc,struct drm_framebuffer *fb,struct drm_pending_vblank_event *event,uint32_t flags) page_flip
Legacy entry point to schedule a flip to the given framebuffer.
Page flipping is a synchronization mechanism that replaces the frame buffer being scanned out by the CRTC with a new frame buffer during vertical blanking, avoiding tearing (except when requested otherwise through the DRM_MODE_PAGE_FLIP_ASYNC flag). When an application requests a page flip the DRM core verifies that the new frame buffer is large enough to be scanned out by the CRTC in the currently configured mode and then calls the CRTC ->:c:func:page_flip() operation with a pointer to the new frame buffer.
The driver must wait for any pending rendering to the new framebuffer to complete before executing the flip. It should also wait for any pending rendering from other drivers if the underlying buffer is a shared dma-buf.
An application can request to be notified when the page flip has completed. The drm core will supply a struct
drm_event
in the event parameter in this case. This can be handled by thedrm_crtc_send_vblank_event()
function, which the driver should call on the provided event upon completion of the flip. Note that if the driver supports vblank signalling and timestamping the vblank counters and timestamps must agree with the ones returned from page flip events. With the current vblank helper infrastructure this can be achieved by holding a vblank reference while the page flip is pending, acquired throughdrm_crtc_vblank_get()
and released withdrm_crtc_vblank_put()
. Drivers are free to implement their own vblank counter and timestamp tracking though, e.g. if they have accurate timestamp registers in hardware.FIXME:
Up to that point drivers need to manage events themselves and can use even->base.list freely for that. Specifically they need to ensure that they don’t send out page flip (or vblank) events for which the corresponding drm file has been closed already. The drm core unfortunately does not (yet) take care of that. Therefore drivers currently must clean up and release pending events in their ->preclose driver function.
This callback is optional.
NOTE:
Very early versions of the KMS ABI mandated that the driver must block (but not reject) any rendering to the old framebuffer until the flip operation has completed and the old framebuffer is no longer visible. This requirement has been lifted, and userspace is instead expected to request delivery of an event and wait with recycling old buffers until such has been received.
RETURNS:
0 on success or a negative error code on failure. Note that if a ->:c:func:page_flip() operation is already pending the callback should return -EBUSY. Pageflips on a disabled CRTC (either by setting a NULL mode or just runtime disabled through DPMS respectively the new atomic “ACTIVE” state) should result in an -EINVAL error code. Note that
drm_atomic_helper_page_flip()
checks this already for atomic drivers.int (*)(struct drm_crtc *crtc,struct drm_property *property, uint64_t val) set_property
This is the legacy entry point to update a property attached to the CRTC.
Drivers implementing atomic modeset should use
drm_atomic_helper_crtc_set_property()
to implement this hook.This callback is optional if the driver does not support any legacy driver-private properties.
RETURNS:
0 on success or a negative error code on failure.
struct drm_crtc_state *(*)(struct drm_crtc *crtc) atomic_duplicate_state
Duplicate the current atomic state for this CRTC and return it. The core and helpers gurantee that any atomic state duplicated with this hook and still owned by the caller (i.e. not transferred to the driver by calling ->:c:func:atomic_commit() from struct
drm_mode_config_funcs
) will be cleaned up by calling the atomic_destroy_state hook in this structure.Atomic drivers which don’t subclass struct
drm_crtc
should usedrm_atomic_helper_crtc_duplicate_state()
. Drivers that subclass the state structure to extend it with driver-private state should use__drm_atomic_helper_crtc_duplicate_state()
to make sure shared state is duplicated in a consistent fashion across drivers.It is an error to call this hook before crtc->state has been initialized correctly.
NOTE:
If the duplicate state references refcounted resources this hook must acquire a reference for each of them. The driver must release these references again in atomic_destroy_state.
RETURNS:
Duplicated atomic state or NULL when the allocation failed.
void (*)(struct drm_crtc *crtc,struct drm_crtc_state *state) atomic_destroy_state
- Destroy a state duplicated with atomic_duplicate_state and release or unreference all resources it references
int (*)(struct drm_crtc *crtc,struct drm_crtc_state *state,struct drm_property *property,uint64_t val) atomic_set_property
Decode a driver-private property value and store the decoded value into the passed-in state structure. Since the atomic core decodes all standardized properties (even for extensions beyond the core set of properties which might not be implemented by all drivers) this requires drivers to subclass the state structure.
Such driver-private properties should really only be implemented for truly hardware/vendor specific state. Instead it is preferred to standardize atomic extension and decode the properties used to expose such an extension in the core.
Do not call this function directly, use
drm_atomic_crtc_set_property()
instead.This callback is optional if the driver does not support any driver-private atomic properties.
NOTE:
This function is called in the state assembly phase of atomic modesets, which can be aborted for any reason (including on userspace’s request to just check whether a configuration would be possible). Drivers MUST NOT touch any persistent state (hardware or software) or data structures except the passed in state parameter.
Also since userspace controls in which order properties are set this function must not do any input validation (since the state update is incomplete and hence likely inconsistent). Instead any such input validation must be done in the various atomic_check callbacks.
RETURNS:
0 if the property has been found, -EINVAL if the property isn’t implemented by the driver (which should never happen, the core only asks for properties attached to this CRTC). No other validation is allowed by the driver. The core already checks that the property value is within the range (integer, valid enum value, ...) the driver set when registering the property.
int (*)(struct drm_crtc *crtc,const struct drm_crtc_state *state,struct drm_property *property,uint64_t *val) atomic_get_property
Reads out the decoded driver-private property. This is used to implement the GETCRTC IOCTL.
Do not call this function directly, use
drm_atomic_crtc_get_property()
instead.This callback is optional if the driver does not support any driver-private atomic properties.
RETURNS:
0 on success, -EINVAL if the property isn’t implemented by the driver (which should never happen, the core only asks for properties attached to this CRTC).
int (*)(struct drm_crtc *crtc) late_register
This optional hook can be used to register additional userspace interfaces attached to the crtc like debugfs interfaces. It is called late in the driver load sequence from
drm_dev_register()
. Everything added from this callback should be unregistered in the early_unregister callback.Returns:
0 on success, or a negative error code on failure.
void (*)(struct drm_crtc *crtc) early_unregister
- This optional hook should be used to unregister the additional
userspace interfaces attached to the crtc from
late_unregister()
. It is called fromdrm_dev_unregister()
, early in the driver unload sequence to disable userspace access before data structures are torndown.
Description
The drm_crtc_funcs structure is the central CRTC management structure in the DRM. Each CRTC controls one or more connectors (note that the name CRTC is simply historical, a CRTC may control LVDS, VGA, DVI, TV out, etc. connectors, not just CRTs).
Each driver is responsible for filling out this structure at startup time, in addition to providing other modesetting features, like i2c and DDC bus accessors.
-
struct
drm_crtc
¶ central CRTC control structure
Definition
struct drm_crtc {
struct drm_device * dev;
struct device_node * port;
struct list_head head;
char * name;
struct drm_modeset_lock mutex;
struct drm_mode_object base;
struct drm_plane * primary;
struct drm_plane * cursor;
unsigned index;
int cursor_x;
int cursor_y;
bool enabled;
struct drm_display_mode mode;
struct drm_display_mode hwmode;
int x;
int y;
const struct drm_crtc_funcs * funcs;
uint32_t gamma_size;
uint16_t * gamma_store;
const struct drm_crtc_helper_funcs * helper_private;
struct drm_object_properties properties;
struct drm_crtc_state * state;
struct list_head commit_list;
spinlock_t commit_lock;
struct drm_modeset_acquire_ctx * acquire_ctx;
};
Members
struct drm_device * dev
- parent DRM device
struct device_node * port
- OF node used by
drm_of_find_possible_crtcs()
struct list_head head
- list management
char * name
- human readable name, can be overwritten by the driver
struct drm_modeset_lock mutex
- This provides a read lock for the overall crtc state (mode, dpms state, ...) and a write lock for everything which can be update without a full modeset (fb, cursor data, crtc properties ...). Full modeset also need to grab dev->mode_config.connection_mutex.
struct drm_mode_object base
- base KMS object for ID tracking etc.
struct drm_plane * primary
- primary plane for this CRTC
struct drm_plane * cursor
- cursor plane for this CRTC
unsigned index
- Position inside the mode_config.list, can be used as an array index. It is invariant over the lifetime of the CRTC.
int cursor_x
- current x position of the cursor, used for universal cursor planes
int cursor_y
- current y position of the cursor, used for universal cursor planes
bool enabled
- is this CRTC enabled?
struct drm_display_mode mode
- current mode timings
struct drm_display_mode hwmode
- mode timings as programmed to hw regs
int x
- x position on screen
int y
- y position on screen
const struct drm_crtc_funcs * funcs
- CRTC control functions
uint32_t gamma_size
- size of gamma ramp
uint16_t * gamma_store
- gamma ramp values
const struct drm_crtc_helper_funcs * helper_private
- mid-layer private data
struct drm_object_properties properties
- property tracking for this CRTC
struct drm_crtc_state * state
- Current atomic state for this CRTC.
struct list_head commit_list
- List of
drm_crtc_commit
structures tracking pending commits. Protected by commit_lock. This list doesn’t hold its own full reference, but burrows it from the ongoing commit. Commit entries must be removed from this list once the commit is fully completed, but before it’s correspodingdrm_atomic_state
gets destroyed. spinlock_t commit_lock
- Spinlock to protect commit_list.
struct drm_modeset_acquire_ctx * acquire_ctx
- Per-CRTC implicit acquire context used by atomic drivers for legacy IOCTLs, so that atomic drivers can get at the locking acquire context.
Description
Each CRTC may have one or more connectors associated with it. This structure allows the CRTC to be controlled.
-
struct
drm_connector_state
¶ mutable connector state
Definition
struct drm_connector_state {
struct drm_connector * connector;
struct drm_crtc * crtc;
struct drm_encoder * best_encoder;
struct drm_atomic_state * state;
};
Members
struct drm_connector * connector
- backpointer to the connector
struct drm_crtc * crtc
- CRTC to connect connector to, NULL if disabled
struct drm_encoder * best_encoder
- can be used by helpers and drivers to select the encoder
struct drm_atomic_state * state
- backpointer to global drm_atomic_state
-
struct
drm_connector_funcs
¶ control connectors on a given device
Definition
struct drm_connector_funcs {
int (* dpms) (struct drm_connector *connector, int mode);
void (* reset) (struct drm_connector *connector);
enum drm_connector_status (* detect) (struct drm_connector *connector,bool force);
void (* force) (struct drm_connector *connector);
int (* fill_modes) (struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
int (* set_property) (struct drm_connector *connector, struct drm_property *property,uint64_t val);
int (* late_register) (struct drm_connector *connector);
void (* early_unregister) (struct drm_connector *connector);
void (* destroy) (struct drm_connector *connector);
struct drm_connector_state *(* atomic_duplicate_state) (struct drm_connector *connector);
void (* atomic_destroy_state) (struct drm_connector *connector,struct drm_connector_state *state);
int (* atomic_set_property) (struct drm_connector *connector,struct drm_connector_state *state,struct drm_property *property,uint64_t val);
int (* atomic_get_property) (struct drm_connector *connector,const struct drm_connector_state *state,struct drm_property *property,uint64_t *val);
};
Members
int (*)(struct drm_connector *connector, int mode) dpms
Legacy entry point to set the per-connector DPMS state. Legacy DPMS is exposed as a standard property on the connector, but diverted to this callback in the drm core. Note that atomic drivers don’t implement the 4 level DPMS support on the connector any more, but instead only have an on/off “ACTIVE” property on the CRTC object.
Drivers implementing atomic modeset should use
drm_atomic_helper_connector_dpms()
to implement this hook.RETURNS:
0 on success or a negative error code on failure.
void (*)(struct drm_connector *connector) reset
Reset connector hardware and software state to off. This function isn’t called by the core directly, only through
drm_mode_config_reset()
. It’s not a helper hook only for historical reasons.Atomic drivers can use
drm_atomic_helper_connector_reset()
to reset atomic state using this hook.enum drm_connector_status (*)(struct drm_connector *connector,bool force) detect
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.
FIXME:
Note that this hook is only called by the probe helper. It’s not in the helper library vtable purely for historical reasons. The only DRM core entry point to probe connector state is fill_modes.
RETURNS:
drm_connector_status indicating the connector’s status.
void (*)(struct drm_connector *connector) force
This function is called to update internal encoder state when the connector is forced to a certain state by userspace, either through the sysfs interfaces or on the kernel cmdline. In that case the detect callback isn’t called.
FIXME:
Note that this hook is only called by the probe helper. It’s not in the helper library vtable purely for historical reasons. The only DRM core entry point to probe connector state is fill_modes.
int (*)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height) fill_modes
Entry point for output detection and basic mode validation. The driver should reprobe the output if needed (e.g. when hotplug handling is unreliable), add all detected modes to connector->modes and filter out any the device can’t support in any configuration. It also needs to filter out any modes wider or higher than the parameters max_width and max_height indicate.
The drivers must also prune any modes no longer valid from connector->modes. Furthermore it must update connector->status and connector->edid. If no EDID has been received for this output connector->edid must be NULL.
Drivers using the probe helpers should use
drm_helper_probe_single_connector_modes()
ordrm_helper_probe_single_connector_modes_nomerge()
to implement this function.RETURNS:
The number of modes detected and filled into connector->modes.
int (*)(struct drm_connector *connector, struct drm_property *property,uint64_t val) set_property
This is the legacy entry point to update a property attached to the connector.
Drivers implementing atomic modeset should use
drm_atomic_helper_connector_set_property()
to implement this hook.This callback is optional if the driver does not support any legacy driver-private properties.
RETURNS:
0 on success or a negative error code on failure.
int (*)(struct drm_connector *connector) late_register
This optional hook can be used to register additional userspace interfaces attached to the connector, light backlight control, i2c, DP aux or similar interfaces. It is called late in the driver load sequence from
drm_connector_register()
when registering all the core drm connector interfaces. Everything added from this callback should be unregistered in the early_unregister callback.Returns:
0 on success, or a negative error code on failure.
void (*)(struct drm_connector *connector) early_unregister
- This optional hook should be used to unregister the additional
userspace interfaces attached to the connector from
late_unregister()
. It is called fromdrm_connector_unregister()
, early in the driver unload sequence to disable userspace access before data structures are torndown. void (*)(struct drm_connector *connector) destroy
- Clean up connector resources. This is called at driver unload time
through
drm_mode_config_cleanup()
. It can also be called at runtime when a connector is being hot-unplugged for drivers that support connector hotplugging (e.g. DisplayPort MST). struct drm_connector_state *(*)(struct drm_connector *connector) atomic_duplicate_state
Duplicate the current atomic state for this connector and return it. The core and helpers gurantee that any atomic state duplicated with this hook and still owned by the caller (i.e. not transferred to the driver by calling ->:c:func:atomic_commit() from struct
drm_mode_config_funcs
) will be cleaned up by calling the atomic_destroy_state hook in this structure.Atomic drivers which don’t subclass struct
drm_connector_state
should usedrm_atomic_helper_connector_duplicate_state()
. Drivers that subclass the state structure to extend it with driver-private state should use__drm_atomic_helper_connector_duplicate_state()
to make sure shared state is duplicated in a consistent fashion across drivers.It is an error to call this hook before connector->state has been initialized correctly.
NOTE:
If the duplicate state references refcounted resources this hook must acquire a reference for each of them. The driver must release these references again in atomic_destroy_state.
RETURNS:
Duplicated atomic state or NULL when the allocation failed.
void (*)(struct drm_connector *connector,struct drm_connector_state *state) atomic_destroy_state
- Destroy a state duplicated with atomic_duplicate_state and release or unreference all resources it references
int (*)(struct drm_connector *connector,struct drm_connector_state *state,struct drm_property *property,uint64_t val) atomic_set_property
Decode a driver-private property value and store the decoded value into the passed-in state structure. Since the atomic core decodes all standardized properties (even for extensions beyond the core set of properties which might not be implemented by all drivers) this requires drivers to subclass the state structure.
Such driver-private properties should really only be implemented for truly hardware/vendor specific state. Instead it is preferred to standardize atomic extension and decode the properties used to expose such an extension in the core.
Do not call this function directly, use
drm_atomic_connector_set_property()
instead.This callback is optional if the driver does not support any driver-private atomic properties.
NOTE:
This function is called in the state assembly phase of atomic modesets, which can be aborted for any reason (including on userspace’s request to just check whether a configuration would be possible). Drivers MUST NOT touch any persistent state (hardware or software) or data structures except the passed in state parameter.
Also since userspace controls in which order properties are set this function must not do any input validation (since the state update is incomplete and hence likely inconsistent). Instead any such input validation must be done in the various atomic_check callbacks.
RETURNS:
0 if the property has been found, -EINVAL if the property isn’t implemented by the driver (which shouldn’t ever happen, the core only asks for properties attached to this connector). No other validation is allowed by the driver. The core already checks that the property value is within the range (integer, valid enum value, ...) the driver set when registering the property.
int (*)(struct drm_connector *connector,const struct drm_connector_state *state,struct drm_property *property,uint64_t *val) atomic_get_property
Reads out the decoded driver-private property. This is used to implement the GETCONNECTOR IOCTL.
Do not call this function directly, use
drm_atomic_connector_get_property()
instead.This callback is optional if the driver does not support any driver-private atomic properties.
RETURNS:
0 on success, -EINVAL if the property isn’t implemented by the driver (which shouldn’t ever happen, the core only asks for properties attached to this connector).
Description
Each CRTC may have one or more connectors attached to it. The functions below allow the core DRM code to control connectors, enumerate available modes, etc.
-
struct
drm_encoder_funcs
¶ encoder controls
Definition
struct drm_encoder_funcs {
void (* reset) (struct drm_encoder *encoder);
void (* destroy) (struct drm_encoder *encoder);
int (* late_register) (struct drm_encoder *encoder);
void (* early_unregister) (struct drm_encoder *encoder);
};
Members
void (*)(struct drm_encoder *encoder) reset
- Reset encoder hardware and software state to off. This function isn’t
called by the core directly, only through
drm_mode_config_reset()
. It’s not a helper hook only for historical reasons. void (*)(struct drm_encoder *encoder) destroy
- Clean up encoder resources. This is only called at driver unload time
through
drm_mode_config_cleanup()
since an encoder cannot be hotplugged in DRM. int (*)(struct drm_encoder *encoder) late_register
This optional hook can be used to register additional userspace interfaces attached to the encoder like debugfs interfaces. It is called late in the driver load sequence from
drm_dev_register()
. Everything added from this callback should be unregistered in the early_unregister callback.Returns:
0 on success, or a negative error code on failure.
void (*)(struct drm_encoder *encoder) early_unregister
- This optional hook should be used to unregister the additional
userspace interfaces attached to the encoder from
late_unregister()
. It is called fromdrm_dev_unregister()
, early in the driver unload sequence to disable userspace access before data structures are torndown.
Description
Encoders sit between CRTCs and connectors.
-
struct
drm_encoder
¶ central DRM encoder structure
Definition
struct drm_encoder {
struct drm_device * dev;
struct list_head head;
struct drm_mode_object base;
char * name;
int encoder_type;
unsigned index;
uint32_t possible_crtcs;
uint32_t possible_clones;
struct drm_crtc * crtc;
struct drm_bridge * bridge;
const struct drm_encoder_funcs * funcs;
const struct drm_encoder_helper_funcs * helper_private;
};
Members
struct drm_device * dev
- parent DRM device
struct list_head head
- list management
struct drm_mode_object base
- base KMS object
char * name
- human readable name, can be overwritten by the driver
int encoder_type
- one of the ``DRM_MODE_ENCODER_``<foo> types in drm_mode.h
unsigned index
- Position inside the mode_config.list, can be used as an array index. It is invariant over the lifetime of the encoder.
uint32_t possible_crtcs
- bitmask of potential CRTC bindings
uint32_t possible_clones
- bitmask of potential sibling encoders for cloning
struct drm_crtc * crtc
- currently bound CRTC
struct drm_bridge * bridge
- bridge associated to the encoder
const struct drm_encoder_funcs * funcs
- control functions
const struct drm_encoder_helper_funcs * helper_private
- mid-layer private data
Description
CRTCs drive pixels to encoders, which convert them into signals appropriate for a given connector or set of connectors.
-
struct
drm_connector
¶ central DRM connector control structure
Definition
struct drm_connector {
struct drm_device * dev;
struct device * kdev;
struct device_attribute * attr;
struct list_head head;
struct drm_mode_object base;
char * name;
unsigned index;
int connector_type;
int connector_type_id;
bool interlace_allowed;
bool doublescan_allowed;
bool stereo_allowed;
bool registered;
struct list_head modes;
enum drm_connector_status status;
struct list_head probed_modes;
struct drm_display_info display_info;
const struct drm_connector_funcs * funcs;
struct drm_property_blob * edid_blob_ptr;
struct drm_object_properties properties;
struct drm_property_blob * path_blob_ptr;
struct drm_property_blob * tile_blob_ptr;
uint8_t polled;
int dpms;
const struct drm_connector_helper_funcs * helper_private;
struct drm_cmdline_mode cmdline_mode;
enum drm_connector_force force;
bool override_edid;
uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
struct drm_encoder * encoder;
uint8_t eld[MAX_ELD_BYTES];
bool dvi_dual;
int max_tmds_clock;
bool latency_present[2];
int video_latency[2];
int audio_latency[2];
int null_edid_counter;
unsigned bad_edid_counter;
bool edid_corrupt;
struct dentry * debugfs_entry;
struct drm_connector_state * state;
bool has_tile;
struct drm_tile_group * tile_group;
bool tile_is_single_monitor;
uint8_t num_h_tile;
uint8_t num_v_tile;
uint8_t tile_h_loc;
uint8_t tile_v_loc;
uint16_t tile_h_size;
uint16_t tile_v_size;
};
Members
struct drm_device * dev
- parent DRM device
struct device * kdev
- kernel device for sysfs attributes
struct device_attribute * attr
- sysfs attributes
struct list_head head
- list management
struct drm_mode_object base
- base KMS object
char * name
- human readable name, can be overwritten by the driver
unsigned index
- Compacted connector index, which matches the position inside the mode_config.list for drivers not supporting hot-add/removing. Can be used as an array index. It is invariant over the lifetime of the connector.
int connector_type
- one of the ``DRM_MODE_CONNECTOR_``<foo> types from drm_mode.h
int connector_type_id
- index into connector type enum
bool interlace_allowed
- can this connector handle interlaced modes?
bool doublescan_allowed
- can this connector handle doublescan?
bool stereo_allowed
- can this connector handle stereo modes?
bool registered
- is this connector exposed (registered) with userspace?
struct list_head modes
- modes available on this connector (from
fill_modes()
+ user) enum drm_connector_status status
- one of the drm_connector_status enums (connected, not, or unknown)
struct list_head probed_modes
- list of modes derived directly from the display
struct drm_display_info display_info
- information about attached display (e.g. from EDID)
const struct drm_connector_funcs * funcs
- connector control functions
struct drm_property_blob * edid_blob_ptr
- DRM property containing EDID if present
struct drm_object_properties properties
- property tracking for this connector
struct drm_property_blob * path_blob_ptr
- DRM blob property data for the DP MST path property.
struct drm_property_blob * tile_blob_ptr
- DRM blob property data for the tile property (used mostly by DP MST).
This is meant for screens which are driven through separate display
pipelines represented by
drm_crtc
, which might not be running with genlocked clocks. For tiled panels which are genlocked, like dual-link LVDS or dual-link DSI, the driver should try to not expose the tiling and virtualize bothdrm_crtc
anddrm_plane
if needed. uint8_t polled
- a ``DRM_CONNECTOR_POLL_``<foo> value for core driven polling
int dpms
- current dpms state
const struct drm_connector_helper_funcs * helper_private
- mid-layer private data
struct drm_cmdline_mode cmdline_mode
- mode line parsed from the kernel cmdline for this connector
enum drm_connector_force force
- a ``DRM_FORCE_``<foo> state for forced mode sets
bool override_edid
- has the EDID been overwritten through debugfs for testing?
uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]
- valid encoders for this connector
struct drm_encoder * encoder
- encoder driving this connector, if any
uint8_t eld[MAX_ELD_BYTES]
- EDID-like data, if present
bool dvi_dual
- dual link DVI, if found
int max_tmds_clock
- max clock rate, if found
bool latency_present[2]
- AV delay info from ELD, if found
int video_latency[2]
- video latency info from ELD, if found
int audio_latency[2]
- audio latency info from ELD, if found
int null_edid_counter
- track sinks that give us all zeros for the EDID
unsigned bad_edid_counter
- track sinks that give us an EDID with invalid checksum
bool edid_corrupt
- indicates whether the last read EDID was corrupt
struct dentry * debugfs_entry
- debugfs directory for this connector
struct drm_connector_state * state
- current atomic state for this connector
bool has_tile
- is this connector connected to a tiled monitor
struct drm_tile_group * tile_group
- tile group for the connected monitor
bool tile_is_single_monitor
- whether the tile is one monitor housing
uint8_t num_h_tile
- number of horizontal tiles in the tile group
uint8_t num_v_tile
- number of vertical tiles in the tile group
uint8_t tile_h_loc
- horizontal location of this tile
uint8_t tile_v_loc
- vertical location of this tile
uint16_t tile_h_size
- horizontal size of this tile.
uint16_t tile_v_size
- vertical size of this tile.
Description
Each connector may be connected to one or more CRTCs, or may be clonable by another connector if they can share a CRTC. Each connector also has a specific position in the broader display (referred to as a ‘screen’ though it could span multiple monitors).
-
struct
drm_plane_state
¶ mutable plane state
Definition
struct drm_plane_state {
struct drm_plane * plane;
struct drm_crtc * crtc;
struct drm_framebuffer * fb;
struct fence * fence;
int32_t crtc_x;
int32_t crtc_y;
uint32_t crtc_w;
uint32_t crtc_h;
uint32_t src_x;
uint32_t src_y;
uint32_t src_h;
uint32_t src_w;
unsigned int rotation;
unsigned int zpos;
unsigned int normalized_zpos;
struct drm_atomic_state * state;
};
Members
struct drm_plane * plane
- backpointer to the plane
struct drm_crtc * crtc
- currently bound CRTC, NULL if disabled
struct drm_framebuffer * fb
- currently bound framebuffer
struct fence * fence
- optional fence to wait for before scanning out fb
int32_t crtc_x
- left position of visible portion of plane on crtc
int32_t crtc_y
- upper position of visible portion of plane on crtc
uint32_t crtc_w
- width of visible portion of plane on crtc
uint32_t crtc_h
- height of visible portion of plane on crtc
uint32_t src_x
- left position of visible portion of plane within plane (in 16.16)
uint32_t src_y
- upper position of visible portion of plane within plane (in 16.16)
uint32_t src_h
- height of visible portion of plane (in 16.16)
uint32_t src_w
- width of visible portion of plane (in 16.16)
unsigned int rotation
- rotation of the plane
unsigned int zpos
- priority of the given plane on crtc (optional)
unsigned int normalized_zpos
- normalized value of zpos: unique, range from 0 to N-1 where N is the number of active planes for given crtc
struct drm_atomic_state * state
- backpointer to global drm_atomic_state
-
struct
drm_plane_funcs
¶ driver plane control functions
Definition
struct drm_plane_funcs {
int (* update_plane) (struct drm_plane *plane,struct drm_crtc *crtc, struct drm_framebuffer *fb,int crtc_x, int crtc_y,unsigned int crtc_w, unsigned int crtc_h,uint32_t src_x, uint32_t src_y,uint32_t src_w, uint32_t src_h);
int (* disable_plane) (struct drm_plane *plane);
void (* destroy) (struct drm_plane *plane);
void (* reset) (struct drm_plane *plane);
int (* set_property) (struct drm_plane *plane,struct drm_property *property, uint64_t val);
struct drm_plane_state *(* atomic_duplicate_state) (struct drm_plane *plane);
void (* atomic_destroy_state) (struct drm_plane *plane,struct drm_plane_state *state);
int (* atomic_set_property) (struct drm_plane *plane,struct drm_plane_state *state,struct drm_property *property,uint64_t val);
int (* atomic_get_property) (struct drm_plane *plane,const struct drm_plane_state *state,struct drm_property *property,uint64_t *val);
int (* late_register) (struct drm_plane *plane);
void (* early_unregister) (struct drm_plane *plane);
};
Members
int (*)(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) update_plane
This is the legacy entry point to enable and configure the plane for the given CRTC and framebuffer. It is never called to disable the plane, i.e. the passed-in crtc and fb paramters are never NULL.
The source rectangle in frame buffer memory coordinates is given by the src_x, src_y, src_w and src_h parameters (as 16.16 fixed point values). Devices that don’t support subpixel plane coordinates can ignore the fractional part.
The destination rectangle in CRTC coordinates is given by the crtc_x, crtc_y, crtc_w and crtc_h parameters (as integer values). Devices scale the source rectangle to the destination rectangle. If scaling is not supported, and the source rectangle size doesn’t match the destination rectangle size, the driver must return a -<errorname>EINVAL</errorname> error.
Drivers implementing atomic modeset should use
drm_atomic_helper_update_plane()
to implement this hook.RETURNS:
0 on success or a negative error code on failure.
int (*)(struct drm_plane *plane) disable_plane
This is the legacy entry point to disable the plane. The DRM core calls this method in response to a DRM_IOCTL_MODE_SETPLANE IOCTL call with the frame buffer ID set to 0. Disabled planes must not be processed by the CRTC.
Drivers implementing atomic modeset should use
drm_atomic_helper_disable_plane()
to implement this hook.RETURNS:
0 on success or a negative error code on failure.
void (*)(struct drm_plane *plane) destroy
- Clean up plane resources. This is only called at driver unload time
through
drm_mode_config_cleanup()
since a plane cannot be hotplugged in DRM. void (*)(struct drm_plane *plane) reset
Reset plane hardware and software state to off. This function isn’t called by the core directly, only through
drm_mode_config_reset()
. It’s not a helper hook only for historical reasons.Atomic drivers can use
drm_atomic_helper_plane_reset()
to reset atomic state using this hook.int (*)(struct drm_plane *plane,struct drm_property *property, uint64_t val) set_property
This is the legacy entry point to update a property attached to the plane.
Drivers implementing atomic modeset should use
drm_atomic_helper_plane_set_property()
to implement this hook.This callback is optional if the driver does not support any legacy driver-private properties.
RETURNS:
0 on success or a negative error code on failure.
struct drm_plane_state *(*)(struct drm_plane *plane) atomic_duplicate_state
Duplicate the current atomic state for this plane and return it. The core and helpers gurantee that any atomic state duplicated with this hook and still owned by the caller (i.e. not transferred to the driver by calling ->:c:func:atomic_commit() from struct
drm_mode_config_funcs
) will be cleaned up by calling the atomic_destroy_state hook in this structure.Atomic drivers which don’t subclass struct
drm_plane_state
should usedrm_atomic_helper_plane_duplicate_state()
. Drivers that subclass the state structure to extend it with driver-private state should use__drm_atomic_helper_plane_duplicate_state()
to make sure shared state is duplicated in a consistent fashion across drivers.It is an error to call this hook before plane->state has been initialized correctly.
NOTE:
If the duplicate state references refcounted resources this hook must acquire a reference for each of them. The driver must release these references again in atomic_destroy_state.
RETURNS:
Duplicated atomic state or NULL when the allocation failed.
void (*)(struct drm_plane *plane,struct drm_plane_state *state) atomic_destroy_state
- Destroy a state duplicated with atomic_duplicate_state and release or unreference all resources it references
int (*)(struct drm_plane *plane,struct drm_plane_state *state,struct drm_property *property,uint64_t val) atomic_set_property
Decode a driver-private property value and store the decoded value into the passed-in state structure. Since the atomic core decodes all standardized properties (even for extensions beyond the core set of properties which might not be implemented by all drivers) this requires drivers to subclass the state structure.
Such driver-private properties should really only be implemented for truly hardware/vendor specific state. Instead it is preferred to standardize atomic extension and decode the properties used to expose such an extension in the core.
Do not call this function directly, use
drm_atomic_plane_set_property()
instead.This callback is optional if the driver does not support any driver-private atomic properties.
NOTE:
This function is called in the state assembly phase of atomic modesets, which can be aborted for any reason (including on userspace’s request to just check whether a configuration would be possible). Drivers MUST NOT touch any persistent state (hardware or software) or data structures except the passed in state parameter.
Also since userspace controls in which order properties are set this function must not do any input validation (since the state update is incomplete and hence likely inconsistent). Instead any such input validation must be done in the various atomic_check callbacks.
RETURNS:
0 if the property has been found, -EINVAL if the property isn’t implemented by the driver (which shouldn’t ever happen, the core only asks for properties attached to this plane). No other validation is allowed by the driver. The core already checks that the property value is within the range (integer, valid enum value, ...) the driver set when registering the property.
int (*)(struct drm_plane *plane,const struct drm_plane_state *state,struct drm_property *property,uint64_t *val) atomic_get_property
Reads out the decoded driver-private property. This is used to implement the GETPLANE IOCTL.
Do not call this function directly, use
drm_atomic_plane_get_property()
instead.This callback is optional if the driver does not support any driver-private atomic properties.
RETURNS:
0 on success, -EINVAL if the property isn’t implemented by the driver (which should never happen, the core only asks for properties attached to this plane).
int (*)(struct drm_plane *plane) late_register
This optional hook can be used to register additional userspace interfaces attached to the plane like debugfs interfaces. It is called late in the driver load sequence from
drm_dev_register()
. Everything added from this callback should be unregistered in the early_unregister callback.Returns:
0 on success, or a negative error code on failure.
void (*)(struct drm_plane *plane) early_unregister
- This optional hook should be used to unregister the additional
userspace interfaces attached to the plane from
late_unregister()
. It is called fromdrm_dev_unregister()
, early in the driver unload sequence to disable userspace access before data structures are torndown.
-
struct
drm_plane
¶ central DRM plane control structure
Definition
struct drm_plane {
struct drm_device * dev;
struct list_head head;
char * name;
struct drm_modeset_lock mutex;
struct drm_mode_object base;
uint32_t possible_crtcs;
uint32_t * format_types;
unsigned int format_count;
bool format_default;
struct drm_crtc * crtc;
struct drm_framebuffer * fb;
struct drm_framebuffer * old_fb;
const struct drm_plane_funcs * funcs;
struct drm_object_properties properties;
enum drm_plane_type type;
unsigned index;
const struct drm_plane_helper_funcs * helper_private;
struct drm_plane_state * state;
struct drm_property * zpos_property;
};
Members
struct drm_device * dev
- DRM device this plane belongs to
struct list_head head
- for list management
char * name
- human readable name, can be overwritten by the driver
struct drm_modeset_lock mutex
- Protects modeset plane state, together with the mutex of
drm_crtc
this plane is linked to (when active, getting actived or getting disabled). struct drm_mode_object base
- base mode object
uint32_t possible_crtcs
- pipes this plane can be bound to
uint32_t * format_types
- array of formats supported by this plane
unsigned int format_count
- number of formats supported
bool format_default
- driver hasn’t supplied supported formats for the plane
struct drm_crtc * crtc
- currently bound CRTC
struct drm_framebuffer * fb
- currently bound fb
struct drm_framebuffer * old_fb
- Temporary tracking of the old fb while a modeset is ongoing. Used by
drm_mode_set_config_internal()
to implement correct refcounting. const struct drm_plane_funcs * funcs
- helper functions
struct drm_object_properties properties
- property tracking for this plane
enum drm_plane_type type
- type of plane (overlay, primary, cursor)
unsigned index
- Position inside the mode_config.list, can be used as an array index. It is invariant over the lifetime of the plane.
const struct drm_plane_helper_funcs * helper_private
- mid-layer private data
struct drm_plane_state * state
- current atomic state for this plane
struct drm_property * zpos_property
- zpos property for this plane
-
struct
drm_bridge_funcs
¶ drm_bridge control functions
Definition
struct drm_bridge_funcs {
int (* attach) (struct drm_bridge *bridge);
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,struct drm_display_mode *mode,struct drm_display_mode *adjusted_mode);
void (* pre_enable) (struct drm_bridge *bridge);
void (* enable) (struct drm_bridge *bridge);
};
Members
int (*)(struct drm_bridge *bridge) attach
- Called during drm_bridge_attach
bool (*)(struct drm_bridge *bridge,const struct drm_display_mode *mode,struct drm_display_mode *adjusted_mode) mode_fixup
This callback is used to validate and adjust a mode. The paramater mode is the display mode that should be fed to the next element in the display chain, either the final
drm_connector
or the nextdrm_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.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.
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.
RETURNS:
True if an acceptable configuration is possible, false if the modeset operation should be rejected.
void (*)(struct drm_bridge *bridge) 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 ->:c:func:disable() function. If the preceding element is a
drm_encoder
it’s called right before the encoder’s ->:c:func:disable(), ->:c:func:prepare() or ->:c:func:dpms() hook from structdrm_encoder_helper_funcs
.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.
void (*)(struct drm_bridge *bridge) 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 ->:c:func:post_disable() function. If the preceding element is a
drm_encoder
it’s called right after the encoder’s ->:c:func:disable(), ->:c:func:prepare() or ->:c:func:dpms() hook from structdrm_encoder_helper_funcs
.The bridge must assume that the display pipe (i.e. clocks and timing singals) feeding it is no longer running when this callback is called.
The post_disable callback is optional.
void (*)(struct drm_bridge *bridge,struct drm_display_mode *mode,struct drm_display_mode *adjusted_mode) mode_set
- This callback should set the given mode on the bridge. It is called after the ->:c:func:mode_set() callback for the preceding element in the display pipeline has been called already. The display pipe (i.e. clocks and timing signals) is off when this function is called.
void (*)(struct drm_bridge *bridge) 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 ->:c:func:pre_enable() function. If the preceding element is a
drm_encoder
it’s called right before the encoder’s ->:c:func:enable(), ->:c:func:commit() or ->:c:func:dpms() hook from structdrm_encoder_helper_funcs
.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.
void (*)(struct drm_bridge *bridge) 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 ->:c:func:enable() function. If the preceding element is a
drm_encoder
it’s called right after the encoder’s ->:c:func:enable(), ->:c:func:commit() or ->:c:func:dpms() hook from structdrm_encoder_helper_funcs
.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.
-
struct
drm_bridge
¶ central DRM bridge control structure
Definition
struct drm_bridge {
struct drm_device * dev;
struct drm_encoder * encoder;
struct drm_bridge * next;
#ifdef CONFIG_OF
struct device_node * of_node;
#endif
struct list_head list;
const struct drm_bridge_funcs * funcs;
void * driver_private;
};
Members
struct drm_device * dev
- DRM device this bridge belongs to
struct drm_encoder * encoder
- encoder to which this bridge is connected
struct drm_bridge * next
- the next bridge in the encoder chain
struct device_node * of_node
- device node pointer to the bridge
struct list_head list
- to keep track of all added bridges
const struct drm_bridge_funcs * funcs
- control functions
void * driver_private
- pointer to the bridge driver’s internal context
-
struct
drm_crtc_commit
¶ track modeset commits on a CRTC
Definition
struct drm_crtc_commit {
struct drm_crtc * crtc;
struct kref ref;
struct completion flip_done;
struct completion hw_done;
struct completion cleanup_done;
struct list_head commit_entry;
struct drm_pending_vblank_event * event;
};
Members
struct drm_crtc * crtc
- DRM CRTC for this commit.
struct kref ref
- Reference count for this structure. Needed to allow blocking on completions without the risk of the completion disappearing meanwhile.
struct completion flip_done
- Will be signaled when the hardware has flipped to the new set of buffers. Signals at the same time as when the drm event for this commit is sent to userspace, or when an out-fence is singalled. Note that for most hardware, in most cases this happens after hw_done is signalled.
struct completion hw_done
Will be signalled when all hw register changes for this commit have been written out. Especially when disabling a pipe this can be much later than than flip_done, since that can signal already when the screen goes black, whereas to fully shut down a pipe more register I/O is required.
Note that this does not need to include separately reference-counted resources like backing storage buffer pinning, or runtime pm management.
struct completion cleanup_done
- Will be signalled after old buffers have been cleaned up by calling
drm_atomic_helper_cleanup_planes()
. Since this can only happen after a vblank wait completed it might be a bit later. This completion is useful to throttle updates and avoid hardware updates getting ahead of the buffer cleanup too much. struct list_head commit_entry
- Entry on the per-CRTC commit_list. Protected by crtc->commit_lock.
struct drm_pending_vblank_event * event
drm_pending_vblank_event
pointer to clean up private events.
Description
This structure is used to track pending modeset changes and atomic commit on a per-CRTC basis. Since updating the list should never block this structure is reference counted to allow waiters to safely wait on an event to complete, without holding any locks.
It has 3 different events in total to allow a fine-grained synchronization between outstanding updates:
atomic commit thread hardware
write new state into hardware ----> ...
signal hw_done
switch to new state on next
... v/hblank
wait for buffers to show up ...
... send completion irq
irq handler signals flip_done
cleanup old buffers
signal cleanup_done
wait for flip_done <----
clean up atomic state
The important bit to know is that cleanup_done is the terminal event, but the ordering between flip_done and hw_done is entirely up to the specific driver and modeset state change.
For an implementation of how to use this look at
drm_atomic_helper_setup_commit()
from the atomic helper library.
-
struct
drm_atomic_state
¶ the global state object for atomic updates
Definition
struct drm_atomic_state {
struct drm_device * dev;
bool allow_modeset:1;
bool legacy_cursor_update:1;
bool legacy_set_config:1;
struct __drm_planes_state * planes;
struct __drm_crtcs_state * crtcs;
int num_connector;
struct __drm_connnectors_state * connectors;
struct drm_modeset_acquire_ctx * acquire_ctx;
struct work_struct commit_work;
};
Members
struct drm_device * dev
- parent DRM device
bool:1 allow_modeset
- allow full modeset
bool:1 legacy_cursor_update
- hint to enforce legacy cursor IOCTL semantics
bool:1 legacy_set_config
- Disable conflicting encoders instead of failing with -EINVAL.
struct __drm_planes_state * planes
- pointer to array of structures with per-plane data
struct __drm_crtcs_state * crtcs
- pointer to array of CRTC pointers
int num_connector
- size of the connectors and connector_states arrays
struct __drm_connnectors_state * connectors
- pointer to array of structures with per-connector data
struct drm_modeset_acquire_ctx * acquire_ctx
- acquire context for this atomic modeset state update
struct work_struct commit_work
- Work item which can be used by the driver or helpers to execute the commit without blocking.
-
struct
drm_mode_set
¶ new values for a CRTC config change
Definition
struct drm_mode_set {
struct drm_framebuffer * fb;
struct drm_crtc * crtc;
struct drm_display_mode * mode;
uint32_t x;
uint32_t y;
struct drm_connector ** connectors;
size_t num_connectors;
};
Members
struct drm_framebuffer * fb
- framebuffer to use for new config
struct drm_crtc * crtc
- CRTC whose configuration we’re about to change
struct drm_display_mode * mode
- mode timings to use
uint32_t x
- position of this CRTC relative to fb
uint32_t y
- position of this CRTC relative to fb
struct drm_connector ** connectors
- array of connectors to drive with this CRTC if possible
size_t num_connectors
- size of connectors array
Description
Represents a single crtc the connectors that it drives with what mode and from which framebuffer it scans out from.
This is used to set modes.
-
struct
drm_mode_config_funcs
¶ basic driver provided mode setting functions
Definition
struct drm_mode_config_funcs {
struct drm_framebuffer *(* fb_create) (struct drm_device *dev,struct drm_file *file_priv,const struct drm_mode_fb_cmd2 *mode_cmd);
void (* output_poll_changed) (struct drm_device *dev);
int (* atomic_check) (struct drm_device *dev,struct drm_atomic_state *state);
int (* atomic_commit) (struct drm_device *dev,struct drm_atomic_state *state,bool nonblock);
struct drm_atomic_state *(* atomic_state_alloc) (struct drm_device *dev);
void (* atomic_state_clear) (struct drm_atomic_state *state);
void (* atomic_state_free) (struct drm_atomic_state *state);
};
Members
struct drm_framebuffer *(*)(struct drm_device *dev,struct drm_file *file_priv,const struct drm_mode_fb_cmd2 *mode_cmd) fb_create
Create a new framebuffer object. The core does basic checks on the requested metadata, but most of that is left to the driver. See struct
drm_mode_fb_cmd2
for details.If the parameters are deemed valid and the backing storage objects in the underlying memory manager all exist, then the driver allocates a new
drm_framebuffer
structure, subclassed to contain driver-specific information (like the internal native buffer object references). It also needs to fill out all relevant metadata, which should be done by callingdrm_helper_mode_fill_fb_struct()
.The initialization is finalized by calling
drm_framebuffer_init()
, which registers the framebuffer and makes it accessible to other threads.RETURNS:
A new framebuffer with an initial reference count of 1 or a negative error code encoded with
ERR_PTR()
.void (*)(struct drm_device *dev) output_poll_changed
Callback used by helpers to inform the driver of output configuration changes.
Drivers implementing fbdev emulation with the helpers can call drm_fb_helper_hotplug_changed from this hook to inform the fbdev helper of output changes.
FIXME:
Except that there’s no vtable for device-level helper callbacks there’s no reason this is a core function.
int (*)(struct drm_device *dev,struct drm_atomic_state *state) atomic_check
This is the only hook to validate an atomic modeset update. This function must reject any modeset and state changes which the hardware or driver doesn’t support. This includes but is of course not limited to:
- Checking that the modes, framebuffers, scaling and placement requirements and so on are within the limits of the hardware.
- Checking that any hidden shared resources are not oversubscribed. This can be shared PLLs, shared lanes, overall memory bandwidth, display fifo space (where shared between planes or maybe even CRTCs).
- Checking that virtualized resources exported to userspace are not oversubscribed. For various reasons it can make sense to expose more planes, crtcs or encoders than which are physically there. One example is dual-pipe operations (which generally should be hidden from userspace if when lockstepped in hardware, exposed otherwise), where a plane might need 1 hardware plane (if it’s just on one pipe), 2 hardware planes (when it spans both pipes) or maybe even shared a hardware plane with a 2nd plane (if there’s a compatible plane requested on the area handled by the other pipe).
- Check that any transitional state is possible and that if requested, the update can indeed be done in the vblank period without temporarily disabling some functions.
- Check any other constraints the driver or hardware might have.
- This callback also needs to correctly fill out the
drm_crtc_state
in this update to make sure thatdrm_atomic_crtc_needs_modeset()
reflects the nature of the possible update and returns true if and only if the update cannot be applied without tearing within one vblank on that CRTC. The core uses that information to reject updates which require a full modeset (i.e. blanking the screen, or at least pausing updates for a substantial amount of time) if userspace has disallowed that in its request. - The driver also does not need to repeat basic input validation like done for the corresponding legacy entry points. The core does that before calling this hook.
See the documentation of atomic_commit for an exhaustive list of error conditions which don’t have to be checked at the ->:c:func:atomic_check() stage?
See the documentation for struct
drm_atomic_state
for how exactly an atomic modeset update is described.Drivers using the atomic helpers can implement this hook using
drm_atomic_helper_check()
, or one of the exported sub-functions of it.RETURNS:
0 on success or one of the below negative error codes:
- -EINVAL, if any of the above constraints are violated.
- -EDEADLK, when returned from an attempt to acquire an additional
drm_modeset_lock
throughdrm_modeset_lock()
. - -ENOMEM, if allocating additional state sub-structures failed due to lack of memory.
- -EINTR, -EAGAIN or -ERESTARTSYS, if the IOCTL should be restarted. This can either be due to a pending signal, or because the driver needs to completely bail out to recover from an exceptional situation like a GPU hang. From a userspace point all errors are treated equally.
int (*)(struct drm_device *dev,struct drm_atomic_state *state,bool nonblock) atomic_commit
This is the only hook to commit an atomic modeset update. The core guarantees that atomic_check has been called successfully before calling this function, and that nothing has been changed in the interim.
See the documentation for struct
drm_atomic_state
for how exactly an atomic modeset update is described.Drivers using the atomic helpers can implement this hook using
drm_atomic_helper_commit()
, or one of the exported sub-functions of it.Nonblocking commits (as indicated with the nonblock parameter) must do any preparatory work which might result in an unsuccessful commit in the context of this callback. The only exceptions are hardware errors resulting in -EIO. But even in that case the driver must ensure that the display pipe is at least running, to avoid compositors crashing when pageflips don’t work. Anything else, specifically committing the update to the hardware, should be done without blocking the caller. For updates which do not require a modeset this must be guaranteed.
The driver must wait for any pending rendering to the new framebuffers to complete before executing the flip. It should also wait for any pending rendering from other drivers if the underlying buffer is a shared dma-buf. Nonblocking commits must not wait for rendering in the context of this callback.
An application can request to be notified when the atomic commit has completed. These events are per-CRTC and can be distinguished by the CRTC index supplied in
drm_event
to userspace.The drm core will supply a struct
drm_event
in the event member of each CRTC’sdrm_crtc_state
structure. This can be handled by thedrm_crtc_send_vblank_event()
function, which the driver should call on the provided event upon completion of the atomic commit. Note that if the driver supports vblank signalling and timestamping the vblank counters and timestamps must agree with the ones returned from page flip events. With the current vblank helper infrastructure this can be achieved by holding a vblank reference while the page flip is pending, acquired throughdrm_crtc_vblank_get()
and released withdrm_crtc_vblank_put()
. Drivers are free to implement their own vblank counter and timestamp tracking though, e.g. if they have accurate timestamp registers in hardware.NOTE:
Drivers are not allowed to shut down any display pipe successfully enabled through an atomic commit on their own. Doing so can result in compositors crashing if a page flip is suddenly rejected because the pipe is off.
RETURNS:
0 on success or one of the below negative error codes:
- -EBUSY, if a nonblocking updated is requested and there is an earlier updated pending. Drivers are allowed to support a queue of outstanding updates, but currently no driver supports that. Note that drivers must wait for preceding updates to complete if a synchronous update is requested, they are not allowed to fail the commit in that case.
- -ENOMEM, if the driver failed to allocate memory. Specifically this can happen when trying to pin framebuffers, which must only be done when committing the state.
- -ENOSPC, as a refinement of the more generic -ENOMEM to indicate that the driver has run out of vram, iommu space or similar GPU address space needed for framebuffer.
- -EIO, if the hardware completely died.
- -EINTR, -EAGAIN or -ERESTARTSYS, if the IOCTL should be restarted. This can either be due to a pending signal, or because the driver needs to completely bail out to recover from an exceptional situation like a GPU hang. From a userspace point of view all errors are treated equally.
This list is exhaustive. Specifically this hook is not allowed to return -EINVAL (any invalid requests should be caught in atomic_check) or -EDEADLK (this function must not acquire additional modeset locks).
struct drm_atomic_state *(*)(struct drm_device *dev) atomic_state_alloc
This optional hook can be used by drivers that want to subclass struct
drm_atomic_state
to be able to track their own driver-private global state easily. If this hook is implemented, drivers must also implement atomic_state_clear and atomic_state_free.RETURNS:
A new
drm_atomic_state
on success or NULL on failure.void (*)(struct drm_atomic_state *state) atomic_state_clear
This hook must clear any driver private state duplicated into the passed-in
drm_atomic_state
. This hook is called when the caller encountered adrm_modeset_lock
deadlock and needs to drop all already acquired locks as part of the deadlock avoidance dance implemented indrm_modeset_lock_backoff()
.Any duplicated state must be invalidated since a concurrent atomic update might change it, and the drm atomic interfaces always apply updates as relative changes to the current state.
Drivers that implement this must call
drm_atomic_state_default_clear()
to clear common state.void (*)(struct drm_atomic_state *state) atomic_state_free
This hook needs driver private resources and the
drm_atomic_state
itself. Note that the core first callsdrm_atomic_state_clear()
to avoid code duplicate between the clear and free hooks.Drivers that implement this must call
drm_atomic_state_default_free()
to release common resources.
Description
Some global (i.e. not per-CRTC, connector, etc) mode setting functions that involve drivers.
-
struct
drm_mode_config
¶ Mode configuration control structure
Definition
struct drm_mode_config {
struct mutex mutex;
struct drm_modeset_lock connection_mutex;
struct drm_modeset_acquire_ctx * acquire_ctx;
struct mutex idr_mutex;
struct idr crtc_idr;
struct idr tile_idr;
struct mutex fb_lock;
int num_fb;
struct list_head fb_list;
int num_connector;
struct ida connector_ida;
struct list_head connector_list;
int num_encoder;
struct list_head encoder_list;
int num_overlay_plane;
int num_total_plane;
struct list_head plane_list;
int num_crtc;
struct list_head crtc_list;
struct list_head property_list;
int min_width;
int min_height;
int max_width;
int max_height;
const struct drm_mode_config_funcs * funcs;
resource_size_t fb_base;
bool poll_enabled;
bool poll_running;
bool delayed_event;
struct delayed_work output_poll_work;
struct mutex blob_lock;
struct list_head property_blob_list;
struct drm_property * edid_property;
struct drm_property * dpms_property;
struct drm_property * path_property;
struct drm_property * tile_property;
struct drm_property * plane_type_property;
struct drm_property * rotation_property;
struct drm_property * prop_src_x;
struct drm_property * prop_src_y;
struct drm_property * prop_src_w;
struct drm_property * prop_src_h;
struct drm_property * prop_crtc_x;
struct drm_property * prop_crtc_y;
struct drm_property * prop_crtc_w;
struct drm_property * prop_crtc_h;
struct drm_property * prop_fb_id;
struct drm_property * prop_crtc_id;
struct drm_property * prop_active;
struct drm_property * prop_mode_id;
struct drm_property * dvi_i_subconnector_property;
struct drm_property * dvi_i_select_subconnector_property;
struct drm_property * tv_subconnector_property;
struct drm_property * tv_select_subconnector_property;
struct drm_property * tv_mode_property;
struct drm_property * tv_left_margin_property;
struct drm_property * tv_right_margin_property;
struct drm_property * tv_top_margin_property;
struct drm_property * tv_bottom_margin_property;
struct drm_property * tv_brightness_property;
struct drm_property * tv_contrast_property;
struct drm_property * tv_flicker_reduction_property;
struct drm_property * tv_overscan_property;
struct drm_property * tv_saturation_property;
struct drm_property * tv_hue_property;
struct drm_property * scaling_mode_property;
struct drm_property * aspect_ratio_property;
struct drm_property * dirty_info_property;
struct drm_property * degamma_lut_property;
struct drm_property * degamma_lut_size_property;
struct drm_property * ctm_property;
struct drm_property * gamma_lut_property;
struct drm_property * gamma_lut_size_property;
struct drm_property * suggested_x_property;
struct drm_property * suggested_y_property;
uint32_t preferred_depth;
uint32_t prefer_shadow;
bool async_page_flip;
bool allow_fb_modifiers;
uint32_t cursor_width;
uint32_t cursor_height;
struct drm_mode_config_helper_funcs * helper_private;
};
Members
struct mutex mutex
- mutex protecting KMS related lists and structures
struct drm_modeset_lock connection_mutex
- ww mutex protecting connector state and routing
struct drm_modeset_acquire_ctx * acquire_ctx
- global implicit acquire context used by atomic drivers for legacy IOCTLs
struct mutex idr_mutex
- Mutex for KMS ID allocation and management. Protects both crtc_idr and tile_idr.
struct idr crtc_idr
- Main KMS ID tracking object. Use this idr for all IDs, fb, crtc, connector, modes - just makes life easier to have only one.
struct idr tile_idr
- Use this idr for allocating new IDs for tiled sinks like use in some high-res DP MST screens.
struct mutex fb_lock
- mutex to protect fb state and lists
int num_fb
- number of fbs available
struct list_head fb_list
- list of framebuffers available
int num_connector
- Number of connectors on this device.
struct ida connector_ida
- ID allocator for connector indices.
struct list_head connector_list
- List of connector objects.
int num_encoder
- number of encoders on this device
struct list_head encoder_list
- list of encoder objects
int num_overlay_plane
- number of overlay planes on this device
int num_total_plane
- number of universal (i.e. with primary/curso) planes on this device
struct list_head plane_list
- list of plane objects
int num_crtc
- number of CRTCs on this device
struct list_head crtc_list
- list of CRTC objects
struct list_head property_list
- list of property objects
int min_width
- minimum pixel width on this device
int min_height
- minimum pixel height on this device
int max_width
- maximum pixel width on this device
int max_height
- maximum pixel height on this device
const struct drm_mode_config_funcs * funcs
- core driver provided mode setting functions
resource_size_t fb_base
- base address of the framebuffer
bool poll_enabled
- track polling support for this device
bool poll_running
- track polling status for this device
bool delayed_event
- track delayed poll uevent deliver for this device
struct delayed_work output_poll_work
- delayed work for polling in process context
struct mutex blob_lock
- mutex for blob property allocation and management @*_property: core property tracking
struct list_head property_blob_list
- list of all the blob property objects
struct drm_property * edid_property
- Default connector property to hold the EDID of the currently connected sink, if any.
struct drm_property * dpms_property
- Default connector property to control the connector’s DPMS state.
struct drm_property * path_property
- Default connector property to hold the DP MST path for the port.
struct drm_property * tile_property
- Default connector property to store the tile position of a tiled screen, for sinks which need to be driven with multiple CRTCs.
struct drm_property * plane_type_property
- Default plane property to differentiate CURSOR, PRIMARY and OVERLAY legacy uses of planes.
struct drm_property * rotation_property
- Optional property for planes or CRTCs to specifiy rotation.
struct drm_property * prop_src_x
- Default atomic plane property for the plane source
position in the connected
drm_framebuffer
. struct drm_property * prop_src_y
- Default atomic plane property for the plane source
position in the connected
drm_framebuffer
. struct drm_property * prop_src_w
- Default atomic plane property for the plane source
position in the connected
drm_framebuffer
. struct drm_property * prop_src_h
- Default atomic plane property for the plane source
position in the connected
drm_framebuffer
. struct drm_property * prop_crtc_x
- Default atomic plane property for the plane destination
position in the
drm_crtc
is is being shown on. struct drm_property * prop_crtc_y
- Default atomic plane property for the plane destination
position in the
drm_crtc
is is being shown on. struct drm_property * prop_crtc_w
- Default atomic plane property for the plane destination
position in the
drm_crtc
is is being shown on. struct drm_property * prop_crtc_h
- Default atomic plane property for the plane destination
position in the
drm_crtc
is is being shown on. struct drm_property * prop_fb_id
- Default atomic plane property to specify the
drm_framebuffer
. struct drm_property * prop_crtc_id
- Default atomic plane property to specify the
drm_crtc
. struct drm_property * prop_active
- Default atomic CRTC property to control the active state, which is the simplified implementation for DPMS in atomic drivers.
struct drm_property * prop_mode_id
- Default atomic CRTC property to set the mode for a CRTC. A 0 mode implies that the CRTC is entirely disabled - all connectors must be of and active must be set to disabled, too.
struct drm_property * dvi_i_subconnector_property
- Optional DVI-I property to differentiate between analog or digital mode.
struct drm_property * dvi_i_select_subconnector_property
- Optional DVI-I property to select between analog or digital mode.
struct drm_property * tv_subconnector_property
- Optional TV property to differentiate between different TV connector types.
struct drm_property * tv_select_subconnector_property
- Optional TV property to select between different TV connector types.
struct drm_property * tv_mode_property
- Optional TV property to select the output TV mode.
struct drm_property * tv_left_margin_property
- Optional TV property to set the left margin.
struct drm_property * tv_right_margin_property
- Optional TV property to set the right margin.
struct drm_property * tv_top_margin_property
- Optional TV property to set the right margin.
struct drm_property * tv_bottom_margin_property
- Optional TV property to set the right margin.
struct drm_property * tv_brightness_property
- Optional TV property to set the brightness.
struct drm_property * tv_contrast_property
- Optional TV property to set the contrast.
struct drm_property * tv_flicker_reduction_property
- Optional TV property to control the flicker reduction mode.
struct drm_property * tv_overscan_property
- Optional TV property to control the overscan setting.
struct drm_property * tv_saturation_property
- Optional TV property to set the saturation.
struct drm_property * tv_hue_property
- Optional TV property to set the hue.
struct drm_property * scaling_mode_property
- Optional connector property to control the upscaling, mostly used for built-in panels.
struct drm_property * aspect_ratio_property
- Optional connector property to control the HDMI infoframe aspect ratio setting.
struct drm_property * dirty_info_property
- Optional connector property to give userspace a hint that the DIRTY_FB ioctl should be used.
struct drm_property * degamma_lut_property
- Optional CRTC property to set the LUT used to convert the framebuffer’s colors to linear gamma.
struct drm_property * degamma_lut_size_property
- Optional CRTC property for the size of the degamma LUT as supported by the driver (read-only).
struct drm_property * ctm_property
- Optional CRTC property to set the matrix used to convert colors after the lookup in the degamma LUT.
struct drm_property * gamma_lut_property
- Optional CRTC property to set the LUT used to convert the colors, after the CTM matrix, to the gamma space of the connected screen.
struct drm_property * gamma_lut_size_property
- Optional CRTC property for the size of the gamma LUT as supported by the driver (read-only).
struct drm_property * suggested_x_property
- Optional connector property with a hint for the position of the output on the host’s screen.
struct drm_property * suggested_y_property
- Optional connector property with a hint for the position of the output on the host’s screen.
uint32_t preferred_depth
- preferred RBG pixel depth, used by fb helpers
uint32_t prefer_shadow
- hint to userspace to prefer shadow-fb rendering
bool async_page_flip
- Does this device support async flips on the primary plane?
bool allow_fb_modifiers
- Whether the driver supports fb modifiers in the ADDFB2.1 ioctl call.
uint32_t cursor_width
- hint to userspace for max cursor width
uint32_t cursor_height
- hint to userspace for max cursor height
struct drm_mode_config_helper_funcs * helper_private
- mid-layer private data
Description
Core mode resource tracking structure. All CRTC, encoders, and connectors enumerated by the driver are added here, as are global properties. Some global restrictions are also here, e.g. dimension restrictions.
-
drm_for_each_plane_mask
(plane, dev, plane_mask)¶ iterate over planes specified by bitmask
Parameters
plane
- the loop cursor
dev
- the DRM device
plane_mask
- bitmask of plane indices
Description
Iterate over all planes specified by bitmask.
-
drm_for_each_encoder_mask
(encoder, dev, encoder_mask)¶ iterate over encoders specified by bitmask
Parameters
encoder
- the loop cursor
dev
- the DRM device
encoder_mask
- bitmask of encoder indices
Description
Iterate over all encoders specified by bitmask.
Parameters
struct drm_crtc * crtc
- CRTC to find index for
Description
Given a registered CRTC, return the index of that CRTC within a DRM device’s list of CRTCs.
Parameters
struct drm_crtc * crtc
- CRTC to find mask for
Description
Given a registered CRTC, return the mask bit of that CRTC for an encoder’s possible_crtcs field.
-
unsigned int
drm_encoder_index
(struct drm_encoder * encoder)¶ find the index of a registered encoder
Parameters
struct drm_encoder * encoder
- encoder to find index for
Description
Given a registered encoder, return the index of that encoder within a DRM device’s list of encoders.
-
bool
drm_encoder_crtc_ok
(struct drm_encoder * encoder, struct drm_crtc * crtc)¶ can a given crtc drive a given encoder?
Parameters
struct drm_encoder * encoder
- encoder to test
struct drm_crtc * crtc
- crtc to test
Description
Return false if encoder can’t be driven by crtc, true otherwise.
Parameters
struct drm_plane * plane
- plane to find index for
Description
Given a registered plane, return the index of that plane within a DRM device’s list of planes.
-
struct drm_connector *
drm_connector_lookup
(struct drm_device * dev, uint32_t id)¶ lookup connector object
Parameters
struct drm_device * dev
- DRM device
uint32_t id
- connector object id
Description
This function looks up the connector object specified by id add takes a reference to it.
-
void
drm_framebuffer_reference
(struct drm_framebuffer * fb)¶ incr the fb refcnt
Parameters
struct drm_framebuffer * fb
- framebuffer
Description
This functions increments the fb’s refcount.
-
void
drm_framebuffer_unreference
(struct drm_framebuffer * fb)¶ unref a framebuffer
Parameters
struct drm_framebuffer * fb
- framebuffer to unref
Description
This functions decrements the fb’s refcount and frees it if it drops to zero.
-
uint32_t
drm_framebuffer_read_refcount
(struct drm_framebuffer * fb)¶ read the framebuffer reference count.
Parameters
struct drm_framebuffer * fb
- framebuffer
Description
This functions returns the framebuffer’s reference count.
-
void
drm_connector_reference
(struct drm_connector * connector)¶ incr the connector refcnt
Parameters
struct drm_connector * connector
- connector
Description
This function increments the connector’s refcount.
-
void
drm_connector_unreference
(struct drm_connector * connector)¶ unref a connector
Parameters
struct drm_connector * connector
- connector to unref
Description
This function decrements the connector’s refcount and frees it if it drops to zero.
KMS Locking¶
As KMS moves toward more fine grained locking, and atomic ioctl where
userspace can indirectly control locking order, it becomes necessary
to use ww_mutex
and acquire-contexts to avoid deadlocks. But because
the locking is more distributed around the driver code, we want a bit
of extra utility/tracking out of our acquire-ctx. This is provided
by drm_modeset_lock / drm_modeset_acquire_ctx.
For basic principles of ww_mutex
, see: Documentation/locking/ww-mutex-design.txt
The basic usage pattern is to:
drm_modeset_acquire_init(:c:type:`ctx`)
retry:
foreach (lock in random_ordered_set_of_locks) {
ret = drm_modeset_lock(lock, :c:type:`ctx`)
if (ret == -EDEADLK) {
drm_modeset_backoff(:c:type:`ctx`);
goto retry;
}
}
... do stuff ...
drm_modeset_drop_locks(:c:type:`ctx`);
drm_modeset_acquire_fini(:c:type:`ctx`);
On top of of these per-object locks using :c:type:`ww_mutex` there's also an overall
dev->mode_config.lock, for protecting everything else. Mostly this means
probe state of connectors, and preventing hotplug add/removal of connectors.
Finally there's a bunch of dedicated locks to protect drm core internal
lists and lookup data structures.
-
struct
drm_modeset_acquire_ctx
¶ locking context (see ww_acquire_ctx)
Definition
struct drm_modeset_acquire_ctx {
struct ww_acquire_ctx ww_ctx;
struct drm_modeset_lock * contended;
struct list_head locked;
bool trylock_only;
};
Members
struct ww_acquire_ctx ww_ctx
- base acquire ctx
struct drm_modeset_lock * contended
- used internally for -EDEADLK handling
struct list_head locked
- list of held locks
bool trylock_only
- trylock mode used in atomic contexts/panic notifiers
Description
Each thread competing for a set of locks must use one acquire ctx. And if any lock fxn returns -EDEADLK, it must backoff and retry.
-
struct
drm_modeset_lock
¶ used for locking modeset resources.
Definition
struct drm_modeset_lock {
struct ww_mutex mutex;
struct list_head head;
};
Members
struct ww_mutex mutex
- resource locking
struct list_head head
- used to hold it’s place on state->locked list when part of an atomic update
Description
Used for locking CRTCs and other modeset resources.
-
void
drm_modeset_lock_init
(struct drm_modeset_lock * lock)¶ initialize lock
Parameters
struct drm_modeset_lock * lock
- lock to init
-
void
drm_modeset_lock_fini
(struct drm_modeset_lock * lock)¶ cleanup lock
Parameters
struct drm_modeset_lock * lock
- lock to cleanup
-
bool
drm_modeset_is_locked
(struct drm_modeset_lock * lock)¶ equivalent to
mutex_is_locked()
Parameters
struct drm_modeset_lock * lock
- lock to check
-
void
drm_modeset_lock_all
(struct drm_device * dev)¶ take all modeset locks
Parameters
struct drm_device * dev
- DRM device
Description
This function takes all modeset locks, suitable where a more fine-grained
scheme isn’t (yet) implemented. Locks must be dropped by calling the
drm_modeset_unlock_all()
function.
This function is deprecated. It allocates a lock acquisition context and
stores it in the DRM device’s ->mode_config. This facilitate conversion of
existing code because it removes the need to manually deal with the
acquisition context, but it is also brittle because the context is global
and care must be taken not to nest calls. New code should use the
drm_modeset_lock_all_ctx()
function and pass in the context explicitly.
-
void
drm_modeset_unlock_all
(struct drm_device * dev)¶ drop all modeset locks
Parameters
struct drm_device * dev
- DRM device
Description
This function drops all modeset locks taken by a previous call to the
drm_modeset_lock_all()
function.
This function is deprecated. It uses the lock acquisition context stored
in the DRM device’s ->mode_config. This facilitates conversion of existing
code because it removes the need to manually deal with the acquisition
context, but it is also brittle because the context is global and care must
be taken not to nest calls. New code should pass the acquisition context
directly to the drm_modeset_drop_locks()
function.
-
void
drm_modeset_lock_crtc
(struct drm_crtc * crtc, struct drm_plane * plane)¶ lock crtc with hidden acquire ctx for a plane update
Parameters
struct drm_crtc * crtc
- DRM CRTC
struct drm_plane * plane
- DRM plane to be updated on crtc
Description
This function locks the given crtc and plane (which should be either the primary or cursor plane) using a hidden acquire context. This is necessary so that drivers internally using the atomic interfaces can grab further locks with the lock acquire context.
Note that plane can be NULL, e.g. when the cursor support hasn’t yet been converted to universal planes yet.
-
struct drm_modeset_acquire_ctx *
drm_modeset_legacy_acquire_ctx
(struct drm_crtc * crtc)¶ find acquire ctx for legacy ioctls
Parameters
struct drm_crtc * crtc
- drm crtc
Description
Legacy ioctl operations like cursor updates or page flips only have per-crtc locking, and store the acquire ctx in the corresponding crtc. All other legacy operations take all locks and use a global acquire context. This function grabs the right one.
Parameters
struct drm_crtc * crtc
- drm crtc
Description
This drops the crtc lock acquire with drm_modeset_lock_crtc()
and all other
locks acquired through the hidden context.
-
void
drm_warn_on_modeset_not_all_locked
(struct drm_device * dev)¶ check that all modeset locks are locked
Parameters
struct drm_device * dev
- device
Description
Useful as a debug assert.
-
void
drm_modeset_acquire_init
(struct drm_modeset_acquire_ctx * ctx, uint32_t flags)¶ initialize acquire context
Parameters
struct drm_modeset_acquire_ctx * ctx
- the acquire context
uint32_t flags
- for future
-
void
drm_modeset_acquire_fini
(struct drm_modeset_acquire_ctx * ctx)¶ cleanup acquire context
Parameters
struct drm_modeset_acquire_ctx * ctx
- the acquire context
-
void
drm_modeset_drop_locks
(struct drm_modeset_acquire_ctx * ctx)¶ drop all locks
Parameters
struct drm_modeset_acquire_ctx * ctx
- the acquire context
Description
Drop all locks currently held against this acquire context.
-
void
drm_modeset_backoff
(struct drm_modeset_acquire_ctx * ctx)¶ deadlock avoidance backoff
Parameters
struct drm_modeset_acquire_ctx * ctx
- the acquire context
Description
If deadlock is detected (ie. drm_modeset_lock()
returns -EDEADLK),
you must call this function to drop all currently held locks and
block until the contended lock becomes available.
-
int
drm_modeset_backoff_interruptible
(struct drm_modeset_acquire_ctx * ctx)¶ deadlock avoidance backoff
Parameters
struct drm_modeset_acquire_ctx * ctx
- the acquire context
Description
Interruptible version of drm_modeset_backoff()
-
int
drm_modeset_lock
(struct drm_modeset_lock * lock, struct drm_modeset_acquire_ctx * ctx) take modeset lock
Parameters
struct drm_modeset_lock * lock
- lock to take
struct drm_modeset_acquire_ctx * ctx
- acquire ctx
Description
If ctx is not NULL, then its ww acquire context is used and the
lock will be tracked by the context and can be released by calling
drm_modeset_drop_locks()
. If -EDEADLK is returned, this means a
deadlock scenario has been detected and it is an error to attempt
to take any more locks without first calling drm_modeset_backoff()
.
-
int
drm_modeset_lock_interruptible
(struct drm_modeset_lock * lock, struct drm_modeset_acquire_ctx * ctx)¶ take modeset lock
Parameters
struct drm_modeset_lock * lock
- lock to take
struct drm_modeset_acquire_ctx * ctx
- acquire ctx
Description
Interruptible version of drm_modeset_lock()
-
void
drm_modeset_unlock
(struct drm_modeset_lock * lock)¶ drop modeset lock
Parameters
struct drm_modeset_lock * lock
- lock to release
-
int
drm_modeset_lock_all_ctx
(struct drm_device * dev, struct drm_modeset_acquire_ctx * ctx)¶ take all modeset locks
Parameters
struct drm_device * dev
- DRM device
struct drm_modeset_acquire_ctx * ctx
- lock acquisition context
Description
This function takes all modeset locks, suitable where a more fine-grained scheme isn’t (yet) implemented.
Unlike drm_modeset_lock_all()
, it doesn’t take the dev->mode_config.mutex
since that lock isn’t required for modeset state changes. Callers which
need to grab that lock too need to do so outside of the acquire context
ctx.
Locks acquired with this function should be released by calling the
drm_modeset_drop_locks()
function on ctx.
Return
0 on success or a negative error-code on failure.
KMS Properties¶
Drivers may need to expose additional parameters to applications than those described in the previous sections. KMS supports attaching properties to CRTCs, connectors and planes and offers a userspace API to list, get and set the property values.
Properties are identified by a name that uniquely defines the property purpose, and store an associated value. For all property types except blob properties the value is a 64-bit unsigned integer.
KMS differentiates between properties and property instances. Drivers first create properties and then create and associate individual instances of those properties to objects. A property can be instantiated multiple times and associated with different objects. Values are stored in property instances, and all other property information are stored in the property and shared between all instances of the property.
Every property is created with a type that influences how the KMS core handles the property. Supported property types are
- DRM_MODE_PROP_RANGE
- Range properties report their minimum and maximum admissible values. The KMS core verifies that values set by application fit in that range.
- DRM_MODE_PROP_ENUM
- Enumerated properties take a numerical value that ranges from 0 to the number of enumerated values defined by the property minus one, and associate a free-formed string name to each value. Applications can retrieve the list of defined value-name pairs and use the numerical value to get and set property instance values.
- DRM_MODE_PROP_BITMASK
- Bitmask properties are enumeration properties that additionally restrict all enumerated values to the 0..63 range. Bitmask property instance values combine one or more of the enumerated bits defined by the property.
- DRM_MODE_PROP_BLOB
Blob properties store a binary blob without any format restriction. The binary blobs are created as KMS standalone objects, and blob property instance values store the ID of their associated blob object.
Blob properties are only used for the connector EDID property and cannot be created by drivers.
To create a property drivers call one of the following functions depending on the property type. All property creation functions take property flags and name, as well as type-specific arguments.
- struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, const char *name, uint64_t min, uint64_t max); Create a range property with the given minimum and maximum values.
- struct drm_property *drm_property_create_enum(struct drm_device
*dev, int flags, const char *name, const struct
drm_prop_enum_list *props, int num_values);
Create an enumerated property. The
props
argument points to an array ofnum_values
value-name pairs. - struct drm_property *drm_property_create_bitmask(struct
drm_device *dev, int flags, const char *name, const struct
drm_prop_enum_list *props, int num_values);
Create a bitmask property. The
props
argument points to an array ofnum_values
value-name pairs.
Properties can additionally be created as immutable, in which case they will be read-only for applications but can be modified by the driver. To create an immutable property drivers must set the DRM_MODE_PROP_IMMUTABLE flag at property creation time.
When no array of value-name pairs is readily available at property
creation time for enumerated or range properties, drivers can create the
property using the drm_property_create()
function and
manually add enumeration value-name pairs by calling the
drm_property_add_enum()
function. Care must be taken to
properly specify the property type through the flags
argument.
After creating properties drivers can attach property instances to CRTC,
connector and plane objects by calling the
drm_object_attach_property()
. The function takes a
pointer to the target object, a pointer to the previously created
property and an initial instance value.
Existing KMS Properties¶
The following table gives description of drm properties exposed by various modules/drivers.
Owner Module/Drivers | Group | Property Name | Type | Property Values | Object attached | Description/Restrictions |
---|---|---|---|---|---|---|
DRM | Generic | “rotation” | BITMASK | { 0, “rotate-0” }, { 1, “rotate-90” }, { 2, “rotate-180” }, { 3, “rotate-270” }, { 4, “reflect-x” }, { 5, “reflect-y” } | CRTC, Plane | rotate-(degrees) rotates the image by the specified amount in degrees in counter clockwise direction. reflect-x and reflect-y reflects the image along the specified axis prior to rotation |
“scaling mode” | ENUM | { “None”, “Full”, “Center”, “Full aspect” } | Connector | Supported by: amdgpu, gma500, i915, nouveau and radeon. | ||
Connector | “EDID” | BLOB | IMMUTABLE | 0 | Connector | Contains id of edid blob ptr object. | |
“DPMS” | ENUM | { “On”, “Standby”, “Suspend”, “Off” } | Connector | Contains DPMS operation mode value. | ||
“PATH” | BLOB | IMMUTABLE | 0 | Connector | Contains topology path to a connector. | ||
“TILE” | BLOB | IMMUTABLE | 0 | Connector | Contains tiling information for a connector. | ||
“CRTC_ID” | OBJECT | DRM_MODE_OBJECT_CRTC | Connector | CRTC that connector is attached to (atomic) | ||
Plane | “type” | ENUM | IMMUTABLE | { “Overlay”, “Primary”, “Cursor” } | Plane | Plane type | |
“SRC_X” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source x coordinate in 16.16 fixed point (atomic) | ||
“SRC_Y” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source y coordinate in 16.16 fixed point (atomic) | ||
“SRC_W” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source width in 16.16 fixed point (atomic) | ||
“SRC_H” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source height in 16.16 fixed point (atomic) | ||
“CRTC_X” | SIGNED_RANGE | Min=INT_MIN, Max=INT_MAX | Plane | Scanout CRTC (destination) x coordinate (atomic) | ||
“CRTC_Y” | SIGNED_RANGE | Min=INT_MIN, Max=INT_MAX | Plane | Scanout CRTC (destination) y coordinate (atomic) | ||
“CRTC_W” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout CRTC (destination) width (atomic) | ||
“CRTC_H” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout CRTC (destination) height (atomic) | ||
“FB_ID” | OBJECT | DRM_MODE_OBJECT_FB | Plane | Scanout framebuffer (atomic) | ||
“CRTC_ID” | OBJECT | DRM_MODE_OBJECT_CRTC | Plane | CRTC that plane is attached to (atomic) | ||
“zpos” | RANGE | Min=0, Max=UINT_MAX | Plane,Z-order of the plane.Planes with higher Z-order values are displayed on top, planes with identical Z-order values are display in an undefined order | |||
DVI-I | “subconnector” | ENUM | { “Unknown”, “DVI-D”, “DVI-A” } | Connector | TBD | |
“select subconnector” | ENUM | { “Automatic”, “DVI-D”, “DVI-A” } | Connector | TBD | ||
TV | “subconnector” | ENUM | { “Unknown”, “Composite”, “SVIDEO”, “Component”, “SCART” } | Connector | TBD | |
“select subconnector” | ENUM | { “Automatic”, “Composite”, “SVIDEO”, “Component”, “SCART” } | Connector | TBD | ||
“mode” | ENUM | { “NTSC_M”, “NTSC_J”, “NTSC_443”, “PAL_B” } etc. | Connector | TBD | ||
“left margin” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“right margin” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“top margin” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“bottom margin” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“brightness” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“contrast” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“flicker reduction” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“overscan” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“saturation” | RANGE | Min=0, Max=100 | Connector | TBD | ||
“hue” | RANGE | Min=0, Max=100 | Connector | TBD | ||
Virtual GPU | “suggested X” | RANGE | Min=0, Max=0xffffffff | Connector | property to suggest an X offset for a connector | |
“suggested Y” | RANGE | Min=0, Max=0xffffffff | Connector | property to suggest an Y offset for a connector | ||
Optional | “aspect ratio” | ENUM | { “None”, “4:3”, “16:9” } | Connector | TDB | |
“dirty” | ENUM | IMMUTABLE | { “Off”, “On”, “Annotate” } | Connector | TBD | ||
“DEGAMMA_LUT” | BLOB | 0 | CRTC | DRM property to set the degamma lookup table (LUT) mapping pixel data from the framebuffer before it is given to the transformation matrix. The data is an interpreted as an array of struct drm_color_lut elements. Hardware might choose not to use the full precision of the LUT elements nor use all the elements of the LUT (for example the hardware might choose to interpolate between LUT[0] and LUT[4]). | ||
“DEGAMMA_LUT_SIZE” | RANGE | IMMUTABLE | Min=0, Max=UINT_MAX | CRTC | DRM property to gives the size of the lookup table to be set on the DEGAMMA_LUT property (the size depends on the underlying hardware). | ||
“CTM” | BLOB | 0 | CRTC | DRM property to set the current transformation matrix (CTM) apply to pixel data after the lookup through the degamma LUT and before the lookup through the gamma LUT. The data is an interpreted as a struct drm_color_ctm. | ||
“GAMMA_LUT” | BLOB | 0 | CRTC | DRM property to set the gamma lookup table (LUT) mapping pixel data after to the transformation matrix to data sent to the connector. The data is an interpreted as an array of struct drm_color_lut elements. Hardware might choose not to use the full precision of the LUT elements nor use all the elements of the LUT (for example the hardware might choose to interpolate between LUT[0] and LUT[4]). | ||
“GAMMA_LUT_SIZE” | RANGE | IMMUTABLE | Min=0, Max=UINT_MAX | CRTC | DRM property to gives the size of the lookup table to be set on the GAMMA_LUT property (the size depends on the underlying hardware). | ||
i915 | Generic | “Broadcast RGB” | ENUM | { “Automatic”, “Full”, “Limited 16:235” } | Connector | When this property is set to Limited 16:235 and CTM is set, the hardware will be programmed with the result of the multiplication of CTM by the limited range matrix to ensure the pixels normaly in the range 0..1.0 are remapped to the range 16/255..235/255. |
“audio” | ENUM | { “force-dvi”, “off”, “auto”, “on” } | Connector | TBD | ||
SDVO-TV | “mode” | ENUM | { “NTSC_M”, “NTSC_J”, “NTSC_443”, “PAL_B” } etc. | Connector | TBD | |
“left_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“right_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“top_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“bottom_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“hpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“vpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“contrast” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“saturation” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“hue” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“sharpness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“flicker_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“flicker_filter_adaptive” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“flicker_filter_2d” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“tv_chroma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“tv_luma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“dot_crawl” | RANGE | Min=0, Max=1 | Connector | TBD | ||
SDVO-TV/LVDS | “brightness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | |
CDV gma-500 | Generic | “Broadcast RGB” | ENUM | { “Full”, “Limited 16:235” } | Connector | TBD |
“Broadcast RGB” | ENUM | { “off”, “auto”, “on” } | Connector | TBD | ||
Poulsbo | Generic | “backlight” | RANGE | Min=0, Max=100 | Connector | TBD |
SDVO-TV | “mode” | ENUM | { “NTSC_M”, “NTSC_J”, “NTSC_443”, “PAL_B” } etc. | Connector | TBD | |
“left_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“right_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“top_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“bottom_margin” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“hpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“vpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“contrast” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“saturation” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“hue” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“sharpness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“flicker_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“flicker_filter_adaptive” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“flicker_filter_2d” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“tv_chroma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“tv_luma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ||
“dot_crawl” | RANGE | Min=0, Max=1 | Connector | TBD | ||
SDVO-TV/LVDS | “brightness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | |
armada | CRTC | “CSC_YUV” | ENUM | { “Auto” , “CCIR601”, “CCIR709” } | CRTC | TBD |
“CSC_RGB” | ENUM | { “Auto”, “Computer system”, “Studio” } | CRTC | TBD | ||
Overlay | “colorkey” | RANGE | Min=0, Max=0xffffff | Plane | TBD | |
“colorkey_min” | RANGE | Min=0, Max=0xffffff | Plane | TBD | ||
“colorkey_max” | RANGE | Min=0, Max=0xffffff | Plane | TBD | ||
“colorkey_val” | RANGE | Min=0, Max=0xffffff | Plane | TBD | ||
“colorkey_alpha” | RANGE | Min=0, Max=0xffffff | Plane | TBD | ||
“colorkey_mode” | ENUM | { “disabled”, “Y component”, “U component” , “V component”, “RGB”, “R component”, “G component”, “B component” } | Plane | TBD | ||
“brightness” | RANGE | Min=0, Max=256 + 255 | Plane | TBD | ||
“contrast” | RANGE | Min=0, Max=0x7fff | Plane | TBD | ||
“saturation” | RANGE | Min=0, Max=0x7fff | Plane | TBD | ||
exynos | CRTC | “mode” | ENUM | { “normal”, “blank” } | CRTC | TBD |
Overlay | “zpos” | RANGE | Min=0, Max=MAX_PLANE-1 | Plane | TBD | |
i2c/ch7006_drv | Generic | “scale” | RANGE | Min=0, Max=2 | Connector | TBD |
TV | “mode” | ENUM | { “PAL”, “PAL-M”,”PAL-N”}, ”PAL-Nc” , “PAL-60”, “NTSC-M”, “NTSC-J” } | Connector | TBD | |
nouveau | NV10 Overlay | “colorkey” | RANGE | Min=0, Max=0x01ffffff | Plane | TBD |
“contrast” | RANGE | Min=0, Max=8192-1 | Plane | TBD | ||
“brightness” | RANGE | Min=0, Max=1024 | Plane | TBD | ||
“hue” | RANGE | Min=0, Max=359 | Plane | TBD | ||
“saturation” | RANGE | Min=0, Max=8192-1 | Plane | TBD | ||
“iturbt_709” | RANGE | Min=0, Max=1 | Plane | TBD | ||
Nv04 Overlay | “colorkey” | RANGE | Min=0, Max=0x01ffffff | Plane | TBD | |
“brightness” | RANGE | Min=0, Max=1024 | Plane | TBD | ||
Display | “dithering mode” | ENUM | { “auto”, “off”, “on” } | Connector | TBD | |
“dithering depth” | ENUM | { “auto”, “off”, “on”, “static 2x2”, “dynamic 2x2”, “temporal” } | Connector | TBD | ||
“underscan” | ENUM | { “auto”, “6 bpc”, “8 bpc” } | Connector | TBD | ||
“underscan hborder” | RANGE | Min=0, Max=128 | Connector | TBD | ||
“underscan vborder” | RANGE | Min=0, Max=128 | Connector | TBD | ||
“vibrant hue” | RANGE | Min=0, Max=180 | Connector | TBD | ||
“color vibrance” | RANGE | Min=0, Max=200 | Connector | TBD | ||
omap | Generic | “zorder” | RANGE | Min=0, Max=3 | CRTC, Plane | TBD |
qxl | Generic | “hotplug_mode_update” | RANGE | Min=0, Max=1 | Connector | TBD |
radeon | DVI-I | “coherent” | RANGE | Min=0, Max=1 | Connector | TBD |
DAC enable load detect | “load detection” | RANGE | Min=0, Max=1 | Connector | TBD | |
TV Standard | “tv standard” | ENUM | { “ntsc”, “pal”, “pal-m”, “pal-60”, “ntsc-j” , “scart-pal”, “pal-cn”, “secam” } | Connector | TBD | |
legacy TMDS PLL detect | “tmds_pll” | ENUM | { “driver”, “bios” } | TBD | ||
Underscan | “underscan” | ENUM | { “off”, “on”, “auto” } | Connector | TBD | |
“underscan hborder” | RANGE | Min=0, Max=128 | Connector | TBD | ||
“underscan vborder” | RANGE | Min=0, Max=128 | Connector | TBD | ||
Audio | “audio” | ENUM | { “off”, “on”, “auto” } | Connector | TBD | |
FMT Dithering | “dither” | ENUM | { “off”, “on” } | Connector | TBD | |
rcar-du | Generic | “alpha” | RANGE | Min=0, Max=255 | Plane | TBD |
“colorkey” | RANGE | Min=0, Max=0x01ffffff | Plane | TBD | ||
“zpos” | RANGE | Min=1, Max=7 | Plane | TBD |
Vertical Blanking¶
Vertical blanking plays a major role in graphics rendering. To achieve tear-free display, users must synchronize page flips and/or rendering to vertical blanking. The DRM API offers ioctls to perform page flips synchronized to vertical blanking and wait for vertical blanking.
The DRM core handles most of the vertical blanking management logic, which involves filtering out spurious interrupts, keeping race-free blanking counters, coping with counter wrap-around and resets and keeping use counts. It relies on the driver to generate vertical blanking interrupts and optionally provide a hardware vertical blanking counter. Drivers must implement the following operations.
- int (*enable_vblank) (struct drm_device *dev, int crtc); void (*disable_vblank) (struct drm_device *dev, int crtc); Enable or disable vertical blanking interrupts for the given CRTC.
- u32 (*get_vblank_counter) (struct drm_device *dev, int crtc);
Retrieve the value of the vertical blanking counter for the given
CRTC. If the hardware maintains a vertical blanking counter its value
should be returned. Otherwise drivers can use the
drm_vblank_count()
helper function to handle this operation.
Drivers must initialize the vertical blanking handling core with a call
to drm_vblank_init()
in their load operation.
Vertical blanking interrupts can be enabled by the DRM core or by
drivers themselves (for instance to handle page flipping operations).
The DRM core maintains a vertical blanking use count to ensure that the
interrupts are not disabled while a user still needs them. To increment
the use count, drivers call drm_vblank_get()
. Upon
return vertical blanking interrupts are guaranteed to be enabled.
To decrement the use count drivers call
drm_vblank_put()
. Only when the use count drops to zero
will the DRM core disable the vertical blanking interrupts after a delay
by scheduling a timer. The delay is accessible through the
vblankoffdelay module parameter or the drm_vblank_offdelay
global
variable and expressed in milliseconds. Its default value is 5000 ms.
Zero means never disable, and a negative value means disable
immediately. Drivers may override the behaviour by setting the
struct drm_device
vblank_disable_immediate flag, which when set causes vblank interrupts
to be disabled immediately regardless of the drm_vblank_offdelay
value. The flag should only be set if there’s a properly working
hardware vblank counter present.
When a vertical blanking interrupt occurs drivers only need to call the
drm_handle_vblank()
function to account for the
interrupt.
Resources allocated by drm_vblank_init()
must be freed
with a call to drm_vblank_cleanup()
in the driver unload
operation handler.
Vertical Blanking and Interrupt Handling Functions Reference¶
Parameters
struct drm_crtc * crtc
- which counter to retrieve
Description
This function is similar to drm_crtc_vblank_count but this function interpolates to handle a race with vblank irq’s.
This is mostly useful for hardware that can obtain the scanout position, but doesn’t have a frame counter.
-
void
drm_vblank_cleanup
(struct drm_device * dev)¶ cleanup vblank support
Parameters
struct drm_device * dev
- DRM device
Description
This function cleans up any resources allocated in drm_vblank_init.
-
int
drm_vblank_init
(struct drm_device * dev, unsigned int num_crtcs)¶ initialize vblank support
Parameters
struct drm_device * dev
- DRM device
unsigned int num_crtcs
- number of CRTCs supported by dev
Description
This function initializes vblank support for num_crtcs display pipelines.
Return
Zero on success or a negative error code on failure.
-
int
drm_irq_install
(struct drm_device * dev, int irq)¶ install IRQ handler
Parameters
struct drm_device * dev
- DRM device
int irq
- IRQ number to install the handler for
Description
Initializes the IRQ related data. Installs the handler, calling the driver
irq_preinstall()
and irq_postinstall()
functions before and after the
installation.
This is the simplified helper interface provided for drivers with no special needs. Drivers which need to install interrupt handlers for multiple interrupts must instead set drm_device->irq_enabled to signal the DRM core that vblank interrupts are available.
Return
Zero on success or a negative error code on failure.
-
int
drm_irq_uninstall
(struct drm_device * dev)¶ uninstall the IRQ handler
Parameters
struct drm_device * dev
- DRM device
Description
Calls the driver’s irq_uninstall()
function and unregisters the IRQ handler.
This should only be called by drivers which used drm_irq_install()
to set up
their interrupt handler. Other drivers must only reset
drm_device->irq_enabled to false.
Note that for kernel modesetting drivers it is a bug if this function fails. The sanity checks are only to catch buggy user modesetting drivers which call the same function through an ioctl.
Return
Zero on success or a negative error code on failure.
-
void
drm_calc_timestamping_constants
(struct drm_crtc * crtc, const struct drm_display_mode * mode)¶ calculate vblank timestamp constants
Parameters
struct drm_crtc * crtc
- drm_crtc whose timestamp constants should be updated.
const struct drm_display_mode * mode
- display mode containing the scanout timings
Description
Calculate and store various constants which are later
needed by vblank and swap-completion timestamping, e.g,
by drm_calc_vbltimestamp_from_scanoutpos()
. They are
derived from CRTC’s true scanout timing, so they take
things like panel scaling or other adjustments into account.
-
int
drm_calc_vbltimestamp_from_scanoutpos
(struct drm_device * dev, unsigned int pipe, int * max_error, struct timeval * vblank_time, unsigned flags, const struct drm_display_mode * mode)¶ precise vblank timestamp helper
Parameters
struct drm_device * dev
- DRM device
unsigned int pipe
- index of CRTC whose vblank timestamp to retrieve
int * max_error
- Desired maximum allowable error in timestamps (nanosecs) On return contains true maximum error of timestamp
struct timeval * vblank_time
- Pointer to struct timeval which should receive the timestamp
unsigned flags
- Flags to pass to driver: 0 = Default, DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler
const struct drm_display_mode * mode
- mode which defines the scanout timings
Description
Implements calculation of exact vblank timestamps from given drm_display_mode
timings and current video scanout position of a CRTC. This can be called from
within get_vblank_timestamp()
implementation of a kms driver to implement the
actual timestamping.
Should return timestamps conforming to the OML_sync_control OpenML extension specification. The timestamp corresponds to the end of the vblank interval, aka start of scanout of topmost-leftmost display pixel in the following video frame.
Requires support for optional dev->driver->:c:func:get_scanout_position() in kms driver, plus a bit of setup code to provide a drm_display_mode that corresponds to the true scanout timing.
The current implementation only handles standard video modes. It returns as no operation if a doublescan or interlaced video mode is active. Higher level code is expected to handle this.
Return
Negative value on error, failure or if not supported in current video mode:
-EINVAL |
|
-EAGAIN |
|
-ENOTSUPP - Function not supported in current display mode. -EIO - Failed, e.g., due to failed scanout position query.
Returns or’ed positive status flags on success:
DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval.
-
u32
drm_vblank_count
(struct drm_device * dev, unsigned int pipe)¶ retrieve “cooked” vblank counter value
Parameters
struct drm_device * dev
- DRM device
unsigned int pipe
- index of CRTC for which to retrieve the counter
Description
Fetches the “cooked” vblank count value that represents the number of vblank events since the system was booted, including lost events due to modesetting activity.
This is the legacy version of drm_crtc_vblank_count()
.
Return
The software vblank counter.
Parameters
struct drm_crtc * crtc
- which counter to retrieve
Description
Fetches the “cooked” vblank count value that represents the number of vblank events since the system was booted, including lost events due to modesetting activity.
This is the native KMS version of drm_vblank_count()
.
Return
The software vblank counter.
-
u32
drm_crtc_vblank_count_and_time
(struct drm_crtc * crtc, struct timeval * vblanktime)¶ retrieve “cooked” vblank counter value and the system timestamp corresponding to that vblank counter value
Parameters
struct drm_crtc * crtc
- which counter to retrieve
struct timeval * vblanktime
- Pointer to struct timeval to receive the vblank timestamp.
Description
Fetches the “cooked” vblank count value that represents the number of vblank events since the system was booted, including lost events due to modesetting activity. Returns corresponding system timestamp of the time of the vblank interval that corresponds to the current vblank counter value.
-
void
drm_crtc_arm_vblank_event
(struct drm_crtc * crtc, struct drm_pending_vblank_event * e)¶ arm vblank event after pageflip
Parameters
struct drm_crtc * crtc
- the source CRTC of the vblank event
struct drm_pending_vblank_event * e
- the event to send
Description
A lot of drivers need to generate vblank events for the very next vblank interrupt. For example when the page flip interrupt happens when the page flip gets armed, but not when it actually executes within the next vblank period. This helper function implements exactly the required vblank arming behaviour.
Caller must hold event lock. Caller must also hold a vblank reference for the event e, which will be dropped when the next vblank arrives.
-
void
drm_crtc_send_vblank_event
(struct drm_crtc * crtc, struct drm_pending_vblank_event * e)¶ helper to send vblank event after pageflip
Parameters
struct drm_crtc * crtc
- the source CRTC of the vblank event
struct drm_pending_vblank_event * e
- the event to send
Description
Updates sequence # and timestamp on event, and sends it to userspace. Caller must hold event lock.
Parameters
struct drm_crtc * crtc
- which CRTC to own
Description
Acquire a reference count on vblank events to avoid having them disabled while in use.
Return
Zero on success or a negative error code on failure.
Parameters
struct drm_crtc * crtc
- which counter to give up
Description
Release ownership of a given vblank counter, turning off interrupts if possible. Disable interrupts after drm_vblank_offdelay milliseconds.
-
void
drm_wait_one_vblank
(struct drm_device * dev, unsigned int pipe)¶ wait for one vblank
Parameters
struct drm_device * dev
- DRM device
unsigned int pipe
- CRTC index
Description
This waits for one vblank to pass on pipe, using the irq driver interfaces. It is a failure to call this when the vblank irq for pipe is disabled, e.g. due to lack of driver support or because the crtc is off.
Parameters
struct drm_crtc * crtc
- DRM crtc
Description
This waits for one vblank to pass on crtc, using the irq driver interfaces. It is a failure to call this when the vblank irq for crtc is disabled, e.g. due to lack of driver support or because the crtc is off.
-
void
drm_vblank_off
(struct drm_device * dev, unsigned int pipe)¶ disable vblank events on a CRTC
Parameters
struct drm_device * dev
- DRM device
unsigned int pipe
- CRTC index
Description
Drivers can use this function to shut down the vblank interrupt handling when
disabling a crtc. This function ensures that the latest vblank frame count is
stored so that drm_vblank_on()
can restore it again.
Drivers must use this function when the hardware vblank counter can get reset, e.g. when suspending.
This is the legacy version of drm_crtc_vblank_off()
.
Parameters
struct drm_crtc * crtc
- CRTC in question
Description
Drivers can use this function to shut down the vblank interrupt handling when disabling a crtc. This function ensures that the latest vblank frame count is stored so that drm_vblank_on can restore it again.
Drivers must use this function when the hardware vblank counter can get reset, e.g. when suspending.
This is the native kms version of drm_vblank_off()
.
Parameters
struct drm_crtc * crtc
- CRTC in question
Description
Drivers can use this function to reset the vblank state to off at load time.
Drivers should use this together with the drm_crtc_vblank_off()
and
drm_crtc_vblank_on()
functions. The difference compared to
drm_crtc_vblank_off()
is that this function doesn’t save the vblank counter
and hence doesn’t need to call any driver hooks.
-
void
drm_vblank_on
(struct drm_device * dev, unsigned int pipe)¶ enable vblank events on a CRTC
Parameters
struct drm_device * dev
- DRM device
unsigned int pipe
- CRTC index
Description
This functions restores the vblank interrupt state captured with
drm_vblank_off()
again. Note that calls to drm_vblank_on()
and
drm_vblank_off()
can be unbalanced and so can also be unconditionally called
in driver load code to reflect the current hardware state of the crtc.
This is the legacy version of drm_crtc_vblank_on()
.
Parameters
struct drm_crtc * crtc
- CRTC in question
Description
This functions restores the vblank interrupt state captured with
drm_vblank_off()
again. Note that calls to drm_vblank_on()
and
drm_vblank_off()
can be unbalanced and so can also be unconditionally called
in driver load code to reflect the current hardware state of the crtc.
This is the native kms version of drm_vblank_on()
.
-
void
drm_vblank_pre_modeset
(struct drm_device * dev, unsigned int pipe)¶ account for vblanks across mode sets
Parameters
struct drm_device * dev
- DRM device
unsigned int pipe
- CRTC index
Description
Account for vblank events across mode setting events, which will likely reset the hardware frame counter.
This is done by grabbing a temporary vblank reference to ensure that the vblank interrupt keeps running across the modeset sequence. With this the software-side vblank frame counting will ensure that there are no jumps or discontinuities.
Unfortunately this approach is racy and also doesn’t work when the vblank
interrupt stops running, e.g. across system suspend resume. It is therefore
highly recommended that drivers use the newer drm_vblank_off()
and
drm_vblank_on()
instead. drm_vblank_pre_modeset()
only works correctly when
using “cooked” software vblank frame counters and not relying on any hardware
counters.
Drivers must call drm_vblank_post_modeset()
when re-enabling the same crtc
again.
-
void
drm_vblank_post_modeset
(struct drm_device * dev, unsigned int pipe)¶ undo drm_vblank_pre_modeset changes
Parameters
struct drm_device * dev
- DRM device
unsigned int pipe
- CRTC index
Description
This function again drops the temporary vblank reference acquired in drm_vblank_pre_modeset.
-
bool
drm_handle_vblank
(struct drm_device * dev, unsigned int pipe)¶ handle a vblank event
Parameters
struct drm_device * dev
- DRM device
unsigned int pipe
- index of CRTC where this event occurred
Description
Drivers should call this routine in their vblank interrupt handlers to update the vblank counter and send any signals that may be pending.
This is the legacy version of drm_crtc_handle_vblank()
.
Parameters
struct drm_crtc * crtc
- where this event occurred
Description
Drivers should call this routine in their vblank interrupt handlers to update the vblank counter and send any signals that may be pending.
This is the native KMS version of drm_handle_vblank()
.
Return
True if the event was successfully handled, false on failure.
-
u32
drm_vblank_no_hw_counter
(struct drm_device * dev, unsigned int pipe)¶ “No hw counter” implementation of .:c:func:get_vblank_counter()
Parameters
struct drm_device * dev
- DRM device
unsigned int pipe
- CRTC for which to read the counter
Description
Drivers can plug this into the .:c:func:get_vblank_counter() function if there is no useable hardware frame counter available.
Return
0
-
struct
drm_pending_vblank_event
¶ pending vblank event tracking
Definition
struct drm_pending_vblank_event {
struct drm_pending_event base;
unsigned int pipe;
struct drm_event_vblank event;
};
Members
struct drm_pending_event base
- Base structure for tracking pending DRM events.
unsigned int pipe
drm_crtc_index()
of thedrm_crtc
this event is for.struct drm_event_vblank event
- Actual event which will be sent to userspace.
-
struct
drm_vblank_crtc
¶ vblank tracking for a CRTC
Definition
struct drm_vblank_crtc {
struct drm_device * dev;
wait_queue_head_t queue;
struct timer_list disable_timer;
seqlock_t seqlock;
u32 count;
struct timeval time;
atomic_t refcount;
u32 last;
unsigned int inmodeset;
unsigned int pipe;
int framedur_ns;
int linedur_ns;
bool enabled;
};
Members
struct drm_device * dev
- Pointer to the
drm_device
. wait_queue_head_t queue
- Wait queue for vblank waiters.
struct timer_list disable_timer
- Disable timer for the delayed vblank disabling
hysteresis logic. Vblank disabling is controlled through the
drm_vblank_offdelay module option and the setting of the
max_vblank_count value in the
drm_device
structure. seqlock_t seqlock
- Protect vblank count and time.
u32 count
- Current software vblank counter.
struct timeval time
- Vblank timestamp corresponding to count.
atomic_t refcount
- Number of users/waiters of the vblank interrupt. Only when this refcount reaches 0 can the hardware interrupt be disabled using disable_timer.
u32 last
- Protected by dev->vbl_lock, used for wraparound handling.
unsigned int inmodeset
- Tracks whether the vblank is disabled due to a modeset.
For legacy driver bit 2 additionally tracks whether an additional
temporary vblank reference has been acquired to paper over the
hardware counter resetting/jumping. KMS drivers should instead just
call
drm_crtc_vblank_off()
anddrm_crtc_vblank_on()
, which explicitly save and restore the vblank count. unsigned int pipe
drm_crtc_index()
of thedrm_crtc
corresponding to this structure.int framedur_ns
- Frame/Field duration in ns, used by
drm_calc_vbltimestamp_from_scanoutpos()
and computed bydrm_calc_timestamping_constants()
. int linedur_ns
- Line duration in ns, used by
drm_calc_vbltimestamp_from_scanoutpos()
and computed bydrm_calc_timestamping_constants()
. bool enabled
- Tracks the enabling state of the corresponding
drm_crtc
to avoid double-disabling and hence corrupting saved state. Needed by drivers not using atomic KMS, since those might go through their CRTC disabling functions multiple times.
Description
This structure tracks the vblank state for one CRTC.
Note that for historical reasons - the vblank handling code is still shared
with legacy/non-kms drivers - this is a free-standing structure not directly
connected to struct drm_crtc
. But all public interface functions are taking
a struct drm_crtc
to hide this implementation detail.
-
wait_queue_head_t *
drm_crtc_vblank_waitqueue
(struct drm_crtc * crtc)¶ get vblank waitqueue for the CRTC
Parameters
struct drm_crtc * crtc
- which CRTC’s vblank waitqueue to retrieve
Description
This function returns a pointer to the vblank waitqueue for the CRTC.
Drivers can use this to implement vblank waits using wait_event()
and related
functions.