diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 15cb181cf..8f2aad88b 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -1720,6 +1721,12 @@ static bool connect_drm_connector(struct wlr_drm_connector *wlr_conn, parse_edid(wlr_conn, edid_len, edid); free(edid); + size_t tile_len = 0; + uint8_t *tile = get_drm_prop_blob(drm->fd, + wlr_conn->id, wlr_conn->props.tile, &tile_len); + parse_tile(wlr_conn, tile_len, tile); + free(tile); + char *subconnector = NULL; if (wlr_conn->props.subconnector) { subconnector = get_drm_prop_enum(drm->fd, diff --git a/backend/drm/properties.c b/backend/drm/properties.c index 314023954..875f9fb4f 100644 --- a/backend/drm/properties.c +++ b/backend/drm/properties.c @@ -27,6 +27,7 @@ static const struct prop_info connector_info[] = { { "EDID", INDEX(edid) }, { "HDR_OUTPUT_METADATA", INDEX(hdr_output_metadata) }, { "PATH", INDEX(path) }, + { "TILE", INDEX(tile) }, { "content type", INDEX(content_type) }, { "link-status", INDEX(link_status) }, { "max bpc", INDEX(max_bpc) }, diff --git a/backend/drm/util.c b/backend/drm/util.c index dd2b37351..ccb562a99 100644 --- a/backend/drm/util.c +++ b/backend/drm/util.c @@ -97,6 +97,47 @@ void parse_edid(struct wlr_drm_connector *conn, size_t len, const uint8_t *data) di_info_destroy(info); } +void parse_tile(struct wlr_drm_connector *conn, size_t len, const uint8_t *data) { + struct wlr_output_group_tile_info *tile_info = &conn->tile_info; + memset(tile_info, 0, sizeof(*tile_info)); + if (len == 0) + return; + + // Reference: + // - include/linux/drm/drm_connector.h tile_blob_ptr + // - drivers/gpu/drm/drm_edid.c drm_parse_tiled_block() + // + // Note: group_id is always > 0 + int ret = sscanf((char*)data, "%d:%d:%d:%d:%d:%d:%d:%d", + &tile_info->group_id, + &tile_info->is_single_monitor, + &tile_info->num_h, + &tile_info->num_v, + &tile_info->h_loc, + &tile_info->v_loc, + &tile_info->h_size, + &tile_info->v_size); + if(ret != 8) { + wlr_log(WLR_ERROR, "Unable to understand tile information for " + "connector %s", conn->name); + return; + } + + wlr_log(WLR_INFO, "Connector '%s' TILE information: " + "group ID %d, single monitor %d, total %d horizontal tiles, " + "total %d vertical tiles, horizontal tile %d, vertical tile " + "%d, width %d, height %d", + conn->name, + tile_info->group_id, + tile_info->is_single_monitor, + tile_info->num_h, + tile_info->num_v, + tile_info->h_loc, + tile_info->v_loc, + tile_info->h_size, + tile_info->v_size); +} + const char *drm_connector_status_str(drmModeConnection status) { switch (status) { case DRM_MODE_CONNECTED: diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index af4231f54..7c829b5ca 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "backend/drm/iface.h" #include "backend/drm/properties.h" @@ -219,6 +220,8 @@ struct wlr_drm_connector { uint32_t hdr_output_metadata; int32_t refresh; + + struct wlr_output_group_tile_info tile_info; }; struct wlr_drm_backend *get_drm_backend_from_backend( diff --git a/include/backend/drm/properties.h b/include/backend/drm/properties.h index c02d655ba..c07d3268b 100644 --- a/include/backend/drm/properties.h +++ b/include/backend/drm/properties.h @@ -22,6 +22,7 @@ struct wlr_drm_connector_props { uint32_t panel_orientation; // not guaranteed to exist uint32_t content_type; // not guaranteed to exist uint32_t max_bpc; // not guaranteed to exist + uint32_t tile; // not guaranteed to exist // atomic-modesetting only diff --git a/include/backend/drm/util.h b/include/backend/drm/util.h index 9ba5f435e..95321cb2e 100644 --- a/include/backend/drm/util.h +++ b/include/backend/drm/util.h @@ -14,6 +14,7 @@ enum wlr_output_mode_aspect_ratio get_picture_aspect_ratio(const drmModeModeInfo const char *get_pnp_manufacturer(const char code[static 3]); // Populates the make/model/phys_{width,height} of output from the edid data void parse_edid(struct wlr_drm_connector *conn, size_t len, const uint8_t *data); +void parse_tile(struct wlr_drm_connector *conn, size_t len, const uint8_t *data); const char *drm_connector_status_str(drmModeConnection status); void generate_cvt_mode(drmModeModeInfo *mode, int hdisplay, int vdisplay, float vrefresh);