STRUCT DRM_CONNECTOR(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… struct drm_connector(9) β€” part 1 of 3, bestie πŸŽ€

okay so before we even get into it β€” hi, welcome to the Kernel API Manual, this is struct drm_connector(9), and this page is long, so we're splitting it into three parts. This is part one. Buckle in. πŸ’–


✨ NAME ✨

struct drm_connector β€” the central DRM connector control structure, no cap. Like, this is THE struct. The main character of the connector world. πŸ‘‘


πŸ¦‹ SYNOPSIS πŸ¦‹

here's the full struct, and yes bestie you're gonna want to read every field because i'm not skipping a single one, i would never do that to you:

struct drm_connector {
    struct drm_device *dev;
    struct device *kdev;
    struct device_attribute *attr;
    struct fwnode_handle *fwnode;
    struct list_head head;
    struct list_head global_connector_list_entry;
    struct drm_mode_object base;
    char *name;
    struct mutex mutex;
    unsigned index;
    int connector_type;
    int connector_type_id;
    bool interlace_allowed;
    bool doublescan_allowed;
    bool stereo_allowed;
    bool ycbcr_420_allowed;
    enum drm_connector_registration_state registration_state;
    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 *scaling_mode_property;
    struct drm_property *vrr_capable_property;
    struct drm_property *colorspace_property;
    struct drm_property *color_format_property;
    struct drm_property_blob *path_blob_ptr;
    unsigned int max_bpc;
    struct drm_property *max_bpc_property;
    struct drm_privacy_screen *privacy_screen;
    struct notifier_block privacy_screen_notifier;
    struct drm_property *privacy_screen_sw_state_property;
    struct drm_property *privacy_screen_hw_state_property;
    struct drm_property *broadcast_rgb_property;
  #define DRM_CONNECTOR_POLL_HPD (1 << 0);
  #define DRM_CONNECTOR_POLL_CONNECT (1 << 1);
  #define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2);
    uint8_t polled;
    int dpms;
    const struct drm_connector_helper_funcs *helper_private;
    struct drm_cmdline_mode cmdline_mode;
    enum drm_connector_force force;
    const struct drm_edid *edid_override;
    struct mutex edid_override_mutex;
    u64 epoch_counter;
    u32 possible_encoders;
    struct drm_encoder *encoder;
  #define MAX_ELD_BYTES   128;
    uint8_t eld[MAX_ELD_BYTES];
    struct mutex eld_mutex;
    bool latency_present[2];
    int video_latency[2];
    int audio_latency[2];
    struct i2c_adapter *ddc;
    int null_edid_counter;
    unsigned bad_edid_counter;
    bool edid_corrupt;
    u8 real_edid_checksum;
    struct dentry *debugfs_entry;
    struct drm_connector_state *state;
    struct drm_property_blob *tile_blob_ptr;
    bool has_tile;
    struct drm_tile_group *tile_group;
    bool tile_is_single_monitor;
    uint8_t num_h_tile, num_v_tile;
    uint8_t tile_h_loc, tile_v_loc;
    uint16_t tile_h_size, tile_v_size;
    struct llist_node free_node;
    struct drm_connector_hdmi hdmi;
    struct drm_connector_hdmi_audio hdmi_audio;
    struct drm_connector_cec cec;
};
ok real talk β€” those #define lines are chillin' inside the struct body in this layout, semicolons and all. that's exactly how it's written here, so that's exactly how i'm giving it to you. copy it as-is, do not "fix" it, i'm begging πŸ™ˆ

and yes, there's genuinely a #define MAX_ELD_BYTES 128; in there too β€” 128 bytes of ELD, iconic. ⭐


that's the whole shape of it for now β€” the fields themselves get their whole own moment coming up, so stay tuned for part 2, we are not done here 🫢🌸

✨ MEMBERS ✨

okay bestie, this is the full roster of struct members, and we are not skipping a single one πŸ’… every field, every lock, every NULL, we're getting through all of it together 🫢

  • dev β€” the parent DRM device πŸ‘‘
  • kdev β€” the kernel device used for sysfs attributes
  • attr β€” sysfs attributes
  • fwnode β€” the associated fwnode supplied by platform firmware 🌸. Drivers can set this to associate a fwnode with a connector, and drivers are expected to get a reference on the fwnode when setting this. drm_connector_cleanup will call fwnode_handle_put on this.
  • head β€” the list of all connectors on a dev, linked from drm_mode_config.connector_list. It's protected by drm_mode_config.connector_list_lock, but like… please only use drm_connector_list_iter to walk this list, ok? πŸ™ˆ
  • global_connector_list_entry β€” the connector's entry in the global connector-list, used by drm_connector_find_by_fwnode.
  • base β€” base KMS object
  • name β€” the human readable name, and yes it can be overwritten by the driver ✨
  • mutex β€” lock for general connector state, but currently it only protects registered. Most of the connector state is still protected by drm_mode_config.mutex. iykyk 🫠
  • index β€” the 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 β€” lowkey iconic of it πŸ’–
  • connector_type β€” one of the DRM_MODE_CONNECTOR_<foo> types from drm_mode.h
  • connector_type_id β€” index into the connector type enum
  • interlace_allowed β€” can this connector handle interlaced modes? Only used by drm_helper_probe_single_connector_modes for mode filtering.
  • doublescan_allowed β€” can this connector handle doublescan? Only used by drm_helper_probe_single_connector_modes for mode filtering.
  • stereo_allowed β€” can this connector handle stereo modes? Only used by drm_helper_probe_single_connector_modes for mode filtering.
  • ycbcr_420_allowed β€” this bool says whether the connector is capable of handling YCBCR 420 output. While parsing the EDID blocks it's very helpful to know if the source is capable of handling YCBCR 420 outputs πŸ‘€
  • registration_state β€” is this connector initializing, exposed (registered) with userspace, or unregistered? Protected by mutex.
  • modes β€” the modes available on this connector (from fill_modes + user). Protected by drm_mode_config.mutex.
  • status β€” one of the drm_connector_status enums (connected, not, or unknown). Protected by drm_mode_config.mutex.
  • probed_modes β€” these are the modes added by probing with DDC or the BIOS, before filtering is applied. Used by the probe helpers. Protected by drm_mode_config.mutex.
  • display_info β€” display information gets filled from EDID information when a display is detected. For non hot-pluggable displays such as flat panels in embedded systems, the driver should initialize the drm_display_info.width_mm and drm_display_info.height_mm fields with the physical size of the display. Protected by drm_mode_config.mutex.
  • funcs β€” connector control functions
  • edid_blob_ptr β€” the DRM property containing EDID if present. Protected by drm_mode_config.mutex.
🚨 This must be updated only by calling drm_edid_connector_update or drm_connector_update_edid_property. And This must not be used by drivers directly. no cap, hands off πŸ”₯
  • properties β€” property tracking for this connector
  • scaling_mode_property β€” optional atomic property to control the upscaling. See drm_connector_attach_content_protection_property.
  • vrr_capable_property β€” optional property to help userspace query hardware support for variable refresh rate on a connector πŸŒ€ Drivers can add the property to a connector by calling drm_connector_attach_vrr_capable_property.
This should be updated only by calling drm_connector_set_vrr_capable_property.
  • colorspace_property β€” connector property to set the suitable colorspace supported by the sink 🌈
  • color_format_property β€” connector property to set the suitable color format supported by the sink
  • path_blob_ptr β€” DRM blob property data for the DP MST path property. This should only be updated by calling drm_connector_set_path_property.
  • max_bpc β€” the maximum bits per color channel the connector supports.
  • max_bpc_property β€” default connector property for the max bpc to be driven out of the connector.
  • privacy_screen β€” the drm_privacy_screen for this connector, or NULL.
  • privacy_screen_notifier β€” the privacy-screen notifier_block
  • privacy_screen_sw_state_property β€” optional atomic property for the connector to control the integrated privacy screen πŸ™ˆ
  • privacy_screen_hw_state_property β€” optional atomic property for the connector to report the actual integrated privacy screen state.
  • broadcast_rgb_property β€” connector property to set the Broadcast RGB selection to output with.
  • polled β€” the 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, without causing flickering even when the connector is in use. DACs should rarely do this without a lot of testing. fr fr, test it πŸ’€

Set to 0 for connectors that don't support connection status discovery.

  • dpms β€” the current dpms state. For legacy drivers the drm_connector_funcs.dpms callback must update this. For atomic drivers, this is handled by the core atomic code, and drivers must only take drm_crtc_state.active into account πŸ‘‘
  • helper_private β€” mid-layer private data
  • cmdline_mode β€” the mode line parsed from the kernel cmdline for this connector
  • force β€” a DRM_FORCE_<foo> state for forced mode sets
  • edid_override β€” the override EDID set via debugfs.
⚠️ Do not modify or access outside of the drm_edid_override_* family of functions. seriously, that's the whole rule 🫢
  • edid_override_mutex β€” protects access to edid_override.
  • epoch_counter β€” used to detect changes in the connector. It gets increased when the connector, including its status, is changed ⏱️
  • possible_encoders β€” bit mask of encoders that can drive this connector. drm_encoder_index determines the index into the bitfield and the bits are set with drm_connector_attach_encoder.
  • encoder β€” the currently bound encoder driving this connector, if any. Only really meaningful for non-atomic drivers. Atomic drivers should instead look at drm_connector_state.best_encoder, and in case they need the CRTC driving this output, drm_connector_state.crtc πŸ‘€
  • eld β€” EDID-like data, if present, protected by eld_mutex
  • eld_mutex β€” protection for concurrent access to eld
  • latency_present β€” AV delay info from ELD, if found
  • video_latency β€” video latency info from ELD, if found. [0]: progressive, [1]: interlaced
  • audio_latency β€” audio latency info from ELD, if found. [0]: progressive, [1]: interlaced
  • ddc β€” the associated ddc adapter. A connector usually has its associated ddc adapter. If a driver uses this field, then an appropriate symbolic link is created in the connector sysfs directory to make it easy for the user to tell which i2c adapter is for a particular display πŸ”Œ

The field should be set by calling drm_connector_init_with_ddc.

  • null_edid_counter β€” tracks sinks that give us all zeros for the EDID. Needed to workaround some HW bugs where we get all 0s 😭
  • bad_edid_counter β€” tracks sinks that give us an EDID with invalid checksum
  • edid_corrupt β€” indicates whether the last read EDID was corrupt. Used in Displayport compliance testing - Displayport Link CTS Core 1.2 rev1.1 4.2.2.6
  • real_edid_checksum β€” the real edid checksum for a corrupted edid block. Required in Displayport 1.4 compliance testing rev1.1 4.2.2.6
  • debugfs_entry β€” debugfs directory for this connector
  • state β€” the current atomic state for this connector. This is protected by drm_mode_config.connection_mutex. Note that nonblocking atomic commits access the current connector state without taking locks. Either by going through the struct drm_atomic_commit pointers, see for_each_oldnew_connector_in_state, for_each_old_connector_in_state and for_each_new_connector_in_state. Or through careful ordering of atomic commit operations as implemented in the atomic helpers, see struct drm_crtc_commit 🧚
  • 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 both drm_crtc and drm_plane if needed.

This should only be updated by calling drm_connector_set_tile_property.

  • has_tile β€” is this connector connected to a tiled monitor?
  • tile_group β€” tile group for the connected monitor
  • tile_is_single_monitor β€” whether the tile is one monitor housing
  • num_h_tile β€” number of horizontal tiles in the tile group
  • num_v_tile β€” number of vertical tiles in the tile group
  • tile_h_loc β€” horizontal location of this tile
  • tile_v_loc β€” vertical location of this tile
  • tile_h_size β€” horizontal size of this tile.
  • tile_v_size β€” vertical size of this tile.
  • free_node β€” list used only by drm_connector_list_iter to be able to clean up a connector from any context, in conjunction with drm_mode_config.connector_free_work.
  • hdmi β€” HDMI-related variable and properties.
  • hdmi_audio β€” HDMI codec properties and non-DRM state.
  • cec β€” CEC-related data πŸŽ€

✨ DESCRIPTION ✨

okay so picture this bestie: each connector may be connected to one or more CRTCs 🫢 β€” like, it's not locked into a single one, it can have several. or, plot twist, a connector may be clonable by another connector 🌈 β€” but only if they can share a CRTC. that's the whole rule, no cap. so the vibe check is: can they share? then yes, clone away πŸ’…

and every connector also has a specific position in the broader display πŸŽ€ β€” the docs call this a 'screen', lowercase, in quotes, because honestly it's giving main character but it could span multiple monitors 😭. so yeah, "screen" here is doing a lot of heavy lifting. it's not necessarily one monitor, bestie, it's the whole spread. iconic behaviour fr fr πŸ’–


πŸ’– SEE ALSO πŸ’–

the kernel file to go look at is ./include/drm/drm_connector.h β€” that's your source of truth, go read it, i'll wait 🧚

and then, the extended universe. yes there are this many, and yes every single one of them matters 😭 don't skip the "boring" ones (there are no boring ones, periodt):

  • enum drm_connector_status(9) β€” the status enum, essential πŸ’…
  • enum drm_connector_registration_state(9) β€” registration state, we love a state
  • enum drm_connector_tv_mode(9) β€” tv mode enum, yes that's a thing
  • struct drm_scrambling(9) β€” scrambling, and no we're not talking about eggs πŸ“
  • struct drm_hdmi_dsc_cap(9) β€” the hdmi dsc capability struct
  • struct drm_hdmi_info(9) β€” hdmi info, straight up
  • enum drm_link_status(9) β€” link status, check it
  • enum drm_panel_orientation(9) β€” which way is the panel facing
  • enum drm_hdmi_broadcast_rgb(9) β€” broadcast rgb, yup
  • struct drm_monitor_range_info(9) β€” monitor range info
  • struct drm_luminance_range_info(9) β€” luminance range info, the glow-up info
  • enum drm_privacy_screen_status(9) β€” privacy screen status, very demure
  • enum drm_colorspace(9) β€” colorspace!! aesthetic!!
  • enum drm_output_color_format(9) β€” output color format, slay
  • enum drm_connector_color_format(9) β€” connector color format, adjacent slay
  • enum drm_bus_flags(9) β€” bus flags, little flags
  • struct drm_amd_vsdb_info(9) β€” amd vsdb info, niche and we respect it
  • struct drm_display_info(9) β€” the display info struct, big one
  • struct drm_connector_tv_margins(9) β€” tv margins, give it some space 🫢
  • struct drm_tv_connector_state(9) β€” tv connector state
  • struct drm_connector_hdmi_infoframe(9) β€” hdmi infoframe struct
  • struct drm_connector_state(9) β€” connector state, the moment
  • struct drm_connector_cec_funcs(9) β€” cec funcs
  • struct drm_connector_infoframe_funcs(9) β€” infoframe funcs
  • struct drm_connector_hdmi_funcs(9) β€” hdmi funcs
  • struct drm_connector_funcs(9) β€” the connector funcs themselves πŸ‘‘
  • struct drm_cmdline_mode(9) β€” cmdline mode, command line era
  • struct drm_connector_hdmi_audio(9) β€” hdmi audio struct, sound on πŸ”Š
  • struct drm_connector_cec(9) β€” cec struct
  • drm_connector_lookup(9) β€” go find a connector
  • drm_connector_get(9) β€” grab a reference, don't be weird about it
  • drm_connector_put(9) β€” and put it back, balanced queen βš–οΈ
  • drm_connector_is_unregistered(9) β€” is it unregistered? ask
  • struct drm_tile_group(9) β€” tile group, tiled agenda
  • struct drm_connector_list_iter(9) β€” the list iterator, looping icon
  • drm_for_each_connector_iter(9) β€” the for-each macro, go iterate bestie
  • drm_connector_for_each_possible_encoder(9) β€” and iterate the possible encoders too, why not ✨

that's the whole page, bestie, you made it to the end πŸŽ€ this was struct drm_connector(9) from the ./include/drm corner of the kernel, dated October 2026 β€” go forth and connect some connectors, you absolute icon πŸ’œπŸ’…πŸ¦‹

πŸ“¦ where this page comes from