[PATCH i-g-t v7 35/48] lib/igt_pipe_crc: Add unigraf crc calculation

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

Unigraf can read crc from the physical output, use this CRC instead of
internal CRC when configured. This allows to also test the hardware signal
generation.

This small addition allows to use the unigraf device for most of the
kms_* tests.

Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
lib/igt_pipe_crc.c | 35 +++++++++++++++++++++++++++++++++++
lib/unigraf/unigraf.c | 22 ++++++++++++++++++++++
2 files changed, 57 insertions(+)

diff --git a/lib/igt_pipe_crc.c b/lib/igt_pipe_crc.c
index 9a79edd51531..ad76e5ca37f7 100644
--- a/lib/igt_pipe_crc.c
+++ b/lib/igt_pipe_crc.c
@@ -3,9 +3,12 @@
* Copyright © 2013 Intel Corporation
*/

+#include "igt_core.h"
+#include "unigraf/unigraf.h"
#include <inttypes.h>
#include <sys/stat.h>
#include <sys/mount.h>
+#include <xf86drmMode.h>
#ifdef __linux__
#include <sys/sysmacros.h>
#endif
@@ -359,6 +362,38 @@ static void read_one_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out)
} while (ret == -EINTR);

fcntl(pipe_crc->crc_fd, F_SETFL, pipe_crc->flags);
+
+#if HAVE_UNIGRAF
+ if (unigraf_open_device(pipe_crc->fd) && unigraf_use_crc()) {
+ int crtc_index;
+ int stream_id;
+ drmModeConnectorPtr connector = unigraf_get_connector(pipe_crc->fd);
+
+ if (!connector)
+ return;
+
+ crtc_index = igt_get_crtc_index_from_connector_id(pipe_crc->fd,
+ connector->connector_id);
+ drmModeFreeConnector(connector);
+
+ if (crtc_index && crtc_index == pipe_crc->crtc_index) {
+ unigraf_read_crc(0, out);
+ return;
+ }
+
+ for (stream_id = 0; stream_id < unigraf_get_mst_stream_count(); stream_id++) {
+ int connector_id = unigraf_get_connector_id_by_stream(pipe_crc->fd,
+ stream_id);
+ crtc_index = igt_get_crtc_index_from_connector_id(pipe_crc->fd,
+ connector_id);
+
+ if (crtc_index && crtc_index == pipe_crc->crtc_index) {
+ unigraf_read_crc(stream_id, out);
+ return;
+ }
+ }
+ }
+#endif
}

/**
diff --git a/lib/unigraf/unigraf.c b/lib/unigraf/unigraf.c
index f30205bbed0b..17b96aa3ac89 100644
--- a/lib/unigraf/unigraf.c
+++ b/lib/unigraf/unigraf.c
@@ -66,6 +66,13 @@ static bool unigraf_crc;
*/
#define UNIGRAF_CONFIG_USE_CRC_NAME "UseCRC"

+/**
+ * UNIGRAF_CONFIG_MST_STREAM_COUNT - Key for the stream count configuration
+ *
+ * Set to 0 to use SST, 1..4 for MST
+ */
+#define UNIGRAF_CONFIG_MST_STREAM_COUNT "MSTStreams"
+
/**
* UNIGRAF_DEFAULT_ROLE_NAME - Default role name to search on the unigraf device
*/
@@ -357,6 +364,7 @@ bool unigraf_open_device(int drm_fd)
int chosen_device;
int chosen_role;
int chosen_input;
+ int unigraf_stream_count;

assert(igt_can_fail());

@@ -413,6 +421,15 @@ bool unigraf_open_device(int drm_fd)
unigraf_debug("CRC usage not configured, using unigraf CRC.\n");
unigraf_crc = true;
}
+
+ cfg_error = NULL;
+ unigraf_stream_count = g_key_file_get_boolean(igt_key_file, UNIGRAF_CONFIG_GROUP,
+ UNIGRAF_CONFIG_MST_STREAM_COUNT,
+ &cfg_error);
+ if (cfg_error) {
+ unigraf_debug("MST usage not configured, using SST.\n");
+ unigraf_stream_count = 0;
+ }
}

unigraf_assert(TSIX_DEV_RescanDevices(0, TSI_DEVCAP_VIDEO_CAPTURE, 0));
@@ -493,6 +510,11 @@ bool unigraf_open_device(int drm_fd)

unigraf_reset();

+ if (!unigraf_stream_count)
+ unigraf_set_sst();
+ else
+ unigraf_set_mst_stream_count(unigraf_stream_count);
+
return unigraf_connector_name != NULL;
}

--
2.52.0