From 73213872f8646c2c4b15d5b8e41f4f5560f60b14 Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Mon, 31 Mar 2025 10:10:01 +0200 Subject: [PATCH] intel_fb: amend connectors report with display name The EDID reported by connected displays contains data to identify displays based on product strings and PNP IDs. Amended the connectors report node by an optional display_name attribute containing the EDID information if available. Fixes #5499 --- .../pc/src/driver/framebuffer/intel/pc/README | 3 +- .../src/driver/framebuffer/intel/pc/lx_i915.h | 1 + .../src/driver/framebuffer/intel/pc/lx_user.c | 30 +++++++++++++++++++ .../src/driver/framebuffer/intel/pc/main.cc | 7 +++-- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/repos/pc/src/driver/framebuffer/intel/pc/README b/repos/pc/src/driver/framebuffer/intel/pc/README index caeb333bf5..e797a9be89 100644 --- a/repos/pc/src/driver/framebuffer/intel/pc/README +++ b/repos/pc/src/driver/framebuffer/intel/pc/README @@ -36,7 +36,7 @@ The exported report has the following format: ! ! ... ! -! +! ! ! ! @@ -47,6 +47,7 @@ The exported report has the following format: ! ! +If available, the EDID display name is reported via 'display_name'. The physical dimension of the display is reported as 'width_mm' and 'height_mm' in millimeter per connector and if available, also per mode. The values can be used as input to DPI calculations. The currently used mode of the connector diff --git a/repos/pc/src/driver/framebuffer/intel/pc/lx_i915.h b/repos/pc/src/driver/framebuffer/intel/pc/lx_i915.h index e94d9fb90c..7a70f968db 100644 --- a/repos/pc/src/driver/framebuffer/intel/pc/lx_i915.h +++ b/repos/pc/src/driver/framebuffer/intel/pc/lx_i915.h @@ -56,6 +56,7 @@ void lx_emul_i915_report_connector(void * lx_data, void * genode_xml, char const *name, char connected, char valid_fb, unsigned brightness, + char const *display_name, unsigned width_mm, unsigned height_mm); void lx_emul_i915_iterate_modes(void *lx_data, void * genode_data); void lx_emul_i915_report_modes(void * genode_xml, struct genode_mode *); diff --git a/repos/pc/src/driver/framebuffer/intel/pc/lx_user.c b/repos/pc/src/driver/framebuffer/intel/pc/lx_user.c index 76e0ac9611..060d496bdd 100644 --- a/repos/pc/src/driver/framebuffer/intel/pc/lx_user.c +++ b/repos/pc/src/driver/framebuffer/intel/pc/lx_user.c @@ -15,6 +15,7 @@ #include #include +#include #include #include "i915_drv.h" @@ -855,6 +856,29 @@ void lx_user_init(void) } +static void display_name_from_edid(struct drm_property_blob *edid_blob_ptr, + char *name, size_t capacity) +{ + struct edid const *edid = edid_blob_ptr->data; + if (!edid) + return; + + drm_edid_get_monitor_name(edid, name, capacity); + + /* fall back to PNP ID */ + if (name[0] == 0) { + u32 const panel_id = (u32)edid->mfg_id[0] << 24 + | (u32)edid->mfg_id[1] << 16 + | (u32)EDID_PRODUCT_ID(edid); + u16 prod; + char vend[4]; + + drm_edid_decode_panel_id(panel_id, vend, &prod); + snprintf(name, capacity, "%.3s%04X", vend, prod); + } +} + + static void _report_connectors(void * genode_data, bool const discrete) { struct drm_connector_list_iter conn_iter; @@ -868,17 +892,23 @@ static void _report_connectors(void * genode_data, bool const discrete) struct genode_mode conf_mode = {}; + char display_name[16] = { 0 }; + /* read configuration for connector */ lx_emul_i915_connector_config(connector->name, &conf_mode); if ((discrete && conf_mode.mirror) || (!discrete && !conf_mode.mirror)) continue; + if (connector->edid_blob_ptr) + display_name_from_edid(connector->edid_blob_ptr, display_name, sizeof(display_name)); + lx_emul_i915_report_connector(connector, genode_data, connector->name, connector->status != connector_status_disconnected, valid_fb, get_brightness(connector, INVALID_BRIGHTNESS), + *display_name ? display_name : 0, connector->display_info.width_mm, connector->display_info.height_mm); } diff --git a/repos/pc/src/driver/framebuffer/intel/pc/main.cc b/repos/pc/src/driver/framebuffer/intel/pc/main.cc index 731de05576..9866d672f7 100644 --- a/repos/pc/src/driver/framebuffer/intel/pc/main.cc +++ b/repos/pc/src/driver/framebuffer/intel/pc/main.cc @@ -683,8 +683,9 @@ int lx_emul_i915_action_to_process(int const action_failed) void lx_emul_i915_report_connector(void * lx_data, void * genode_xml, char const *name, char const connected, char const /* fb_available */, - unsigned brightness, unsigned width_mm, - unsigned height_mm) + unsigned brightness, + char const *display_name, + unsigned width_mm, unsigned height_mm) { auto &xml = *reinterpret_cast(genode_xml); @@ -692,6 +693,8 @@ void lx_emul_i915_report_connector(void * lx_data, void * genode_xml, { xml.attribute("connected", !!connected); xml.attribute("name", name); + if (display_name) + xml.attribute("display_name", display_name); if (width_mm) xml.attribute("width_mm" , width_mm); if (height_mm)