[PATCH i-g-t v7 25/48] lib/unigraf: Add unigraf assert and deassert helpers

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

Unigraf is able to manipulate the HPD line of the connector, add few
helpers to manipulate them.

Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
lib/unigraf/unigraf.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++
lib/unigraf/unigraf.h | 6 ++++++
2 files changed, 59 insertions(+)

diff --git a/lib/unigraf/unigraf.c b/lib/unigraf/unigraf.c
index bd47cebb8480..5812f46fe6ae 100644
--- a/lib/unigraf/unigraf.c
+++ b/lib/unigraf/unigraf.c
@@ -92,6 +92,22 @@ static void unigraf_init(void)
igt_install_exit_handler(unigraf_exit_handler);
}

+/**
+ * unigraf_write_u32 - Write a 32-bit value to a TSI configuration item
+ * @config_id: The configuration item ID to write to
+ * @value: The 32-bit value to write
+ *
+ * This macro writes a 32-bit value to the specified TSI configuration item.
+ * This is a macro to have the proper line information when using unigraf_debug.
+ */
+#define unigraf_write_u32(config_id, value) \
+ ({ \
+ uint32_t v = (value); \
+ igt_assert(unigraf_device); \
+ unigraf_debug("Value write: " #config_id "=%d...\n", v); \
+ unigraf_assert(TSIX_TS_SetConfigItem(unigraf_device, config_id, &v, sizeof(value))); \
+ })
+
/**
* unigraf_device_count() - Return the number of scanned devices
*
@@ -292,3 +308,40 @@ void unigraf_require_device(int drm_fd)
*/
void unigraf_reset(void)
{}
+
+/**
+ * unigraf_hpd_assert() - Assert Hot Plug Detect signal
+ *
+ * This function asserts the HPD signal, simulating a device connection.
+ */
+void unigraf_hpd_assert(void)
+{
+ unigraf_write_u32(TSI_FORCE_HOT_PLUG_STATE_W, 1);
+}
+
+/**
+ * unigraf_hpd_pulse() - Pulse the Hot Plug Detect signal
+ * @duration: The duration in milliseconds for which the HPD signal should be pulsed
+ *
+ * This function pulses the HPD signal for the specified duration.
+ */
+void unigraf_hpd_pulse(int duration)
+{
+ /* In theory this should work:
+ * unigraf_write_u32(TSI_DPRX_HPD_PULSE_W, duration);
+ * But this seems to be broken and this works:
+ */
+ unigraf_hpd_deassert();
+ usleep(duration);
+ unigraf_hpd_assert();
+}
+
+/**
+ * unigraf_hpd_deassert() - Deassert Hot Plug Detect signal
+ *
+ * This function deasserts the HPD signal, simulating a device disconnection.
+ */
+void unigraf_hpd_deassert(void)
+{
+ unigraf_write_u32(TSI_FORCE_HOT_PLUG_STATE_W, 0);
+}
diff --git a/lib/unigraf/unigraf.h b/lib/unigraf/unigraf.h
index 4c2cbd6b1aa5..77fba4e53912 100644
--- a/lib/unigraf/unigraf.h
+++ b/lib/unigraf/unigraf.h
@@ -42,4 +42,10 @@ void unigraf_require_device(int drm_fd);

void unigraf_reset(void);

+void unigraf_hpd_deassert(void);
+
+void unigraf_hpd_pulse(int duration);
+
+void unigraf_hpd_assert(void);
+
#endif // UNIGRAF_H

--
2.52.0