public inbox for igt-dev@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Louis Chauvet <louis.chauvet@bootlin.com>
To: "Naladala, Ramanaidu" <Ramanaidu.naladala@intel.com>,
	igt-dev@lists.freedesktop.org
Subject: Re: [PATCH i-g-t v9 20/49] lib/unigraf: Initial Unigraf support
Date: Tue, 24 Mar 2026 10:37:55 +0100	[thread overview]
Message-ID: <3b9d04a6-3cab-4a2a-b48f-fd7d437588cc@bootlin.com> (raw)
In-Reply-To: <066263f2-9ff2-48ef-8193-eed5b320a4dc@intel.com>



On 3/24/26 09:19, Naladala, Ramanaidu wrote:
> Hi Louis Chauvet,
> 
> On 3/16/2026 9:47 PM, Louis Chauvet wrote:
>> This introduce the basic boilerplate to connect to a unigraf device.
>>
>> This integration currently only supports one device opened to simplify
>> its usage and cleanup.
>>
>> The functions unigraf_open_device and unigraf_require_device will 
>> register
>> a handler to do proper cleanup on IGT exit.
>>
>> Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>> ---
>>   lib/meson.build       |  10 +++++
>>   lib/unigraf/unigraf.c | 120 ++++++++++++++++++++++++++++++++++++++++ 
>> ++++++++++
>>   lib/unigraf/unigraf.h |  43 ++++++++++++++++++
>>   meson.build           |  14 ++++++
>>   4 files changed, 187 insertions(+)
>>
>> diff --git a/lib/meson.build b/lib/meson.build
>> index cd03e8f634e4..268f3238cbfa 100644
>> --- a/lib/meson.build
>> +++ b/lib/meson.build
>> @@ -151,6 +151,13 @@ lib_deps = [
>>       zlib
>>   ]
>> +if libtsi.found()
>> +    lib_deps += libtsi
>> +    lib_sources += [
>> +        'unigraf/unigraf.c'
>> +    ]
>> +endif
>> +
>>   if libdrm_nouveau.found()
>>       lib_deps += libdrm_nouveau
>>       lib_sources += [
>> @@ -232,6 +239,9 @@ endif
>>   if chamelium.found()
>>       lib_deps += chamelium
>>       lib_sources += [ 'igt_chamelium.c', 'igt_chamelium_stream.c' ]
>> +endif
>> +
>> +if chamelium.found() or libtsi.found()
>>       lib_sources += 'monitor_edids/monitor_edids_helper.c'
>>   endif
>> diff --git a/lib/unigraf/unigraf.c b/lib/unigraf/unigraf.c
>> new file mode 100644
>> index 000000000000..df18ab178e16
>> --- /dev/null
>> +++ b/lib/unigraf/unigraf.c
>> @@ -0,0 +1,120 @@
>> +// SPDX-License-Identifier: MIT
>> +/*
>> + * Copyright © 2026 Google
>> + *
>> + * Authors:
>> + *   Louis Chauvet <louis.chauvet@bootlin.com>
>> + */
>> +
>> +#include "igt_core.h"
>> +#include <stdint.h>
>> +
>> +#include "unigraf.h"
>> +#include "TSI.h"
>> +#include "TSI_types.h"
>> +
>> +#define unigraf_debug(fmt, ...)    igt_debug("TSI:%p: " fmt, 
>> unigraf_device, ##__VA_ARGS__)
>> +
>> +static TSI_HANDLE unigraf_device;
>> +static char *unigraf_default_edid;
>> +static char *unigraf_connector_name;
>> +
>> +static void unigraf_close_device(void)
>> +{
>> +    if (!unigraf_device)
>> +        return;
>> +
>> +    unigraf_debug("Closing...\n");
>> +    unigraf_assert(TSIX_DEV_CloseDevice(unigraf_device));
>> +    TSI_Clean();
>> +    unigraf_device = NULL;
>> +    free(unigraf_default_edid);
>> +    free(unigraf_connector_name);
>> +}
>> +
>> +/**
>> + * unigraf_exit_handler - Handle the exit signal and clean up unigraf 
>> resources.
>> + * @sig: The signal number received.
>> + *
>> + * This function is called when the program receives an exit signal. 
>> It ensures
>> + * that all unigraf resources are properly cleaned up by calling 
>> unigraf_deinit
>> + * for each open instance.
>> + */
>> +static void unigraf_exit_handler(int sig)
>> +{
>> +    unigraf_close_device();
>> +}
> 
> Unigraf sub test is Success. But the exit handler still asserts due to 
> invalid argument during unigraf_close_device().
> 
> Subtest unigraf-connect-edid: SUCCESS (43.200s)
> (unigraf_connectivity:5625) igt_core-DEBUG: Exiting with status code 0
> (unigraf_connectivity:5625) unigraf/unigraf-DEBUG: TSI:0x6010b136c010: 
> Closing...
> (unigraf_connectivity:5625) unigraf/unigraf-CRITICAL: Test assertion 
> failure function unigraf_close_device, file ../lib/unigraf/unigraf.c:97:
> (unigraf_connectivity:5625) unigraf/unigraf-CRITICAL: Failed assertion: 
> false
> (unigraf_connectivity:5625) unigraf/unigraf-CRITICAL: Last errno: 22, 
> Invalid argument
> (unigraf_connectivity:5625) unigraf/unigraf-CRITICAL: unigraf error: -50 
> (Invalid device handle.)
> Stack trace:
>    #0 ../lib/igt_core.c:2108 __igt_fail_assert()
>    #1 ../lib/unigraf/unigraf.c:97 unigraf_exit_handler()
>    #2 ../lib/igt_core.c:2994 igt_atexit_handler()
>    #3 ./stdlib/exit.c:119 __run_exit_handlers()
>    #4 [exit+0x1e]
>    #5 ../lib/igt_core.c:2419 igt_exit()
>    #6 [main+0x32]
>    #7 ../sysdeps/nptl/libc_start_call_main.h:74 __libc_start_call_main()
>    #8 ../csu/libc-start.c:128 __libc_start_main@@GLIBC_2.34()
>    #9 [_start+0x25]

I saw it yesterday while checking the default_dectect_timeout values, it 
was not the case in the few first iterations of the series. I am 
currently looking to understand what happen.

My current guess is that unigraf_exit_handler is maybe called twice, 
because the function itself works well in my tiny C programs.

>> +
>> +static void unigraf_init(void)
>> +{
>> +    int ret;
>> +
>> +    unigraf_debug("Initialize unigraf...\n");
>> +    ret = TSI_Init(TSI_CURRENT_VERSION);
>> +    unigraf_assert(ret);
>> +    igt_install_exit_handler(unigraf_exit_handler);
>> +}
>> +
>> +/**
>> + * unigraf_device_count() - Return the number of scanned devices
>> + *
>> + * Must be called after a unigraf_rescan_devices().
>> + */
>> +static unsigned int unigraf_device_count(void)
>> +{
>> +    return unigraf_assert(TSIX_DEV_GetDeviceCount());
>> +}
>> +
>> +/**
>> + * unigraf_open_device() - Search and open a device.
>> + * @drm_fd: File descriptor of the currently used drm device
>> + *
>> + * Returns: true if a device was found and initialized, otherwise false.
>> + *
>> + * This function searches for a compatible device and opens it.
>> + */
>> +bool unigraf_open_device(int drm_fd)
>> +{
>> +    TSI_RESULT r;
>> +    int device_count;
>> +    int chosen_device = 0;
>> +    int chosen_role = 0;
>> +    int chosen_input = 0;
>> +
>> +    assert(igt_can_fail());
>> +
>> +    if (unigraf_device)
>> +        return true;
>> +
>> +    unigraf_init();
>> +
>> +    unigraf_assert(TSIX_DEV_RescanDevices(0, 
>> TSI_DEVCAP_VIDEO_CAPTURE, 0));
>> +
>> +    device_count = unigraf_device_count();
>> +    if (device_count < 1) {
>> +        unigraf_debug("No device found.\n");
>> +        return false;
>> +    }
>> +
>> +    unigraf_device = TSIX_DEV_OpenDevice(chosen_device, &r);
>> +    unigraf_assert(r);
>> +    igt_assert(unigraf_device);
>> +    unigraf_debug("Successfully opened the unigraf device %d.\n", 
>> chosen_device);
>> +
>> +    unigraf_assert(TSIX_DEV_SelectRole(unigraf_device, chosen_role));
>> +    unigraf_assert(TSIX_VIN_Select(unigraf_device, chosen_input));
>> +    unigraf_assert(TSIX_VIN_Enable(unigraf_device, chosen_input));
>> +
>> +    return true;
>> +}
>> +
>> +/**
>> + * unigraf_require_device() - Search and open a device.
>> + * @drm_fd: File descriptor of the currently used drm device
>> + *
>> + * This is a shorthand to reduce test boilerplate when a unigraf 
>> device must be present.
>> + */
>> +void unigraf_require_device(int drm_fd)
>> +{
>> +    igt_require(unigraf_open_device(drm_fd));
>> +}
>> diff --git a/lib/unigraf/unigraf.h b/lib/unigraf/unigraf.h
>> new file mode 100644
>> index 000000000000..c08ce62894c5
>> --- /dev/null
>> +++ b/lib/unigraf/unigraf.h
>> @@ -0,0 +1,43 @@
>> +/* SPDX-License-Identifier: MIT */
>> +/*
>> + * Copyright © 2026 Google
>> + *
>> + * Authors:
>> + *   Louis Chauvet <louis.chauvet@bootlin.com>
>> + */
>> +
>> +#ifndef UNIGRAF_H
>> +#define UNIGRAF_H
>> +
>> +#include <stdbool.h>
>> +#include <stdint.h>
>> +
>> +/**
>> + * unigraf_assert: Helper macro to assert a TSI return value and 
>> retrieve a detailed error message.
>> + * @result: libTSI return value to check
>> + *
>> + * This macro checks the return value of a libTSI function call. If 
>> the return value indicates an
>> + * error, it retrieves a detailed error message and asserts with that 
>> message.
>> + * If retrieving the error description fails, it asserts with a 
>> generic error message.
>> + */
>> +#define unigraf_assert(result)                                    \
>> +({                                                \
>> +    char msg[256];                                        \
>> +    TSI_RESULT __r = (result);                                \
>> +    if (__r < TSI_SUCCESS) {                                \
>> +        TSI_RESULT __r2 = TSI_MISC_GetErrorDescription(__r, msg, 
>> sizeof(msg));        \
>> +        if (__r2 < TSI_SUCCESS)                                \
>> +            igt_assert_f(false,                            \
>> +                     "unigraf error: %d (get error description 
>> failed: %d)\n",    \
>> +                     __r, __r2);                        \
>> +        else                                        \
>> +            igt_assert_f(false, "unigraf error: %d (%s)\n", __r, 
>> msg);        \
>> +    }                                            \
>> +    (__r);                                            \
>> +})
>> +
>> +bool unigraf_open_device(int drm_fd);
>> +
>> +void unigraf_require_device(int drm_fd);
>> +
>> +#endif // UNIGRAF_H
>> diff --git a/meson.build b/meson.build
>> index 57849648a377..127abbf62024 100644
>> --- a/meson.build
>> +++ b/meson.build
>> @@ -166,6 +166,12 @@ libpci = dependency('libpci', required : true)
>>   libudev = dependency('libudev', required : true)
>>   glib = dependency('glib-2.0', required : true)
>> +libtsi = cc.find_library('TSI', required : false)
>> +
>> +if libtsi.found()
>> +    config.set('HAVE_UNIGRAF', 1)
>> +endif
>> +
>>   xmlrpc = dependency('xmlrpc', required : false)
>>   xmlrpc_util = dependency('xmlrpc_util', required : false)
>>   xmlrpc_client = dependency('xmlrpc_client', required : false)
>> @@ -290,6 +296,7 @@ amdgpudir = join_paths(libexecdir, 'amdgpu')
>>   msmdir = join_paths(libexecdir, 'msm')
>>   panfrostdir = join_paths(libexecdir, 'panfrost')
>>   panthordir = join_paths(libexecdir, 'panthor')
>> +unigrafdir = join_paths(libexecdir, 'unigraf')
>>   v3ddir = join_paths(libexecdir, 'v3d')
>>   vc4dir = join_paths(libexecdir, 'vc4')
>>   vkmsdir = join_paths(libexecdir, 'vkms')
>> @@ -372,6 +379,12 @@ if get_option('use_rpath')
>>           vmwgfx_rpathdir = join_paths(vmwgfx_rpathdir, '..')
>>       endforeach
>>       vmwgfx_rpathdir = join_paths(vmwgfx_rpathdir, libdir)
>> +
>> +    unigraf_rpathdir = '$ORIGIN'
>> +    foreach p : unigrafdir.split('/')
>> +        unigraf_rpathdir = join_paths(unigraf_rpathdir, '..')
>> +    endforeach
>> +    unigraf_rpathdir = join_paths(unigraf_rpathdir, libdir)
>>   else
>>       bindir_rpathdir = ''
>>       libexecdir_rpathdir = ''
>> @@ -383,6 +396,7 @@ else
>>       vc4_rpathdir = ''
>>       vkms_rpathdir = ''
>>       vmwgfx_rpathdir = ''
>> +    unigraf_rpathdir = ''
>>   endif
>>   build_testplan = get_option('testplan')
>>


  reply	other threads:[~2026-03-24  9:37 UTC|newest]

Thread overview: 83+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-16 16:17 [PATCH i-g-t v9 00/49] Unigraf integration Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 01/49] lib/igt_kms: Add a detect timeout value Louis Chauvet
2026-03-16 18:50   ` Kamil Konieczny
2026-03-16 16:17 ` [PATCH i-g-t v9 02/49] lib/igt_kms: Add helper to wait for a specific status on a connector Louis Chauvet
2026-03-24 10:22   ` Kamil Konieczny
2026-03-16 16:17 ` [PATCH i-g-t v9 03/49] lib/igt_kms: Add function to list connected connectors Louis Chauvet
2026-03-24 10:34   ` Kamil Konieczny
2026-03-24 13:56     ` Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 04/49] lib/igt_kms: Add helper to obtain a connector by its name or MST path Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 05/49] lib/igt_kms: Add helper to wait for new connectors Louis Chauvet
2026-03-17 14:56   ` Kory Maincent
2026-03-23 14:40     ` Louis Chauvet
2026-03-24 10:11   ` Kamil Konieczny
2026-03-16 16:17 ` [PATCH i-g-t v9 06/49] lib/tests: Add tests for array manipulations Louis Chauvet
2026-03-17 15:00   ` Kory Maincent
2026-03-16 16:17 ` [PATCH i-g-t v9 07/49] lib/igt_kms: Add helper to get a pipe from a connector Louis Chauvet
2026-03-24  7:58   ` Jani Nikula
2026-03-24 10:02   ` Kamil Konieczny
2026-03-16 16:17 ` [PATCH i-g-t v9 08/49] lib/igt_kms: Expose dump_connector_attrs Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 09/49] lib/igt_kms: Expose reset_connectors_at_exit Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 10/49] lib/igt_kms: Expose connector_attr_set and igt_connector_attr_set Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 11/49] lib/igt_debugfs: Move debugfs helpers to the proper location Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 12/49] lib/igt_debugfs: Add const when make sense Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 13/49] lib/igt_amd: " Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 14/49] lib/igt_kms: " Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 15/49] lib/monitor_edids: Add helper functions for using monitor_edid objects Louis Chauvet
2026-03-17 15:09   ` Kory Maincent
2026-03-24 10:15   ` Kamil Konieczny
2026-03-24 14:09     ` Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 16/49] lib/monitor_edids: Add helper to get an EDID by its name Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 17/49] lib/monitor_edids: Add helper to print all available EDID names Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 18/49] lib/unigraf: Add used defines for TSI_Types Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 19/49] lib/unigraf: Add TSI.h Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 20/49] lib/unigraf: Initial Unigraf support Louis Chauvet
2026-03-24  8:19   ` Naladala, Ramanaidu
2026-03-24  9:37     ` Louis Chauvet [this message]
2026-03-26  9:59       ` Louis Chauvet
2026-03-24  9:58   ` Kamil Konieczny
2026-03-16 16:17 ` [PATCH i-g-t v9 21/49] lib/igt_kms: Automatically connect unigraf on display require Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 22/49] lib/unigraf: Introduce device configuration Louis Chauvet
2026-03-17 15:16   ` Kory Maincent
2026-03-16 16:17 ` [PATCH i-g-t v9 23/49] lib/unigraf: Introduce role configuration Louis Chauvet
2026-03-17 15:19   ` Kory Maincent
2026-03-16 16:17 ` [PATCH i-g-t v9 24/49] lib/unigraf: Introduce input configuration Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 25/49] lib/unigraf: Add reset function Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 26/49] lib/unigraf: Add unigraf assert and deassert helpers Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 27/49] lib/unigraf: Add plug/unplug helpers Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 28/49] lib/unigraf: Allows sst/mst configuration Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 29/49] lib/unigraf: Add helpers to read and write edid Louis Chauvet
2026-03-17 15:32   ` Kory Maincent
2026-03-23 14:46     ` Louis Chauvet
2026-03-23 16:26   ` Kamil Konieczny
2026-03-23 17:34     ` Louis Chauvet
2026-03-24  9:35       ` Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 30/49] lib/unigraf: Add connector and EDID configuration Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 31/49] tests/unigraf: Add basic unigraf tests Louis Chauvet
2026-03-17 15:46   ` Kory Maincent
2026-03-23 14:49     ` Louis Chauvet
2026-03-24 19:25   ` Naladala, Ramanaidu
2026-03-16 16:17 ` [PATCH i-g-t v9 32/49] lib/unigraf: Add unigraf CRC capture Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 33/49] lib/unigraf: Add configuration for CRC usage Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 34/49] lib/unigraf: add unigraf_get_connector_by_stream Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 35/49] lib/unigraf: Add helper to check timings received by unigraf Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 36/49] lib/igt_pipe_crc: Add unigraf crc calculation Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 37/49] lib/i915/dp: Move DP-related function for i915 to proper folder Louis Chauvet
2026-03-16 16:17 ` [PATCH i-g-t v9 38/49] lib/i915/dp: Rename functions to avoid confusion Louis Chauvet
2026-03-16 16:18 ` [PATCH i-g-t v9 39/49] lib/i915/dp: Add helper to get maximum supported rate Louis Chauvet
2026-03-16 16:18 ` [PATCH i-g-t v9 40/49] lib/i915/dp: Properly check sscanf results Louis Chauvet
2026-03-16 16:18 ` [PATCH i-g-t v9 41/49] lib/i915/dp: Use igt_output_name instead of private field Louis Chauvet
2026-03-16 16:18 ` [PATCH i-g-t v9 42/49] lib/igt_dp: Create generic helpers for DP information Louis Chauvet
2026-03-17 15:55   ` Kory Maincent
2026-03-23 14:52     ` Louis Chauvet
2026-03-16 16:18 ` [PATCH i-g-t v9 43/49] lib/igt_kms: Add asserts to avoid null pointer dereference Louis Chauvet
2026-03-16 16:18 ` [PATCH i-g-t v9 44/49] lib/igt_kms: Add helper to get a CRTC from an output Louis Chauvet
2026-03-17 15:56   ` Kory Maincent
2026-03-16 16:18 ` [PATCH i-g-t v9 45/49] lib/unigraf: Add lane count configuration Louis Chauvet
2026-03-16 16:18 ` [PATCH i-g-t v9 46/49] docs/unigraf: Add unigraf documentation Louis Chauvet
2026-03-17 15:58   ` Kory Maincent
2026-03-24  8:07   ` Naladala, Ramanaidu
2026-03-16 16:18 ` [PATCH i-g-t v9 47/49] lib/unigraf: Add helpers to set maximum link rate Louis Chauvet
2026-03-16 16:18 ` [PATCH i-g-t v9 48/49] lib/unigraf: Add helpers to get the current LT status Louis Chauvet
2026-03-16 16:18 ` [PATCH i-g-t v9 49/49] tests/unigraf/unigraf_lt: Add test for link training Louis Chauvet
2026-03-17 12:02 ` ✗ Fi.CI.BUILD: failure for Unigraf integration (rev8) Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3b9d04a6-3cab-4a2a-b48f-fd7d437588cc@bootlin.com \
    --to=louis.chauvet@bootlin.com \
    --cc=Ramanaidu.naladala@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox