[PATCH i-g-t v7 14/48] lib/monitor_edids: Add helper functions for using monitor_edid objects

Louis Chauvet
2026-02-23T12:09:05Z

Introduce the functions edid_from_monitor_edid() and
get_edids_for_connector_type(). The former converts a monitor_edid object
to a struct edid, which can then be utilized by igt_kms helpers. The
latter returns a list of monitor_edid objects for a specific connector
with certain characteristics

Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
lib/monitor_edids/dp_edids.h | 3 ++
lib/monitor_edids/hdmi_edids.h | 3 ++
lib/monitor_edids/monitor_edids_helper.c | 80 ++++++++++++++++++++++++++++++++
lib/monitor_edids/monitor_edids_helper.h | 7 ++-
4 files changed, 92 insertions(+), 1 deletion(-)

diff --git a/lib/monitor_edids/dp_edids.h b/lib/monitor_edids/dp_edids.h
index 144907558be1..07793381257e 100644
--- a/lib/monitor_edids/dp_edids.h
+++ b/lib/monitor_edids/dp_edids.h
@@ -194,4 +194,7 @@ monitor_edid DP_EDIDS_NON_4K[] = {

};

+#define DP_EDIDS_4K_COUNT ARRAY_SIZE(DP_EDIDS_4K)
+#define DP_EDIDS_NON_4K_COUNT ARRAY_SIZE(DP_EDIDS_NON_4K)
+
#endif /* TESTS_CHAMELIUM_MONITOR_EDIDS_DP_EDIDS_H_ */
diff --git a/lib/monitor_edids/hdmi_edids.h b/lib/monitor_edids/hdmi_edids.h
index f6cfe82ff6e1..3984241775c3 100644
--- a/lib/monitor_edids/hdmi_edids.h
+++ b/lib/monitor_edids/hdmi_edids.h
@@ -604,4 +604,7 @@ monitor_edid HDMI_EDIDS_NON_4K[] = {
"1620582c2500baac4200009e0000006b" },
};

+#define HDMI_EDIDS_4K_COUNT ARRAY_SIZE(HDMI_EDIDS_4K)
+#define HDMI_EDIDS_NON_4K_COUNT ARRAY_SIZE(HDMI_EDIDS_NON_4K)
+
#endif /* TESTS_CHAMELIUM_MONITOR_EDIDS_HDMI_EDIDS_H_ */
diff --git a/lib/monitor_edids/monitor_edids_helper.c b/lib/monitor_edids/monitor_edids_helper.c
index 1cbf1c22f0bb..6043e7a084b3 100644
--- a/lib/monitor_edids/monitor_edids_helper.c
+++ b/lib/monitor_edids/monitor_edids_helper.c
@@ -15,6 +15,10 @@
#include <assert.h>

#include "igt_core.h"
+#include "igt_edid.h"
+#include "dp_edids.h"
+#include "drmtest.h"
+#include "hdmi_edids.h"

static uint8_t convert_hex_char_to_byte(char c)
{
@@ -90,3 +94,79 @@ void free_chamelium_edid_from_monitor_edid(struct chamelium_edid *edid)
free(edid);
edid = NULL;
}
+
+/**
+ * edid_from_monitor_edid:
+ * @mon_edid: Monitor EDID to convert
+ *
+ * Get a struct edid from a monitor_edid. This returns a pointer to a newly allocated struct edid.
+ * The caller is in charge to free this pointer when required.
+ */
+struct edid *edid_from_monitor_edid(const monitor_edid *mon_edid)
+{
+ uint8_t *raw_edid;
+ size_t edid_size;
+ int i;
+
+ edid_size = strlen(mon_edid->edid) / 2; /* each ascii is a nibble. */
+ raw_edid = malloc(edid_size);
+ igt_assert(raw_edid);
+
+ for (i = 0; i < edid_size; i++) {
+ raw_edid[i] = convert_hex_char_to_byte(mon_edid->edid[i * 2]) << 4 |
+ convert_hex_char_to_byte(mon_edid->edid[i * 2 + 1]);
+ }
+
+ if (edid_get_size((struct edid *)raw_edid) > edid_size) {
+ uint8_t *new_edid;
+
+ igt_debug("The edid size stored in the raw edid is longer than the edid stored in the table.");
+ new_edid = realloc(raw_edid, edid_get_size((struct edid *)raw_edid));
+ igt_assert(new_edid);
+ raw_edid = new_edid;
+ }
+
+ return (struct edid *)raw_edid;
+}
+
+/**
+ * get_edids_for_connector_type:
+ * @type: The connector type to get the EDIDs from
+ * @count: Used to store the number of EDIDs in the returned list
+ * @four_k: Use true to fetch 4k EDIDs, false to fetch non-4k EDIDs
+ *
+ * Get the list of EDIDS for a specific connector type. This returns a pointer to a static list,
+ * so no need to free the pointer.
+ */
+struct monitor_edid *get_edids_for_connector_type(uint32_t type, size_t *count, bool four_k)
+{
+ if (four_k) {
+ switch (type) {
+ case DRM_MODE_CONNECTOR_DisplayPort:
+ *count = DP_EDIDS_4K_COUNT;
+ return DP_EDIDS_4K;
+ case DRM_MODE_CONNECTOR_HDMIA:
+ *count = HDMI_EDIDS_4K_COUNT;
+ return HDMI_EDIDS_4K;
+ default:
+ *count = 0;
+ igt_debug("No 4k EDID for the connector %s\n",
+ kmstest_connector_type_str(type));
+ return NULL;
+ }
+ } else {
+ switch (type) {
+ case DRM_MODE_CONNECTOR_DisplayPort:
+ *count = DP_EDIDS_NON_4K_COUNT;
+ return DP_EDIDS_NON_4K;
+ case DRM_MODE_CONNECTOR_HDMIA:
+ *count = HDMI_EDIDS_NON_4K_COUNT;
+ return HDMI_EDIDS_NON_4K;
+ default:
+ *count = 0;
+ igt_debug("No EDID for the connector %s\n",
+ kmstest_connector_type_str(type));
+ return NULL;
+ }
+ }
+}
diff --git a/lib/monitor_edids/monitor_edids_helper.h b/lib/monitor_edids/monitor_edids_helper.h
index 05679f0897f3..e5069868683d 100644
--- a/lib/monitor_edids/monitor_edids_helper.h
+++ b/lib/monitor_edids/monitor_edids_helper.h
@@ -12,6 +12,8 @@
#define TESTS_CHAMELIUM_MONITOR_EDIDS_MONITOR_EDIDS_HELPER_H_

#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>

#include "igt_chamelium.h"

@@ -30,4 +32,7 @@ get_chameleon_edid_from_monitor_edid(struct chamelium *chamelium,
const monitor_edid *edid);
void free_chamelium_edid_from_monitor_edid(struct chamelium_edid *edid);

-#endif /* TESTS_CHAMELIUM_MONITOR_EDIDS_MONITOR_EDIDS_HELPER_H_ */
\ No newline at end of file
+struct edid *edid_from_monitor_edid(const monitor_edid *monitor_edid);
+struct monitor_edid *get_edids_for_connector_type(uint32_t type, size_t *count, bool four_k);
+
+#endif /* TESTS_CHAMELIUM_MONITOR_EDIDS_MONITOR_EDIDS_HELPER_H_ */

--
2.52.0