STRUCT DRM_CRTC(9)
π struct drm_crtc(9)
okay so bestie, this page lives in the Kernel API Manual, and honestly? it's a whole vibe. it's the manual page for struct drm_crtc β the central CRTC control structure. no cap, this is the main character of KMS. let's get into it π
β¨ NAME β¨
struct drm_crtc β the central CRTC control structure π
π¦ SYNOPSIS π¦
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_property *scaling_filter_property;
struct drm_property *sharpness_strength_property;
struct drm_crtc_state *state;
struct list_head commit_list;
spinlock_t commit_lock;
struct dentry *debugfs_entry;
struct drm_crtc_crc crc;
unsigned int fence_context;
spinlock_t fence_lock;
unsigned long fence_seqno;
char timeline_name[32];
struct drm_self_refresh_data *self_refresh_data;
};
look at all those fields, she's stacked π«Ά
πΈ Members πΈ
devβ the parent DRM device. the mothership, if you will πportβ the OF node used bydrm_of_find_possible_crtcs.headβ the list of all CRTCs ondev, linked fromdrm_mode_config.crtc_list. it's invariant over the lifetime ofdev, which means it literally does not need locking. slay, stable data structure πnameβ human readable name. can be overwritten by the driver, so drivers get to pick the nickname bestie β¨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 ...). a full modeset also need to grabdrm_mode_config.connection_mutex.- for atomic drivers specifically, this protects
state.
- for atomic drivers specifically, this protects
baseβ the base KMS object for ID tracking etc.primaryβ the Primary plane for this CRTC. note that this is only relevant for legacy IOCTL, it specifies the plane implicitly used by theSETCRTCandPAGE_FLIPIOCTLs. it does not have any significance beyond that. like, that's it, that's her whole job πcursorβ the Cursor plane for this CRTC. note that this is only relevant for legacy IOCTL, it specifies the plane implicitly used by theSETCURSORandSETCURSOR2IOCTLs. it does not have any significance beyond that. same deal πindexβ position inside themode_config.list, can be used as an array index. it is invariant over the lifetime of the CRTC. iconic and unchanging fr frcursor_xβ current x position of the cursor, used for universal cursor planes because theSETCURSORIOCTL only can update the framebuffer without supplying the coordinates.- drivers should not use this directly. atomic drivers should look at
drm_plane_state.crtc_xof the cursor plane instead.
- drivers should not use this directly. atomic drivers should look at
cursor_yβ current y position of the cursor, used for universal cursor planes because theSETCURSORIOCTL only can update the framebuffer without supplying the coordinates.- drivers should not use this directly. atomic drivers should look at
drm_plane_state.crtc_yof the cursor plane instead.
- drivers should not use this directly. atomic drivers should look at
enabledβ is this CRTC enabled? should only be used by legacy drivers. atomic drivers should instead consultdrm_crtc_state.enableanddrm_crtc_state.active. atomic drivers can update this by callingdrm_atomic_helper_update_legacy_modeset_state.modeβ current mode timings. should only be used by legacy drivers, atomic drivers should instead consultdrm_crtc_state.mode. atomic drivers can update this by callingdrm_atomic_helper_update_legacy_modeset_state.hwmodeβ programmed mode in hw, after adjustments for encoders, crtc, panel scaling etc. should only be used by legacy drivers, for high precision vblank timestamps indrm_crtc_vblank_helper_get_vblank_timestamp.- note that atomic drivers should not use this, but instead use
drm_crtc_state.adjusted_mode. and for high-precision timestampsdrm_crtc_vblank_helper_get_vblank_timestampuseddrm_vblank_crtc.hwmode, which is filled out by callingdrm_calc_timestamping_constants.
- note that atomic drivers should not use this, but instead use
xβ x position on screen. should only be used by legacy drivers, atomic drivers should look atdrm_plane_state.crtc_xof the primary plane instead. updated by callingdrm_atomic_helper_update_legacy_modeset_state.yβ y position on screen. should only be used by legacy drivers, atomic drivers should look atdrm_plane_state.crtc_yof the primary plane instead. updated by callingdrm_atomic_helper_update_legacy_modeset_state.funcsβ CRTC control functions β¨gamma_sizeβ size of legacy gamma ramp reported to userspace. set up by callingdrm_mode_crtc_set_gamma_size.- note that atomic drivers need to instead use
drm_crtc_state.gamma_lut. seedrm_crtc_enable_color_mgmt.
- note that atomic drivers need to instead use
gamma_storeβ gamma ramp values used by the legacySETGAMMAandGETGAMMAIOCTls. set up by callingdrm_mode_crtc_set_gamma_size.- note that atomic drivers need to instead use
drm_crtc_state.gamma_lut. seedrm_crtc_enable_color_mgmt.
- note that atomic drivers need to instead use
helper_privateβ mid-layer private data π΅οΈββοΈpropertiesβ property tracking for this CRTC.scaling_filter_propertyβ property to apply a particular filter while scaling.sharpness_strength_propertyβ property to apply the intensity of the sharpness requested.stateβ current atomic state for this CRTC.- this is protected by
mutex. note that nonblocking atomic commits access the current CRTC state without taking locks. either by going through thestruct drm_atomic_commitpointers, seefor_each_oldnew_crtc_in_state,for_each_old_crtc_in_stateandfor_each_new_crtc_in_state. or through careful ordering of atomic commit operations as implemented in the atomic helpers, seestruct drm_crtc_commit. lowkey the most delicate part of this whole page ngl π
- this is protected by
commit_listβ list ofdrm_crtc_commitstructures tracking pending commits. protected bycommit_lock. this list holds its own full reference, as does the ongoing commit.- "Note that the commit for a state change is also tracked in
drm_crtc_state.commit. For accessing the immediately preceding commit in an atomic update it is recommended to just use that pointer in the old CRTC state, since accessing that doesn't need any locking or list-walking.commit_listshould only be used to stall for framebuffer cleanup that's signalled throughdrm_crtc_commit.cleanup_done."
- "Note that the commit for a state change is also tracked in
commit_lockβ spinlock to protectcommit_list.debugfs_entryβ debugfs directory for this CRTC.crcβ configuration settings of CRC capture.fence_contextβ timeline context used for fence operations.fence_lockβ spinlock to protect the fences in thefence_context.fence_seqnoβ seqno variable used as monotonic counter for the fences created on the CRTC's timeline.timeline_nameβ the name of the CRTC's fence timeline.self_refresh_dataβ holds the state for the self refresh helpers.- initialized via
drm_self_refresh_helper_init.
- initialized via
π Description π
each CRTC may have one or more connectors associated with it. this structure allows the CRTC to be controlled. that's the whole description, she's short and she knows it π
π₯ SEE ALSO π₯
kernel file ./include/drm/drm_crtc.h, struct drm_crtc_state(9), struct drm_crtc_funcs(9), struct drm_mode_set(9), drmm_crtc_alloc_with_planes(9), drm_crtc_index(9), drm_crtc_mask(9), drm_crtc_find(9), drm_for_each_crtc(9), drm_for_each_crtc_reverse(9) β go read those too bestie, iykyk π
and that's the page! π this came out of ./include/drm, dated October 2026, and the footer still reads struct drm_crtc(9) β go off, documentation. mwah πβ¨
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms