[PATCH i-g-t v3 20/29] lib/unigraf: Add helpers to read and write edid

Louis Chauvet louis.chauvet at bootlin.com
Sat Aug 23 02:11:40 UTC 2025


Read and writing EDID on unigraf can be useful to emulate different
screens, add helpers to read and write them.

There is a limitation on the libTSI.so, it is only possible to read EDID
using buffers of size multiple of 128 bytes, and there is no way to query
the actual EDID size. The current implementation can only read EDID up to
2048 bytes.

Signed-off-by: Louis Chauvet <louis.chauvet at bootlin.com>
---
 lib/unigraf/unigraf.c | 27 +++++++++++++++++++++++++++
 lib/unigraf/unigraf.h | 21 +++++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/lib/unigraf/unigraf.c b/lib/unigraf/unigraf.c
index 6166a6d7e9bb8e348c8f6e6f42ad30b6487bbdd6..6b11fb7744a78d003b064183127c2666d4c36c74 100644
--- a/lib/unigraf/unigraf.c
+++ b/lib/unigraf/unigraf.c
@@ -304,6 +304,33 @@ void unigraf_require_device(int drm_fd)
 	igt_require(unigraf_open_device(drm_fd));
 }
 
+struct edid *unigraf_read_edid(uint32_t stream, uint32_t *edid_size)
+{
+	void *edid;
+
+	igt_assert(unigraf_device);
+	unigraf_debug("Read EDID for stream %d...\n", stream);
+
+	edid = malloc(2048);
+	memset(edid, 0, 2048);
+
+	unigraf_write(TSI_EDID_SELECT_STREAM, &stream, sizeof(stream));
+	*edid_size = unigraf_assert(TSIX_TS_GetConfigItem(unigraf_device,
+							  TSI_EDID_TE_INPUT,
+							  edid, 2048));
+
+	return edid;
+}
+
+void unigraf_write_edid(uint32_t stream, const struct edid *edid, uint32_t edid_size)
+{
+	igt_assert(unigraf_device);
+	unigraf_debug("Write EDID for stream %d...\n", stream);
+
+	unigraf_write(TSI_EDID_SELECT_STREAM, &stream, edid_size);
+	unigraf_write(TSI_EDID_TE_INPUT, edid, 2048);
+}
+
 void unigraf_hpd_assert(void)
 {
 	int d = 1;
diff --git a/lib/unigraf/unigraf.h b/lib/unigraf/unigraf.h
index 4d9eb1b926dfe9ad531e58243f4edf1623a24473..95c86a8cd428725d4e3a28bb91158800c840654c 100644
--- a/lib/unigraf/unigraf.h
+++ b/lib/unigraf/unigraf.h
@@ -47,6 +47,27 @@ bool unigraf_open_device(int drm_fd);
  */
 void unigraf_require_device(int drm_fd);
 
+/**
+ * unigraf_read_edid() - Read the EDID from the specified input
+ * @dev: The device handle
+ * @stream: The stream ID to read the EDID from
+ * @edid_size: Pointer to an integer where the size of the EDID will be stored
+ *
+ * Returns: A pointer to the EDID structure, or NULL if the operation failed. The caller
+ * is responsible to free this pointer.
+ */
+struct edid *unigraf_read_edid(uint32_t stream, uint32_t *edid_size);
+
+/**
+ * unigraf_write_edid() - Write EDID data to the specified stream
+ * @stream: The stream ID to write the EDID to
+ * @edid: Pointer to the EDID structure to write
+ * @edid_size: Size of the EDID data in bytes
+ *
+ * This function writes the provided EDID data to the specified stream.
+ */
+void unigraf_write_edid(uint32_t stream, const struct edid *edid, uint32_t edid_size);
+
 /**
  * unigraf_hpd_deassert() - Deassert Hot Plug Detect signal
  *

-- 
2.50.1



More information about the igt-dev mailing list