* [PATCH i-g-t RFC 01/13] tests/chamelium: Extract chamelium v2 tests into its own directory
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
@ 2024-06-05 14:30 ` Louis Chauvet
2024-06-05 14:30 ` [PATCH i-g-t RFC 02/13] lib/chamelium: Extract chamelium v2 wrapper " Louis Chauvet
` (14 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Louis Chauvet @ 2024-06-05 14:30 UTC (permalink / raw)
To: igt-dev, ihf, markyacoub, thomas.petazzoni, Louis Chauvet
In preparation for the Chamelium v3, the chamelium v2 tests are
moved in its own directory.
The two Chamelium versions have different sets of functionality (audio,
MST, CRC computation, etc.). As most of the tests will need to be
rewritten to works with chamelium v3, to avoid breaking them, it is
simpler to create new ones for v3.
The current identified complexities that necessitate a thorough rework of
the existing v2 tests are:
- Not all ports are discoverable in v3 (MST ports are not physical
ports, but they can have EDID, be plugged, etc.), and they can change
over time.
- The v3 is unable to perform CRC computation
- Not all ports can be plugged at once, which is a feature used by the
existing v2 wrapper to set up the Chamelium.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
tests/chamelium/{ => v2}/kms_chamelium_audio.c | 0
tests/chamelium/{ => v2}/kms_chamelium_color.c | 0
tests/chamelium/{ => v2}/kms_chamelium_edid.c | 0
tests/chamelium/{ => v2}/kms_chamelium_frames.c | 0
tests/chamelium/{ => v2}/kms_chamelium_helper.c | 0
tests/chamelium/{ => v2}/kms_chamelium_helper.h | 0
tests/chamelium/{ => v2}/kms_chamelium_hpd.c | 0
tests/meson.build | 10 +++++-----
8 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/tests/chamelium/kms_chamelium_audio.c b/tests/chamelium/v2/kms_chamelium_audio.c
similarity index 100%
rename from tests/chamelium/kms_chamelium_audio.c
rename to tests/chamelium/v2/kms_chamelium_audio.c
diff --git a/tests/chamelium/kms_chamelium_color.c b/tests/chamelium/v2/kms_chamelium_color.c
similarity index 100%
rename from tests/chamelium/kms_chamelium_color.c
rename to tests/chamelium/v2/kms_chamelium_color.c
diff --git a/tests/chamelium/kms_chamelium_edid.c b/tests/chamelium/v2/kms_chamelium_edid.c
similarity index 100%
rename from tests/chamelium/kms_chamelium_edid.c
rename to tests/chamelium/v2/kms_chamelium_edid.c
diff --git a/tests/chamelium/kms_chamelium_frames.c b/tests/chamelium/v2/kms_chamelium_frames.c
similarity index 100%
rename from tests/chamelium/kms_chamelium_frames.c
rename to tests/chamelium/v2/kms_chamelium_frames.c
diff --git a/tests/chamelium/kms_chamelium_helper.c b/tests/chamelium/v2/kms_chamelium_helper.c
similarity index 100%
rename from tests/chamelium/kms_chamelium_helper.c
rename to tests/chamelium/v2/kms_chamelium_helper.c
diff --git a/tests/chamelium/kms_chamelium_helper.h b/tests/chamelium/v2/kms_chamelium_helper.h
similarity index 100%
rename from tests/chamelium/kms_chamelium_helper.h
rename to tests/chamelium/v2/kms_chamelium_helper.h
diff --git a/tests/chamelium/kms_chamelium_hpd.c b/tests/chamelium/v2/kms_chamelium_hpd.c
similarity index 100%
rename from tests/chamelium/kms_chamelium_hpd.c
rename to tests/chamelium/v2/kms_chamelium_hpd.c
diff --git a/tests/meson.build b/tests/meson.build
index 758ae090c927..6063a02962a2 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -352,11 +352,11 @@ extra_sources = {
'dumb_buffer': ['dumb_buffer.c' ],
'testdisplay': [ 'testdisplay_hotplug.c' ],
'kms_color': [ 'kms_color_helper.c' ],
- 'kms_chamelium_audio': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ],
+ 'kms_chamelium_audio': [ join_paths ('chamelium', 'v2', 'kms_chamelium_helper.c') ],
'kms_chamelium_color': [ 'kms_color_helper.c' ],
- 'kms_chamelium_edid': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ],
- 'kms_chamelium_frames': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ],
- 'kms_chamelium_hpd': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ],
+ 'kms_chamelium_edid': [ join_paths ('chamelium', 'v2', 'kms_chamelium_helper.c') ],
+ 'kms_chamelium_frames': [ join_paths ('chamelium', 'v2', 'kms_chamelium_helper.c') ],
+ 'kms_chamelium_hpd': [ join_paths ('chamelium', 'v2', 'kms_chamelium_helper.c') ],
'kms_dsc': [ join_paths ('intel', 'kms_dsc_helper.c') ],
'kms_psr2_sf': [ join_paths ('intel', 'kms_dsc_helper.c') ],
}
@@ -440,7 +440,7 @@ endforeach
if chamelium.found()
foreach prog : chamelium_progs
testexe = executable(prog,
- [join_paths('chamelium', prog + '.c')] + extra_sources.get(prog, []),
+ [join_paths('chamelium', 'v2', prog + '.c')] + extra_sources.get(prog, []),
dependencies : test_deps + extra_dependencies.get(prog, []),
install_dir : libexecdir,
install_rpath : libexecdir_rpathdir,
--
2.43.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH i-g-t RFC 02/13] lib/chamelium: Extract chamelium v2 wrapper into its own directory
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
2024-06-05 14:30 ` [PATCH i-g-t RFC 01/13] tests/chamelium: Extract chamelium v2 tests into its own directory Louis Chauvet
@ 2024-06-05 14:30 ` Louis Chauvet
2024-06-05 14:30 ` [PATCH i-g-t RFC 03/13] lib/chamelium: Change build options to split chamelium v2 and v3 Louis Chauvet
` (13 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Louis Chauvet @ 2024-06-05 14:30 UTC (permalink / raw)
To: igt-dev, ihf, markyacoub, thomas.petazzoni, Louis Chauvet
In preparation for the Chamelium v3, the support for Chamelium v2 is being
extracted into its own directory.
The two Chamelium versions have different sets of functionality (audio,
MST, CRC computation, etc.). As the current wrapper is already complex,
extracting the v2 part into its own directory allows for the v3 wrapper to
be written without breaking any existing tests or complicating the
existing code.
The current identified complexities that necessitate a thorough rework of
the existing v2 wrapper are:
- Not all ports are discoverable in v3 (MST ports are not physical
ports, but they can have EDID, be plugged, etc.), and they can change
over time.
- The v3 is unable to perform CRC computation, so many tests must be
rewritten or adapted to work.
- Not all ports can be plugged at once, which is a feature used by the
existing v2 wrapper to set up the Chamelium.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
lib/{ => chamelium/v2}/igt_chamelium.c | 2 +-
lib/{ => chamelium/v2}/igt_chamelium.h | 0
lib/{ => chamelium/v2}/igt_chamelium_stream.c | 2 +-
lib/{ => chamelium/v2}/igt_chamelium_stream.h | 0
lib/igt.h | 4 ++--
lib/igt_kms.c | 2 +-
lib/meson.build | 5 ++++-
lib/monitor_edids/monitor_edids_helper.h | 2 +-
tests/chamelium/v2/kms_chamelium_edid.c | 2 +-
tests/kms_feature_discovery.c | 2 +-
10 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/lib/igt_chamelium.c b/lib/chamelium/v2/igt_chamelium.c
similarity index 99%
rename from lib/igt_chamelium.c
rename to lib/chamelium/v2/igt_chamelium.c
index 016d5356630c..f38b30463e21 100644
--- a/lib/igt_chamelium.c
+++ b/lib/chamelium/v2/igt_chamelium.c
@@ -37,7 +37,7 @@
#include <pixman.h>
#include <cairo.h>
-#include "igt_chamelium.h"
+#include "chamelium/v2/igt_chamelium.h"
#include "igt_core.h"
#include "igt_aux.h"
#include "igt_edid.h"
diff --git a/lib/igt_chamelium.h b/lib/chamelium/v2/igt_chamelium.h
similarity index 100%
rename from lib/igt_chamelium.h
rename to lib/chamelium/v2/igt_chamelium.h
diff --git a/lib/igt_chamelium_stream.c b/lib/chamelium/v2/igt_chamelium_stream.c
similarity index 99%
rename from lib/igt_chamelium_stream.c
rename to lib/chamelium/v2/igt_chamelium_stream.c
index a8cd19e51b0b..8d96e654947d 100644
--- a/lib/igt_chamelium_stream.c
+++ b/lib/chamelium/v2/igt_chamelium_stream.c
@@ -33,7 +33,7 @@
#include <sys/types.h>
#include <sys/socket.h>
-#include "igt_chamelium_stream.h"
+#include "chamelium/v2/igt_chamelium_stream.h"
#include "igt_core.h"
#include "igt_rc.h"
diff --git a/lib/igt_chamelium_stream.h b/lib/chamelium/v2/igt_chamelium_stream.h
similarity index 100%
rename from lib/igt_chamelium_stream.h
rename to lib/chamelium/v2/igt_chamelium_stream.h
diff --git a/lib/igt.h b/lib/igt.h
index 7af3d10cbcd3..cf91e92eb2d4 100644
--- a/lib/igt.h
+++ b/lib/igt.h
@@ -45,8 +45,8 @@
#ifdef HAVE_CHAMELIUM
#include "igt_alsa.h"
#include "igt_audio.h"
-#include "igt_chamelium.h"
-#include "igt_chamelium_stream.h"
+#include "chamelium/v2/igt_chamelium.h"
+#include "chamelium/v2/igt_chamelium_stream.h"
#endif
#include "instdone.h"
#include "intel_batchbuffer.h"
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index af63d13b1da3..4a61c3560999 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -60,7 +60,7 @@
#include "igt_sysfs.h"
#include "sw_sync.h"
#ifdef HAVE_CHAMELIUM
-#include "igt_chamelium.h"
+#include "chamelium/v2/igt_chamelium.h"
#endif
/**
diff --git a/lib/meson.build b/lib/meson.build
index e2f740c116f8..74080e339c19 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -189,7 +189,10 @@ endif
if chamelium.found()
lib_deps += chamelium
- lib_sources += [ 'igt_chamelium.c', 'igt_chamelium_stream.c' ]
+ lib_sources += [
+ 'chamelium/v2/igt_chamelium.c',
+ 'chamelium/v2/igt_chamelium_stream.c'
+ ]
lib_sources += 'monitor_edids/monitor_edids_helper.c'
endif
diff --git a/lib/monitor_edids/monitor_edids_helper.h b/lib/monitor_edids/monitor_edids_helper.h
index 05679f0897f3..63a183409293 100644
--- a/lib/monitor_edids/monitor_edids_helper.h
+++ b/lib/monitor_edids/monitor_edids_helper.h
@@ -13,7 +13,7 @@
#include <stdint.h>
-#include "igt_chamelium.h"
+#include "chamelium/v2/igt_chamelium.h"
/* Max Length can be increased as needed, when new EDIDs are added. */
#define EDID_NAME_MAX_LEN 28
diff --git a/tests/chamelium/v2/kms_chamelium_edid.c b/tests/chamelium/v2/kms_chamelium_edid.c
index 8438f5f156b7..772654f37de8 100644
--- a/tests/chamelium/v2/kms_chamelium_edid.c
+++ b/tests/chamelium/v2/kms_chamelium_edid.c
@@ -41,7 +41,7 @@
#include "config.h"
#include "igt.h"
-#include "igt_chamelium.h"
+#include "chamelium/v2/igt_chamelium.h"
#include "igt_edid.h"
#include "igt_eld.h"
#include "igt_vc4.h"
diff --git a/tests/kms_feature_discovery.c b/tests/kms_feature_discovery.c
index 5bca9ad76684..edb0186361a8 100644
--- a/tests/kms_feature_discovery.c
+++ b/tests/kms_feature_discovery.c
@@ -36,7 +36,7 @@
#include "igt.h"
#ifdef HAVE_CHAMELIUM
-#include "igt_chamelium.h"
+#include "chamelium/v2/igt_chamelium.h"
#endif
#include "igt_kms.h"
#include "igt_psr.h"
--
2.43.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH i-g-t RFC 03/13] lib/chamelium: Change build options to split chamelium v2 and v3
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
2024-06-05 14:30 ` [PATCH i-g-t RFC 01/13] tests/chamelium: Extract chamelium v2 tests into its own directory Louis Chauvet
2024-06-05 14:30 ` [PATCH i-g-t RFC 02/13] lib/chamelium: Extract chamelium v2 wrapper " Louis Chauvet
@ 2024-06-05 14:30 ` Louis Chauvet
2024-06-05 14:30 ` [PATCH i-g-t RFC 04/13] lib/chamelium: Introduce the foundation for the chamelium v3 library Louis Chauvet
` (12 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Louis Chauvet @ 2024-06-05 14:30 UTC (permalink / raw)
To: igt-dev, ihf, markyacoub, thomas.petazzoni, Louis Chauvet
Rename the Chamelium option to "chamelium_v2" to prepare for the
introduction of the v3 wrapper. Additionally, rename the "HAVE_CHAMELIUM"
define to avoid conflicts when the v3 is introduced.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
docs/testplan/meson.build | 4 ++--
lib/igt.h | 2 +-
lib/igt_kms.c | 3 ++-
lib/meson.build | 4 ++--
lib/tests/meson.build | 4 ++--
meson.build | 30 +++++++++++++++---------------
meson_options.txt | 4 ++--
tests/kms_color_helper.h | 2 +-
tests/kms_feature_discovery.c | 4 ++--
tests/kms_tiled_display.c | 6 +++---
tests/meson.build | 8 ++++----
11 files changed, 36 insertions(+), 35 deletions(-)
diff --git a/docs/testplan/meson.build b/docs/testplan/meson.build
index 5560347f1337..f60c82ad139c 100644
--- a/docs/testplan/meson.build
+++ b/docs/testplan/meson.build
@@ -21,8 +21,8 @@ if build_tests
build_info += 'Will Check if documentation is in sync with testlist'
check_testlist = [ '--check-testlist', '--igt-build-path', build_root ]
- if not chamelium.found()
- warning('WARNING: Will not check if documentation is in sync for KMS as chamelium is disabled')
+ if not chamelium_v2.found()
+ warning('WARNING: Will not check if documentation is in sync for KMS as chamelium v2 is disabled')
else
kms_check_testlist = check_testlist
endif
diff --git a/lib/igt.h b/lib/igt.h
index cf91e92eb2d4..390e59cd9b92 100644
--- a/lib/igt.h
+++ b/lib/igt.h
@@ -42,7 +42,7 @@
#include "igt_sizes.h"
#include "igt_stats.h"
#include "igt_dsc.h"
-#ifdef HAVE_CHAMELIUM
+#ifdef HAVE_CHAMELIUM_V2
#include "igt_alsa.h"
#include "igt_audio.h"
#include "chamelium/v2/igt_chamelium.h"
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 4a61c3560999..fbb9c545e1b4 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -59,7 +59,7 @@
#include "igt_device.h"
#include "igt_sysfs.h"
#include "sw_sync.h"
-#ifdef HAVE_CHAMELIUM
+#ifdef HAVE_CHAMELIUM_V2
#include "chamelium/v2/igt_chamelium.h"
#endif
@@ -2883,6 +2883,7 @@ void igt_display_require(igt_display_t *display, int drm_fd)
goto out;
#ifdef HAVE_CHAMELIUM
+#ifdef HAVE_CHAMELIUM_V2
{
struct chamelium *chamelium;
diff --git a/lib/meson.build b/lib/meson.build
index 74080e339c19..accf9ff41222 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -187,8 +187,8 @@ if alsa.found()
lib_sources += 'igt_alsa.c'
endif
-if chamelium.found()
- lib_deps += chamelium
+if chamelium_v2.found()
+ lib_deps += chamelium_v2
lib_sources += [
'chamelium/v2/igt_chamelium.c',
'chamelium/v2/igt_chamelium_stream.c'
diff --git a/lib/tests/meson.build b/lib/tests/meson.build
index fa3d81de6cef..f98c948bc827 100644
--- a/lib/tests/meson.build
+++ b/lib/tests/meson.build
@@ -34,8 +34,8 @@ lib_fail_tests = [
lib_tests_deps = igt_deps
-if chamelium.found()
- lib_deps += chamelium
+if chamelium_v2.found()
+ lib_deps += chamelium_v2
lib_tests += 'igt_audio'
endif
diff --git a/meson.build b/meson.build
index ab44aadb1fdf..a6c8ddf6a128 100644
--- a/meson.build
+++ b/meson.build
@@ -86,7 +86,7 @@ foreach cc_arg : cc_args
endif
endforeach
-build_chamelium = get_option('chamelium')
+build_chamelium_v2 = get_option('chamelium_v2')
build_docs = get_option('docs')
build_tests = not get_option('tests').disabled()
build_xe = not get_option('xe_driver').disabled()
@@ -172,28 +172,28 @@ if not xmlrpc.found() and xmlrpc_cmd.found()
endif
endif
-if build_chamelium.enabled() and not (xmlrpc.found() and xmlrpc_util.found() and xmlrpc_client.found())
+if build_chamelium_v2.enabled() and not (xmlrpc.found() and xmlrpc_util.found() and xmlrpc_client.found())
error('Chamelium build forced and required dependency xmlrpc not found')
endif
-gsl = dependency('gsl', required : build_chamelium)
-alsa = dependency('alsa', required : build_chamelium)
-libcurl = dependency('libcurl', required : build_chamelium)
+gsl = dependency('gsl', required : build_chamelium_v2)
+alsa = dependency('alsa', required : build_chamelium_v2)
+libcurl = dependency('libcurl', required : build_chamelium_v2)
if xmlrpc.found() and xmlrpc_util.found() and xmlrpc_client.found() and gsl.found() and alsa.found() and libcurl.found()
- config.set('HAVE_CHAMELIUM', 1)
- chamelium = declare_dependency(dependencies : [
- xmlrpc,
- xmlrpc_util,
- xmlrpc_client,
- gsl,
- alsa,
- ])
+ config.set('HAVE_CHAMELIUM_V2', 1)
+ chamelium_v2 = declare_dependency(dependencies : [
+ xmlrpc,
+ xmlrpc_util,
+ xmlrpc_client,
+ gsl,
+ alsa,
+ ])
else
- chamelium = disabler()
+ chamelium_v2 = disabler()
endif
-build_info += 'Build Chamelium test: @0@'.format(chamelium.found())
+build_info += 'Build Chamelium v2 test: @0@'.format(chamelium_v2.found())
pthreads = dependency('threads')
math = cc.find_library('m')
diff --git a/meson_options.txt b/meson_options.txt
index 6a9493ea6ecd..fea91fb129aa 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -8,9 +8,9 @@ option('overlay_backends',
choices : [ 'auto', 'x', 'xv' ],
description : 'Overlay backends to enable')
-option('chamelium',
+option('chamelium_v2',
type : 'feature',
- description : 'Build Chamelium test')
+ description : 'Build Chamelium v2 test')
option('valgrind',
type : 'feature',
diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
index 23463b944b6f..910de27bf61f 100644
--- a/tests/kms_color_helper.h
+++ b/tests/kms_color_helper.h
@@ -57,7 +57,7 @@ typedef struct {
uint32_t color_depth;
uint64_t degamma_lut_size;
uint64_t gamma_lut_size;
- #ifdef HAVE_CHAMELIUM
+ #ifdef HAVE_CHAMELIUM_V2
struct chamelium *chamelium;
struct chamelium_port **ports;
int port_count;
diff --git a/tests/kms_feature_discovery.c b/tests/kms_feature_discovery.c
index edb0186361a8..76e958c84d51 100644
--- a/tests/kms_feature_discovery.c
+++ b/tests/kms_feature_discovery.c
@@ -35,7 +35,7 @@
*/
#include "igt.h"
-#ifdef HAVE_CHAMELIUM
+#ifdef HAVE_CHAMELIUM_V2
#include "chamelium/v2/igt_chamelium.h"
#endif
#include "igt_kms.h"
@@ -140,7 +140,7 @@ igt_main {
}
}
-#ifdef HAVE_CHAMELIUM
+#ifdef HAVE_CHAMELIUM_V2
igt_describe("Make sure that Chamelium is configured and reachable.");
igt_subtest("chamelium") {
struct chamelium *chamelium =
diff --git a/tests/kms_tiled_display.c b/tests/kms_tiled_display.c
index 3ffd6a9a4a2d..c541115c2c74 100644
--- a/tests/kms_tiled_display.c
+++ b/tests/kms_tiled_display.c
@@ -83,7 +83,7 @@ typedef struct {
struct timeval first_ts;
int linetime_us;
-#ifdef HAVE_CHAMELIUM
+#ifdef HAVE_CHAMELIUM_V2
struct chamelium *chamelium;
struct chamelium_port **ports;
int port_count;
@@ -408,7 +408,7 @@ static bool got_all_page_flips(data_t *data)
return true;
}
-#ifdef HAVE_CHAMELIUM
+#ifdef HAVE_CHAMELIUM_V2
static void test_with_chamelium(data_t *data)
{
int i, count = 0;
@@ -624,7 +624,7 @@ igt_main
test_cleanup(&data);
}
-#ifdef HAVE_CHAMELIUM
+#ifdef HAVE_CHAMELIUM_V2
igt_describe("Make sure the Tiled CRTCs are synchronized and we get "
"page flips for all tiled CRTCs in one vblank (executes on chamelium).");
igt_subtest_f("basic-test-pattern-with-chamelium") {
diff --git a/tests/meson.build b/tests/meson.build
index 6063a02962a2..0b0a913bd878 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -326,7 +326,7 @@ msm_progs = [
'msm_submitoverhead',
]
-chamelium_progs = [
+chamelium_v2_progs = [
'kms_chamelium_audio',
'kms_chamelium_color',
'kms_chamelium_edid',
@@ -437,8 +437,8 @@ foreach prog : msm_progs
test_list += prog
endforeach
-if chamelium.found()
- foreach prog : chamelium_progs
+if chamelium_v2.found()
+ foreach prog : chamelium_v2_progs
testexe = executable(prog,
[join_paths('chamelium', 'v2', prog + '.c')] + extra_sources.get(prog, []),
dependencies : test_deps + extra_dependencies.get(prog, []),
@@ -456,7 +456,7 @@ if chamelium.found()
output : name + '.testlist')
endif
endforeach
- test_deps += chamelium
+ test_deps += chamelium_v2
endif
subdir('amdgpu')
--
2.43.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH i-g-t RFC 04/13] lib/chamelium: Introduce the foundation for the chamelium v3 library
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
` (2 preceding siblings ...)
2024-06-05 14:30 ` [PATCH i-g-t RFC 03/13] lib/chamelium: Change build options to split chamelium v2 and v3 Louis Chauvet
@ 2024-06-05 14:30 ` Louis Chauvet
2024-06-11 16:45 ` Kamil Konieczny
2024-06-05 14:30 ` [PATCH i-g-t RFC 05/13] lib/chamelium: Implement all RPC calls for the chamelium v3 Louis Chauvet
` (11 subsequent siblings)
15 siblings, 1 reply; 18+ messages in thread
From: Louis Chauvet @ 2024-06-05 14:30 UTC (permalink / raw)
To: igt-dev, ihf, markyacoub, thomas.petazzoni, Louis Chauvet
Adds a build option to enable building the chamelium v3 wrapper.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
lib/chamelium/v3/igt_chamelium.c | 9 +++++++++
lib/chamelium/v3/igt_chamelium.h | 8 ++++++++
lib/igt_kms.c | 9 ++++++++-
lib/meson.build | 7 +++++++
lib/tests/meson.build | 4 ++++
meson.build | 17 +++++++++++++++-
meson_options.txt | 4 ++++
tests/meson.build | 43 +++++++++++++++++++++++++++++++---------
8 files changed, 90 insertions(+), 11 deletions(-)
diff --git a/lib/chamelium/v3/igt_chamelium.c b/lib/chamelium/v3/igt_chamelium.c
new file mode 100644
index 000000000000..9579bd2cd9f8
--- /dev/null
+++ b/lib/chamelium/v3/igt_chamelium.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <igt_core.h>
+#include "igt_chamelium.h"
+
+void chamelium_v3_init(void)
+{
+ igt_info("Using chamelium v3\n");
+}
diff --git a/lib/chamelium/v3/igt_chamelium.h b/lib/chamelium/v3/igt_chamelium.h
new file mode 100644
index 000000000000..1848f66b574f
--- /dev/null
+++ b/lib/chamelium/v3/igt_chamelium.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef V3_IGT_CHAMELIUM_H
+#define V3_IGT_CHAMELIUM_H
+
+void chamelium_v3_init(void);
+
+#endif //V3_IGT_CHAMELIUM_H
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index fbb9c545e1b4..56038b82b8a0 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -2882,8 +2882,14 @@ void igt_display_require(igt_display_t *display, int drm_fd)
if (!resources)
goto out;
-#ifdef HAVE_CHAMELIUM
+/*
+ * FIXME: Dirty hack to avoid those lines when chamelium v3 is used
+ *
+ * Must be replaced with a configuration file information, so the end user can choose if the
+ * chamelium must be connected or not.
+ */
#ifdef HAVE_CHAMELIUM_V2
+#ifndef HAVE_CHAMELIUM_V3
{
struct chamelium *chamelium;
@@ -2898,6 +2904,7 @@ void igt_display_require(igt_display_t *display, int drm_fd)
chamelium_deinit_rpc_only(chamelium);
}
}
+#endif
#endif
igt_require_f(resources->count_crtcs <= IGT_MAX_PIPES,
diff --git a/lib/meson.build b/lib/meson.build
index accf9ff41222..126bd07c1d66 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -196,6 +196,13 @@ if chamelium_v2.found()
lib_sources += 'monitor_edids/monitor_edids_helper.c'
endif
+if chamelium_v3.found()
+ lib_deps += chamelium_v3
+ lib_sources += [
+ 'chamelium/v3/igt_chamelium.c',
+ ]
+endif
+
if libprocps.found()
lib_deps += libprocps
else
diff --git a/lib/tests/meson.build b/lib/tests/meson.build
index f98c948bc827..15f484ba0d54 100644
--- a/lib/tests/meson.build
+++ b/lib/tests/meson.build
@@ -39,6 +39,10 @@ if chamelium_v2.found()
lib_tests += 'igt_audio'
endif
+if chamelium_v3.found()
+ lib_deps += chamelium_v3
+endif
+
foreach lib_test : lib_tests
exec = executable(lib_test, lib_test + '.c', install : false,
dependencies : igt_deps)
diff --git a/meson.build b/meson.build
index a6c8ddf6a128..47a509db734b 100644
--- a/meson.build
+++ b/meson.build
@@ -87,6 +87,7 @@ foreach cc_arg : cc_args
endforeach
build_chamelium_v2 = get_option('chamelium_v2')
+build_chamelium_v3 = get_option('chamelium_v3')
build_docs = get_option('docs')
build_tests = not get_option('tests').disabled()
build_xe = not get_option('xe_driver').disabled()
@@ -172,7 +173,7 @@ if not xmlrpc.found() and xmlrpc_cmd.found()
endif
endif
-if build_chamelium_v2.enabled() and not (xmlrpc.found() and xmlrpc_util.found() and xmlrpc_client.found())
+if (build_chamelium_v2.enabled() or build_chamelium_v3.enabled()) and not (xmlrpc.found() and xmlrpc_util.found() and xmlrpc_client.found())
error('Chamelium build forced and required dependency xmlrpc not found')
endif
@@ -195,6 +196,20 @@ endif
build_info += 'Build Chamelium v2 test: @0@'.format(chamelium_v2.found())
+
+if xmlrpc.found() and xmlrpc_util.found() and xmlrpc_client.found() and libcurl.found()
+ config.set('HAVE_CHAMELIUM_V3', 1)
+ chamelium_v3 = declare_dependency(dependencies : [
+ xmlrpc,
+ xmlrpc_util,
+ xmlrpc_client,
+ gsl,
+ alsa,
+ ])
+else
+ chamelium_v3 = disabler()
+endif
+
pthreads = dependency('threads')
math = cc.find_library('m')
realtime = cc.find_library('rt')
diff --git a/meson_options.txt b/meson_options.txt
index fea91fb129aa..4d4047407854 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -12,6 +12,10 @@ option('chamelium_v2',
type : 'feature',
description : 'Build Chamelium v2 test')
+option('chamelium_v3',
+ type : 'feature',
+ description : 'Build Chamelium v3 tests')
+
option('valgrind',
type : 'feature',
description : 'Build with support for valgrind annotations')
diff --git a/tests/meson.build b/tests/meson.build
index 0b0a913bd878..d7c20e235325 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -334,6 +334,9 @@ chamelium_v2_progs = [
'kms_chamelium_hpd',
]
+chamelium_v3_progs = [
+]
+
test_deps = [ igt_deps ]
if libdrm_nouveau.found()
@@ -440,25 +443,47 @@ endforeach
if chamelium_v2.found()
foreach prog : chamelium_v2_progs
testexe = executable(prog,
- [join_paths('chamelium', 'v2', prog + '.c')] + extra_sources.get(prog, []),
- dependencies : test_deps + extra_dependencies.get(prog, []),
- install_dir : libexecdir,
- install_rpath : libexecdir_rpathdir,
- install : true)
+ [join_paths('chamelium', 'v2', prog + '.c')] + extra_sources.get(prog, []),
+ dependencies : test_deps + extra_dependencies.get(prog, []),
+ install_dir : libexecdir,
+ install_rpath : libexecdir_rpathdir,
+ install : true)
test_list += prog
test_executables += testexe
name = prog.split('/').get(-1)
if not meson.is_cross_build()
testlist_files += custom_target(name + '.testlist',
- build_by_default : true,
- command : [testexe, '--show-testlist'],
- capture : true,
- output : name + '.testlist')
+ build_by_default : true,
+ command : [testexe, '--show-testlist'],
+ capture : true,
+ output : name + '.testlist')
endif
endforeach
test_deps += chamelium_v2
endif
+if chamelium_v3.found()
+ foreach prog : chamelium_v3_progs
+ testexe = executable(prog,
+ [join_paths('chamelium', 'v3', prog + '.c')],
+ dependencies : test_deps,
+ install_dir : libexecdir,
+ install_rpath : libexecdir_rpathdir,
+ install : true)
+ test_list += prog
+ test_executables += testexe
+ name = prog.split('/').get(-1)
+ if not meson.is_cross_build()
+ testlist_files += custom_target(name + '.testlist',
+ build_by_default : true,
+ command : [testexe, '--show-testlist'],
+ capture : true,
+ output : name + '.testlist')
+ endif
+ endforeach
+ test_deps += chamelium_v3
+endif
+
subdir('amdgpu')
subdir('v3d')
--
2.43.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH i-g-t RFC 04/13] lib/chamelium: Introduce the foundation for the chamelium v3 library
2024-06-05 14:30 ` [PATCH i-g-t RFC 04/13] lib/chamelium: Introduce the foundation for the chamelium v3 library Louis Chauvet
@ 2024-06-11 16:45 ` Kamil Konieczny
0 siblings, 0 replies; 18+ messages in thread
From: Kamil Konieczny @ 2024-06-11 16:45 UTC (permalink / raw)
To: igt-dev; +Cc: Louis Chauvet, ihf, markyacoub, thomas.petazzoni
Hi Louis,
On 2024-06-05 at 16:30:16 +0200, Louis Chauvet wrote:
> Adds a build option to enable building the chamelium v3 wrapper.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> lib/chamelium/v3/igt_chamelium.c | 9 +++++++++
> lib/chamelium/v3/igt_chamelium.h | 8 ++++++++
> lib/igt_kms.c | 9 ++++++++-
> lib/meson.build | 7 +++++++
> lib/tests/meson.build | 4 ++++
> meson.build | 17 +++++++++++++++-
> meson_options.txt | 4 ++++
> tests/meson.build | 43 +++++++++++++++++++++++++++++++---------
> 8 files changed, 90 insertions(+), 11 deletions(-)
>
> diff --git a/lib/chamelium/v3/igt_chamelium.c b/lib/chamelium/v3/igt_chamelium.c
> new file mode 100644
> index 000000000000..9579bd2cd9f8
> --- /dev/null
> +++ b/lib/chamelium/v3/igt_chamelium.c
> @@ -0,0 +1,9 @@
> +// SPDX-License-Identifier: GPL-2.0
------------------------------ ^^^^^^^
Please use MIT here.
> +
> +#include <igt_core.h>
imho here:
#include "igt_core.h"
and this should be after igt_chamelium.h (alphabetical order).
> +#include "igt_chamelium.h"
> +
Describe each new lib function here.
Regards,
Kamil
> +void chamelium_v3_init(void)
> +{
> + igt_info("Using chamelium v3\n");
> +}
> diff --git a/lib/chamelium/v3/igt_chamelium.h b/lib/chamelium/v3/igt_chamelium.h
> new file mode 100644
> index 000000000000..1848f66b574f
> --- /dev/null
> +++ b/lib/chamelium/v3/igt_chamelium.h
> @@ -0,0 +1,8 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef V3_IGT_CHAMELIUM_H
> +#define V3_IGT_CHAMELIUM_H
> +
> +void chamelium_v3_init(void);
> +
> +#endif //V3_IGT_CHAMELIUM_H
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index fbb9c545e1b4..56038b82b8a0 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -2882,8 +2882,14 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> if (!resources)
> goto out;
>
> -#ifdef HAVE_CHAMELIUM
> +/*
> + * FIXME: Dirty hack to avoid those lines when chamelium v3 is used
> + *
> + * Must be replaced with a configuration file information, so the end user can choose if the
> + * chamelium must be connected or not.
> + */
> #ifdef HAVE_CHAMELIUM_V2
> +#ifndef HAVE_CHAMELIUM_V3
> {
> struct chamelium *chamelium;
>
> @@ -2898,6 +2904,7 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> chamelium_deinit_rpc_only(chamelium);
> }
> }
> +#endif
> #endif
>
> igt_require_f(resources->count_crtcs <= IGT_MAX_PIPES,
> diff --git a/lib/meson.build b/lib/meson.build
> index accf9ff41222..126bd07c1d66 100644
> --- a/lib/meson.build
> +++ b/lib/meson.build
> @@ -196,6 +196,13 @@ if chamelium_v2.found()
> lib_sources += 'monitor_edids/monitor_edids_helper.c'
> endif
>
> +if chamelium_v3.found()
> + lib_deps += chamelium_v3
> + lib_sources += [
> + 'chamelium/v3/igt_chamelium.c',
> + ]
> +endif
> +
> if libprocps.found()
> lib_deps += libprocps
> else
> diff --git a/lib/tests/meson.build b/lib/tests/meson.build
> index f98c948bc827..15f484ba0d54 100644
> --- a/lib/tests/meson.build
> +++ b/lib/tests/meson.build
> @@ -39,6 +39,10 @@ if chamelium_v2.found()
> lib_tests += 'igt_audio'
> endif
>
> +if chamelium_v3.found()
> + lib_deps += chamelium_v3
> +endif
> +
> foreach lib_test : lib_tests
> exec = executable(lib_test, lib_test + '.c', install : false,
> dependencies : igt_deps)
> diff --git a/meson.build b/meson.build
> index a6c8ddf6a128..47a509db734b 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -87,6 +87,7 @@ foreach cc_arg : cc_args
> endforeach
>
> build_chamelium_v2 = get_option('chamelium_v2')
> +build_chamelium_v3 = get_option('chamelium_v3')
> build_docs = get_option('docs')
> build_tests = not get_option('tests').disabled()
> build_xe = not get_option('xe_driver').disabled()
> @@ -172,7 +173,7 @@ if not xmlrpc.found() and xmlrpc_cmd.found()
> endif
> endif
>
> -if build_chamelium_v2.enabled() and not (xmlrpc.found() and xmlrpc_util.found() and xmlrpc_client.found())
> +if (build_chamelium_v2.enabled() or build_chamelium_v3.enabled()) and not (xmlrpc.found() and xmlrpc_util.found() and xmlrpc_client.found())
> error('Chamelium build forced and required dependency xmlrpc not found')
> endif
>
> @@ -195,6 +196,20 @@ endif
>
> build_info += 'Build Chamelium v2 test: @0@'.format(chamelium_v2.found())
>
> +
> +if xmlrpc.found() and xmlrpc_util.found() and xmlrpc_client.found() and libcurl.found()
> + config.set('HAVE_CHAMELIUM_V3', 1)
> + chamelium_v3 = declare_dependency(dependencies : [
> + xmlrpc,
> + xmlrpc_util,
> + xmlrpc_client,
> + gsl,
> + alsa,
> + ])
> +else
> + chamelium_v3 = disabler()
> +endif
> +
> pthreads = dependency('threads')
> math = cc.find_library('m')
> realtime = cc.find_library('rt')
> diff --git a/meson_options.txt b/meson_options.txt
> index fea91fb129aa..4d4047407854 100644
> --- a/meson_options.txt
> +++ b/meson_options.txt
> @@ -12,6 +12,10 @@ option('chamelium_v2',
> type : 'feature',
> description : 'Build Chamelium v2 test')
>
> +option('chamelium_v3',
> + type : 'feature',
> + description : 'Build Chamelium v3 tests')
> +
> option('valgrind',
> type : 'feature',
> description : 'Build with support for valgrind annotations')
> diff --git a/tests/meson.build b/tests/meson.build
> index 0b0a913bd878..d7c20e235325 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -334,6 +334,9 @@ chamelium_v2_progs = [
> 'kms_chamelium_hpd',
> ]
>
> +chamelium_v3_progs = [
> +]
> +
> test_deps = [ igt_deps ]
>
> if libdrm_nouveau.found()
> @@ -440,25 +443,47 @@ endforeach
> if chamelium_v2.found()
> foreach prog : chamelium_v2_progs
> testexe = executable(prog,
> - [join_paths('chamelium', 'v2', prog + '.c')] + extra_sources.get(prog, []),
> - dependencies : test_deps + extra_dependencies.get(prog, []),
> - install_dir : libexecdir,
> - install_rpath : libexecdir_rpathdir,
> - install : true)
> + [join_paths('chamelium', 'v2', prog + '.c')] + extra_sources.get(prog, []),
> + dependencies : test_deps + extra_dependencies.get(prog, []),
> + install_dir : libexecdir,
> + install_rpath : libexecdir_rpathdir,
> + install : true)
> test_list += prog
> test_executables += testexe
> name = prog.split('/').get(-1)
> if not meson.is_cross_build()
> testlist_files += custom_target(name + '.testlist',
> - build_by_default : true,
> - command : [testexe, '--show-testlist'],
> - capture : true,
> - output : name + '.testlist')
> + build_by_default : true,
> + command : [testexe, '--show-testlist'],
> + capture : true,
> + output : name + '.testlist')
> endif
> endforeach
> test_deps += chamelium_v2
> endif
>
> +if chamelium_v3.found()
> + foreach prog : chamelium_v3_progs
> + testexe = executable(prog,
> + [join_paths('chamelium', 'v3', prog + '.c')],
> + dependencies : test_deps,
> + install_dir : libexecdir,
> + install_rpath : libexecdir_rpathdir,
> + install : true)
> + test_list += prog
> + test_executables += testexe
> + name = prog.split('/').get(-1)
> + if not meson.is_cross_build()
> + testlist_files += custom_target(name + '.testlist',
> + build_by_default : true,
> + command : [testexe, '--show-testlist'],
> + capture : true,
> + output : name + '.testlist')
> + endif
> + endforeach
> + test_deps += chamelium_v3
> +endif
> +
> subdir('amdgpu')
>
> subdir('v3d')
>
> --
> 2.43.2
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH i-g-t RFC 05/13] lib/chamelium: Implement all RPC calls for the chamelium v3
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
` (3 preceding siblings ...)
2024-06-05 14:30 ` [PATCH i-g-t RFC 04/13] lib/chamelium: Introduce the foundation for the chamelium v3 library Louis Chauvet
@ 2024-06-05 14:30 ` Louis Chauvet
2024-06-05 14:30 ` [PATCH i-g-t RFC 06/13] lib/chamelium: Introduce a simple chamelium v3 test Louis Chauvet
` (10 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Louis Chauvet @ 2024-06-05 14:30 UTC (permalink / raw)
To: igt-dev, ihf, markyacoub, thomas.petazzoni, Louis Chauvet
Introduce all the RPC calls supported by the Chamelium v3. This commmit is
not split enough, many RPC calls are introduced at the same time, some
code is in common with chamelium v2...
I will split this in many different commits:
- Introduce igt_get_pipe_for_output, this is used in few tests and is
needed for my work in chamelium.
- Introduce `igt_wait_for_connector_status`, which allows busy waiting for
a connector becoming connected. It is in common with the chamelium v2,
but I made it more generic.
- Introduce `igt_get_connector_from_name`, extracted from the v2 code.
- Configuration reading/auto port detection (which needs to be polished
and simplified).
- The introduction of all RPC calls can be either split in many commits
and put near the tests which require them.
- In addition to the RPC calls, some helpers are useful when manipulating
video capture from the chamelium. The functions are taken from the v2
and I will put them in common with the v2 wrapper.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
lib/chamelium/v3/igt_chamelium.c | 1023 +++++++++++++++++++++++++++++++++++++-
lib/chamelium/v3/igt_chamelium.h | 114 ++++-
2 files changed, 1133 insertions(+), 4 deletions(-)
diff --git a/lib/chamelium/v3/igt_chamelium.c b/lib/chamelium/v3/igt_chamelium.c
index 9579bd2cd9f8..8a3cf8db2169 100644
--- a/lib/chamelium/v3/igt_chamelium.c
+++ b/lib/chamelium/v3/igt_chamelium.c
@@ -1,9 +1,1026 @@
// SPDX-License-Identifier: GPL-2.0
-#include <igt_core.h>
+#include <xmlrpc-c/base.h>
+#include <xmlrpc-c/client.h>
+#include <math.h>
+#include <igt_rc.h>
#include "igt_chamelium.h"
+#include "igt_core.h"
+#include "drm_mode.h"
-void chamelium_v3_init(void)
+struct igt_chamelium_rpc {
+ xmlrpc_env env;
+ xmlrpc_client *client;
+ char *url;
+
+ struct igt_list_head port_mapping;
+};
+
+struct igt_chamelium_rpc_frame_dump {
+ unsigned char *bgr;
+ size_t size;
+ int width;
+ int height;
+ chamelium_port_id port_id;
+ double timestamp;
+ int sequence;
+};
+
+static void chamelium_rpc_port_mapping_free(struct chamelium_rpc_port_mapping *port_mapping)
+{
+ igt_list_del(&port_mapping->link);
+ free(port_mapping->connector_name);
+ free(port_mapping);
+}
+
+/**
+ * chamelium_rpc_init() - Initialize the RPC connexion with a chamelium
+ *
+ * @url: URL to connect to the chamelium
+ * @url_len: length of the url
+ *
+ * Returns a chamelium_rpc pointer, which must be freed by chamelium_rpc_uninit;
+ */
+struct igt_chamelium_rpc *chamelium_rpc_init(char *url, size_t url_len)
+{
+ struct igt_chamelium_rpc *chamelium = malloc(sizeof(struct igt_chamelium_rpc));
+ struct xmlrpc_clientparms clientparms;
+ struct xmlrpc_curl_xportparms curlparms;
+
+ if (!chamelium)
+ return NULL;
+
+ memset(chamelium, 0, sizeof(*chamelium));
+ memset(&clientparms, 0, sizeof(clientparms));
+ memset(&curlparms, 0, sizeof(curlparms));
+
+ /* curl's timeout is in milliseconds */
+ curlparms.timeout = 10 * 1000;
+
+ clientparms.transport = "curl";
+ clientparms.transportparmsP = &curlparms;
+ clientparms.transportparm_size = XMLRPC_CXPSIZE(timeout);
+
+ /* Setup the libxmlrpc context */
+ xmlrpc_env_init(&chamelium->env);
+ xmlrpc_client_setup_global_const(&chamelium->env);
+ xmlrpc_client_create(&chamelium->env, XMLRPC_CLIENT_NO_FLAGS, PACKAGE,
+ PACKAGE_VERSION, &clientparms, 0, &chamelium->client);
+ if (chamelium->env.fault_occurred) {
+ igt_debug("Failed to init xmlrpc: %s\n",
+ chamelium->env.fault_string);
+ goto error;
+ }
+
+ chamelium->url = strdup(url);
+ IGT_INIT_LIST_HEAD(&chamelium->port_mapping);
+
+ return chamelium;
+error:
+ chamelium_rpc_uninit(chamelium);
+ return NULL;
+}
+
+/**
+ * chamelium_rpc_init_from_config() - Initialize the RPC connexion with a chamelium from the config
+ * file
+ *
+ * Returns a chamelium_rpc pointer, which must be freed by chamelium_rpc_uninit;
+ */
+struct igt_chamelium_rpc *chamelium_rpc_init_from_config(void)
+{
+ struct igt_chamelium_rpc *chamelium;
+ GError *error = NULL;
+ char *url;
+
+ if (!igt_key_file) {
+ igt_debug("No configuration file available for chamelium\n");
+ return NULL;
+ }
+
+ url = g_key_file_get_string(igt_key_file, "Chamelium", "URL", &error);
+ if (!url) {
+ igt_debug("Couldn't read chamelium URL from config file: %s\n", error->message);
+ return false;
+ }
+
+ chamelium = chamelium_rpc_init(url, strlen(url));
+ free(url);
+ return chamelium;
+}
+
+const struct chamelium_rpc_port_mapping *chamelium_rpc_find_port_mapping_by_id
+ (struct igt_chamelium_rpc *chamelium, chamelium_port_id port_id)
+{
+ struct chamelium_rpc_port_mapping *tmp, *pos;
+
+ igt_list_for_each_entry_safe(pos, tmp, &chamelium->port_mapping, link) {
+ if (pos->port_id == port_id)
+ return pos;
+ }
+ return NULL;
+}
+
+drmModeConnectorPtr
+chamelium_rpc_port_mapping_get_connector(const struct chamelium_rpc_port_mapping *chamelium_port_mapping,
+ int drm_fd)
+{
+ return igt_get_connector_from_name(drm_fd, chamelium_port_mapping->connector_name);
+}
+
+struct igt_list_head *chamelium_rpc_get_port_mapping(struct igt_chamelium_rpc *chamelium)
+{
+ return &chamelium->port_mapping;
+}
+
+static void chamelium_rpc_port_mapping_info_list(struct igt_list_head *head)
+{
+ struct chamelium_rpc_port_mapping *tmp, *pos;
+
+ igt_list_for_each_entry_safe(pos, tmp, head, link) {
+ igt_info("\t%s: port_id=%d parent_id=%d is_children=%d adapter_allowed=%d\n",
+ pos->connector_name, pos->port_id, pos->parent_id, pos->is_children,
+ pos->adapter_allowed);
+ }
+}
+
+void chamelium_rpc_fill_port_mapping(struct igt_chamelium_rpc *chamelium, int drm_fd)
+{
+ struct chamelium_rpc_port_mapping *tmp, *port_mapping;
+ GError *error = NULL;
+ char **group_list;
+ drmModeRes *res;
+ drmModeRes *res_2;
+ bool connected;
+ char *map_name;
+ int i;
+ char name[50];
+ bool found;
+ bool trust_config = false;
+ chamelium_port_id *port_ids;
+ int chamelium_port_count;
+ drmModeConnector *connector;
+ unsigned int *already_connected_connector_ids = malloc(0);
+ int already_connected_connector_ids_count = 0;
+
+ IGT_LIST_HEAD(tmp_mapping);
+
+ /* Extract current port mapping from config file */
+ if (igt_key_file) {
+ group_list = g_key_file_get_groups(igt_key_file, NULL);
+ for (i = 0; group_list[i]; i++) {
+ if (strstr(group_list[i], "Chamelium:")) {
+ tmp = malloc(sizeof(*tmp));
+ map_name = group_list[i] + (sizeof("Chamelium:") - 1);
+
+ tmp->connector_name = strdup(map_name);
+ tmp->port_id = g_key_file_get_integer(igt_key_file, group_list[i],
+ "ChameliumPortID",
+ &error);
+ if (error) {
+ igt_info("Skipping malformed entry %s: %s\n",
+ group_list[i], error->message);
+ free(tmp->connector_name);
+ free(tmp);
+ continue;
+ }
+
+ if (g_key_file_has_key(igt_key_file, group_list[i],
+ "AdapterAllowed", NULL)) {
+ tmp->adapter_allowed = g_key_file_get_boolean(igt_key_file,
+ group_list[i],
+ "AdapterAllowed",
+ &error);
+ if (error) {
+ igt_info("Skipping malformed entry %s: %s\n",
+ group_list[i], error->message);
+ free(tmp->connector_name);
+ free(tmp);
+ continue;
+ }
+ } else {
+ tmp->adapter_allowed = false;
+ }
+
+ if (g_key_file_has_key(igt_key_file, group_list[i],
+ "ChameliumParentId", NULL)) {
+ tmp->parent_id = g_key_file_get_integer(igt_key_file,
+ group_list[i],
+ "ChameliumParentId",
+ &error);
+ tmp->is_children = true;
+ if (error) {
+ igt_info("Skipping malformed entry %s: %s\n",
+ group_list[i],
+ error->message);
+ free(tmp->connector_name);
+ free(tmp);
+ continue;
+ }
+ } else {
+ tmp->parent_id = 0;
+ tmp->is_children = false;
+ }
+
+ igt_list_add(&tmp->link, &tmp_mapping);
+ }
+ free(group_list[i]);
+ }
+ free(group_list);
+
+ trust_config = g_key_file_get_boolean(igt_key_file, "Chamelium", "TrustConfig",
+ &error);
+ }
+
+ if (trust_config) {
+ igt_list_for_each_entry_safe(port_mapping, tmp, &tmp_mapping, link) {
+ igt_list_del(&port_mapping->link);
+ igt_list_add(&port_mapping->link, &chamelium->port_mapping);
+ }
+ } else {
+ /* Attempt to find direct connection connectors (no MST here) */
+ chamelium_reset_rpc(chamelium);
+ res = drmModeGetResources(drm_fd);
+ if (!res)
+ return;
+
+ for (i = 0; i < res->count_connectors; i++) {
+ connector = drmModeGetConnector(drm_fd, res->connectors[i]);
+
+ /* We have to generate the connector name on our own */
+ snprintf(name, 50, "%s-%u",
+ kmstest_connector_type_str(connector->connector_type),
+ connector->connector_type_id);
+
+ igt_debug("Attempt to find the port mapping of %s (connector_id=%d)\n",
+ name, connector->connector_id);
+
+ /* If not found, try to auto-detect the chamelium port */
+ if (connector->connection == DRM_MODE_CONNECTED) {
+ igt_warn("The connector %s is reported as connected, impossible to perform autodetection, skip it.\n",
+ name);
+ already_connected_connector_ids_count++;
+ already_connected_connector_ids = calloc(already_connected_connector_ids_count,
+ sizeof(*already_connected_connector_ids));
+ already_connected_connector_ids[already_connected_connector_ids_count - 1] = connector->connector_id;
+ drmModeFreeConnector(connector);
+ continue;
+ }
+
+ chamelium_port_count = chamelium_get_supported_ports_rpc(chamelium,
+ &port_ids);
+ igt_debug("Connector %s not found in config, plug all chamelium port to find the correct port_id\n",
+ name);
+ for (int i_2 = 0; i_2 < chamelium_port_count; i_2++) {
+ chamelium_reset_rpc(chamelium);
+ if (chamelium_is_pysical_plugged_rpc(chamelium, port_ids[i_2])) {
+ chamelium_apply_edid_rpc(chamelium, port_ids[i_2], 0);
+ chamelium_plug_rpc(chamelium, port_ids[i_2]);
+ connected = igt_wait_for_connector_status(drm_fd,
+ connector->connector_id,
+ 5.0,
+ DRM_MODE_CONNECTED);
+ if (connected) {
+ tmp = malloc(sizeof(*tmp));
+ tmp->connector_name = strdup(name);
+ tmp->port_id = port_ids[i_2];
+ tmp->adapter_allowed = false;
+ tmp->is_children = false;
+ tmp->parent_id = false;
+ igt_list_add(&tmp->link, &chamelium->port_mapping);
+ igt_info("Connector %s detected on port_id %d\n",
+ name, tmp->port_id);
+ }
+ }
+ }
+ free(port_ids);
+ drmModeFreeConnector(connector);
+ }
+
+ /*
+ * Insert the remaning connectors if they are MST children and their parent are
+ * found
+ */
+ int prev_count = 0;
+
+ while (prev_count != igt_list_length(&tmp_mapping)) {
+ prev_count = igt_list_length(&tmp_mapping);
+ igt_list_for_each_entry_safe(port_mapping, tmp, &tmp_mapping, link) {
+ if (!port_mapping->is_children) {
+ igt_warn("The connector %s is not detected and is not an MST children, skipping it.\n",
+ port_mapping->connector_name);
+ chamelium_rpc_port_mapping_free(port_mapping);
+ continue;
+ }
+ if (!chamelium_rpc_find_port_mapping_by_id(chamelium,
+ port_mapping->parent_id)) {
+ igt_debug("The parent of %s is not found yet, keeping it for the next iteration\n",
+ port_mapping->connector_name);
+ continue;
+ }
+ igt_list_del(&port_mapping->link);
+ igt_list_add(&port_mapping->link, &chamelium->port_mapping);
+ }
+ }
+
+ igt_list_for_each_entry_safe(port_mapping, tmp, &tmp_mapping, link) {
+ igt_warn("The configured connector %s is not a physical port nor a MST children in the Chamelium\n",
+ port_mapping->connector_name);
+ chamelium_rpc_port_mapping_free(port_mapping);
+ }
+ }
+
+ igt_info("Port mapping found after scanning:\n");
+ chamelium_rpc_port_mapping_info_list(&chamelium->port_mapping);
+ free(already_connected_connector_ids);
+}
+
+/**
+ * chamelium_deinit() - Free the resources used by a chamelium_rpc
+ *
+ * @chamelium_rpc: The Chamelium instance to free
+ *
+ * Frees the resources used by a connection to the chamelium that was set up
+ * with chamelium_rpc_init().
+ */
+void chamelium_rpc_uninit(struct igt_chamelium_rpc *chamelium_rpc)
+{
+ struct chamelium_rpc_port_mapping *port_mapping, *tmp_port_mapping;
+
+ /* Destroy any EDIDs we created to make sure we don't leak them */
+ igt_list_for_each_entry_safe(port_mapping, tmp_port_mapping, &chamelium_rpc->port_mapping,
+ link) {
+ chamelium_rpc_port_mapping_free(port_mapping);
+ }
+ free(chamelium_rpc);
+}
+
+static xmlrpc_value *__chamelium_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ const char *method_name,
+ const char *format_str,
+ ...)
+{
+ xmlrpc_value *res;
+ va_list va_args;
+
+ if (chamelium_rpc->env.fault_occurred) {
+ xmlrpc_env_clean(&chamelium_rpc->env);
+ xmlrpc_env_init(&chamelium_rpc->env);
+ }
+ va_start(va_args, format_str);
+ xmlrpc_client_call2f_va(&chamelium_rpc->env, chamelium_rpc->client,
+ chamelium_rpc->url, method_name, format_str, &res,
+ va_args);
+ va_end(va_args);
+ igt_assert_f(!chamelium_rpc->env.fault_occurred,
+ "Chamelium RPC call[%s] failed: %s\n", method_name,
+ chamelium_rpc->env.fault_string);
+ return res;
+}
+
+unsigned int chamelium_get_connector_type_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port)
+{
+ xmlrpc_value *res;
+ const char *port_type_str;
+ unsigned int port_type;
+
+ res = __chamelium_rpc(chamelium_rpc, "GetConnectorType", "(i)", port);
+
+ xmlrpc_read_string(&chamelium_rpc->env, res, &port_type_str);
+
+ if (strcmp(port_type_str, "DP") == 0)
+ port_type = DRM_MODE_CONNECTOR_DisplayPort;
+ else if (strcmp(port_type_str, "HDMI") == 0)
+ port_type = DRM_MODE_CONNECTOR_HDMIA;
+ else if (strcmp(port_type_str, "VGA") == 0)
+ port_type = DRM_MODE_CONNECTOR_VGA;
+ else
+ port_type = DRM_MODE_CONNECTOR_Unknown;
+
+ free((void *)port_type_str);
+ xmlrpc_DECREF(res);
+
+ return port_type;
+}
+
+void chamelium_reset_rpc(struct igt_chamelium_rpc *chamelium_rpc)
+{
+ igt_debug("RPC Reset()\n");
+ xmlrpc_DECREF(__chamelium_rpc(chamelium_rpc, "Reset", "()"));
+}
+
+void chamelium_get_mac_rpc(struct igt_chamelium_rpc *chamelium_rpc, char mac[6])
+{
+ xmlrpc_value *res;
+ const char *mac_str;
+
+ igt_debug("RPC GetMacAddress()\n");
+ res = __chamelium_rpc(chamelium_rpc, "GetMacAddress", "()");
+
+ xmlrpc_read_string(&chamelium_rpc->env, res, &mac_str);
+
+ igt_assert_eq(sscanf(mac_str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx%*c", &mac[0], &mac[1],
+ &mac[2], &mac[3], &mac[4], &mac[5]), 6);
+
+ free((void *) mac_str);
+ xmlrpc_DECREF(res);
+}
+
+/*
+ * The caller must free the returned pointer
+ */
+char *chamelium_get_port_name_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port_id)
+{
+ xmlrpc_value *res;
+ const char *port_name;
+
+ igt_debug("RPC GetPortName(%d)\n", port_id);
+ res = __chamelium_rpc(chamelium_rpc, "GetPortName", "(i)", port_id);
+
+ xmlrpc_read_string(&chamelium_rpc->env, res, &port_name);
+
+ xmlrpc_DECREF(res);
+
+ return port_name;
+}
+
+/*
+ * The caller must free the returned pointer
+ */
+int chamelium_get_supported_ports_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id **port_ids)
+{
+ xmlrpc_value *res, *res_port;
+ int port_count, i;
+
+ igt_debug("RPC GetSupportedPorts()\n");
+ res = __chamelium_rpc(chamelium_rpc, "GetSupportedPorts", "()");
+
+ port_count = xmlrpc_array_size(&chamelium_rpc->env, res);
+ *port_ids = calloc(port_count, sizeof(**port_ids));
+
+ for (i = 0; i < port_count; i++) {
+ xmlrpc_array_read_item(&chamelium_rpc->env, res, i, &res_port);
+ xmlrpc_read_int(&chamelium_rpc->env, res_port, &(*port_ids)[i]);
+ xmlrpc_DECREF(res_port);
+ }
+ xmlrpc_DECREF(res);
+
+ return port_count;
+}
+
+/*
+ * The caller must free the returned pointer
+ */
+int chamelium_get_children_rpc(struct igt_chamelium_rpc *chamelium_rpc, chamelium_port_id port_id,
+ chamelium_port_id **port_ids)
+{
+ xmlrpc_value *res, *res_port;
+ int port_count, i;
+
+ igt_debug("RPC GetChildren(%d)\n", port_id);
+ res = __chamelium_rpc(chamelium_rpc, "GetChildren", "(i)", port_id);
+
+ port_count = xmlrpc_array_size(&chamelium_rpc->env, res);
+ *port_ids = calloc(port_count, sizeof(**port_ids));
+
+ for (i = 0; i < port_count; i++) {
+ xmlrpc_array_read_item(&chamelium_rpc->env, res, i, &res_port);
+ xmlrpc_read_int(&chamelium_rpc->env, res_port, &(*port_ids)[i]);
+ xmlrpc_DECREF(res_port);
+ }
+ xmlrpc_DECREF(res);
+
+ return port_count;
+}
+
+bool chamelium_is_mst_rpc(struct igt_chamelium_rpc *chamelium_rpc, chamelium_port_id port_id)
+{
+ xmlrpc_value *res;
+ xmlrpc_bool is_mst;
+
+ igt_debug("RPC IsMst(%d)\n", port_id);
+ res = __chamelium_rpc(chamelium_rpc, "IsMst", "(i)", port_id);
+
+ xmlrpc_read_bool(&chamelium_rpc->env, res, &is_mst);
+
+ xmlrpc_DECREF(res);
+
+ return is_mst;
+}
+
+bool chamelium_has_audio_support_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port_id)
+{
+ xmlrpc_value *res;
+ xmlrpc_bool has_audio_support;
+
+ igt_debug("RPC HasAudioSupport(%d)\n", port_id);
+ res = __chamelium_rpc(chamelium_rpc, "HasAudioSupport", "(i)", port_id);
+ xmlrpc_read_bool(&chamelium_rpc->env, res, &has_audio_support);
+
+ xmlrpc_DECREF(res);
+
+ return has_audio_support;
+}
+
+bool chamelium_has_video_support_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port_id)
+{
+ xmlrpc_value *res;
+ xmlrpc_bool has_video_support;
+
+ igt_debug("RPC HasVideoSupport(%d)\n", port_id);
+ res = __chamelium_rpc(chamelium_rpc, "HasVideoSupport", "(i)", port_id);
+ xmlrpc_read_bool(&chamelium_rpc->env, res, &has_video_support);
+
+ xmlrpc_DECREF(res);
+
+ return has_video_support;
+}
+
+chamelium_edid_id chamelium_create_edid_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ const struct edid *edid)
+{
+ xmlrpc_value *res;
+ chamelium_edid_id edid_id;
+
+ igt_debug("RPC CreateEdid(...)\n");
+ res = __chamelium_rpc(chamelium_rpc, "CreateEdid", "(6)",
+ edid, edid_get_size(edid));
+ xmlrpc_read_int(&chamelium_rpc->env, res, &edid_id);
+ xmlrpc_DECREF(res);
+
+ return edid_id;
+}
+
+void chamelium_destroy_edid_rpc(struct igt_chamelium_rpc *chamelium_rpc, chamelium_edid_id edid_id)
+{
+ igt_debug("RPC DestroyEdid(%d)\n", edid_id);
+ xmlrpc_DECREF(__chamelium_rpc(chamelium_rpc, "DestroyEdid", "(i)", edid_id));
+}
+
+/*
+ * The caller must free the returned pointer
+ */
+const struct edid *chamelium_read_edid_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port_id)
+{
+ xmlrpc_value *res;
+ const struct edid *edid;
+ size_t edid_size;
+
+ igt_debug("RPC ReadEdid(%d)\n", port_id);
+ res = __chamelium_rpc(chamelium_rpc, "ReadEdid", "(i)", port_id);
+ xmlrpc_read_base64(&chamelium_rpc->env, res, &edid_size, (const unsigned char **)&edid);
+
+ xmlrpc_DECREF(res);
+
+ return edid;
+}
+
+void chamelium_apply_edid_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port_id, chamelium_edid_id edid_id)
+{
+ igt_debug("RPC ApplyEdid(%d, %d)\n", port_id, edid_id);
+ xmlrpc_DECREF(__chamelium_rpc(chamelium_rpc, "ApplyEdid", "(ii)", port_id, edid_id));
+}
+
+bool chamelium_is_conflict_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port_id_a, chamelium_port_id port_id_b)
+{
+ xmlrpc_value *res;
+ xmlrpc_bool conflict;
+
+ igt_debug("RPC IsConflict(%d, %d)\n", port_id_a, port_id_b);
+ res = __chamelium_rpc(chamelium_rpc, "IsConflict", "(ii)", port_id_a, port_id_b);
+ xmlrpc_read_bool(&chamelium_rpc->env, res, &conflict);
+
+ xmlrpc_DECREF(res);
+
+ return conflict;
+}
+
+/*
+ * The caller must free the returned pointer
+ */
+const chamelium_port_id *chamelium_get_mutually_exclusive_ports_rpc
+ (struct igt_chamelium_rpc *chamelium_rpc, chamelium_port_id port_id)
+{
+ chamelium_port_id *port_ids;
+ xmlrpc_value *res, *res_port;
+ int port_count;
+
+ igt_debug("RPC GetMutuallyExclusivePorts(%d)\n", port_id);
+ res = __chamelium_rpc(chamelium_rpc, "GetMutuallyExclusivePorts", "(i)", port_id);
+
+ port_count = xmlrpc_array_size(&chamelium_rpc->env, res);
+ port_ids = calloc(port_count, sizeof(*port_ids));
+
+ for (; port_count > 0; port_count--) {
+ xmlrpc_array_read_item(&chamelium_rpc->env, res, port_count - 1, &res_port);
+ xmlrpc_read_int(&chamelium_rpc->env, res_port, &port_ids[port_count - 1]);
+ xmlrpc_DECREF(res_port);
+ }
+ xmlrpc_DECREF(res);
+
+ return port_ids;
+}
+
+bool chamelium_is_plugged_rpc(struct igt_chamelium_rpc *chamelium_rpc, chamelium_port_id port_id)
+{
+ xmlrpc_value *res;
+ xmlrpc_bool plugged;
+
+ igt_debug("RPC IsPlugged(%d)\n", port_id);
+ res = __chamelium_rpc(chamelium_rpc, "IsPlugged", "(i)", port_id);
+ xmlrpc_read_bool(&chamelium_rpc->env, res, &plugged);
+
+ xmlrpc_DECREF(res);
+
+ return plugged;
+}
+
+void chamelium_plug_rpc(struct igt_chamelium_rpc *chamelium_rpc, chamelium_port_id port_id)
+{
+ igt_debug("RPC Plug(%d)\n", port_id);
+ xmlrpc_DECREF(__chamelium_rpc(chamelium_rpc, "Plug", "(i)", port_id));
+}
+
+void chamelium_plug_with_children_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port_id, chamelium_port_id *children,
+ size_t children_port_count)
+{
+ xmlrpc_value *tmp;
+ xmlrpc_value *children_array = xmlrpc_array_new(&chamelium_rpc->env);
+
+ for (int i = 0; i < children_port_count; i++) {
+ tmp = xmlrpc_int_new(&chamelium_rpc->env, children[i]);
+ xmlrpc_array_append_item(&chamelium_rpc->env, children_array, tmp);
+ xmlrpc_DECREF(tmp);
+ }
+
+ igt_debug("RPC PlugWithChildren(%d, ...)\n", port_id);
+ xmlrpc_DECREF(__chamelium_rpc(chamelium_rpc, "PlugWithChildren", "(iA)", port_id,
+ children_array));
+ xmlrpc_DECREF(children_array);
+}
+
+void chamelium_unplug_rpc(struct igt_chamelium_rpc *chamelium_rpc, chamelium_port_id port_id)
+{
+ igt_debug("RPC Unplug(%d)\n", port_id);
+ xmlrpc_DECREF(__chamelium_rpc(chamelium_rpc, "Unplug", "(i)", port_id));
+}
+
+void chamelium_unplug_hpd_rpc(struct igt_chamelium_rpc *chamelium_rpc, chamelium_port_id port_id)
+{
+ igt_debug("RPC UnplugHPD(%d)\n", port_id);
+ xmlrpc_DECREF(__chamelium_rpc(chamelium_rpc, "UnplugHPD", "(i)", port_id));
+}
+
+void chamelium_fire_hpd_pulse_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port_id, int deassert_interval_usec,
+ int assert_interval_usec, int repeat_count, int end_level)
{
- igt_info("Using chamelium v3\n");
+ igt_debug("RPC FireHpdPulse(%d, %d, %d, %d, ...)\n", port_id, deassert_interval_usec,
+ assert_interval_usec, repeat_count);
+
+ xmlrpc_DECREF(__chamelium_rpc(chamelium_rpc, "FireHpdPulse", "(iiiib)", port_id,
+ deassert_interval_usec, assert_interval_usec,
+ repeat_count, end_level));
+}
+
+void chamelium_fire_mixed_hpd_pulses_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port_id, int *widths_msec,
+ size_t widths_msec_count)
+{
+ xmlrpc_value *tmp;
+ xmlrpc_value *widths_msec_array = xmlrpc_array_new(&chamelium_rpc->env);
+
+ for (int i = 0; i < widths_msec_count; i++) {
+ tmp = xmlrpc_int_new(&chamelium_rpc->env, widths_msec[i]);
+ xmlrpc_array_append_item(&chamelium_rpc->env, widths_msec_array, tmp);
+ xmlrpc_DECREF(tmp);
+ }
+
+ igt_debug("RPC FireMixedHpdPulses(%d, ...)\n", port_id);
+
+ xmlrpc_DECREF(__chamelium_rpc(chamelium_rpc, "FireMixedHpdPulses", "(iA)", port_id,
+ widths_msec_array));
+ xmlrpc_DECREF(widths_msec_array);
+}
+
+void chamelium_schedule_hpd_toggle_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port_id, int delay_ms, bool end_level)
+{
+ igt_debug("RPC ScheduleHpdToggle(%d, %d, %d)\n", port_id, delay_ms, end_level);
+ xmlrpc_DECREF(__chamelium_rpc(chamelium_rpc, "ScheduleHpdToggle", "(iib)", port_id,
+ delay_ms, end_level));
+}
+
+bool chamelium_port_wait_video_input_stable_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port_id,
+ int timeout_secs)
+{
+ xmlrpc_value *res;
+ xmlrpc_bool is_on;
+
+ igt_debug("RPC WaitVideoInputStable(%d, %d)\n", port_id, timeout_secs);
+ res = __chamelium_rpc(chamelium_rpc, "WaitVideoInputStable", "(ii)",
+ port_id, timeout_secs);
+
+ xmlrpc_read_bool(&chamelium_rpc->env, res, &is_on);
+ xmlrpc_DECREF(res);
+
+ return is_on;
+}
+
+bool chamelium_is_pysical_plugged_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port_id)
+{
+ xmlrpc_value *res;
+ xmlrpc_bool plugged;
+
+ igt_debug("RPC IsPhysicalPlugged(%d)\n", port_id);
+ res = __chamelium_rpc(chamelium_rpc, "IsPhysicalPlugged", "(i)", port_id);
+ xmlrpc_read_bool(&chamelium_rpc->env, res, &plugged);
+
+ xmlrpc_DECREF(res);
+
+ return plugged;
+}
+
+/*
+ * The caller must free the returned pointer
+ */
+const chamelium_port_id *chamelium_probe_ports_rpc(struct igt_chamelium_rpc *chamelium_rpc)
+{
+ chamelium_port_id *port_ids;
+ xmlrpc_value *res, *res_port;
+ int port_count;
+
+ igt_debug("RPC ProbePorts()\n");
+ res = __chamelium_rpc(chamelium_rpc, "ProbePorts", "()");
+
+ port_count = xmlrpc_array_size(&chamelium_rpc->env, res);
+ port_ids = calloc(port_count, sizeof(*port_ids));
+
+ for (; port_count > 0; port_count--) {
+ xmlrpc_array_read_item(&chamelium_rpc->env, res, port_count - 1, &res_port);
+ xmlrpc_read_int(&chamelium_rpc->env, res_port, &port_ids[port_count - 1]);
+ xmlrpc_DECREF(res_port);
+ }
+ xmlrpc_DECREF(res);
+
+ return port_ids;
+}
+
+void chamelium_port_get_resolution_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port_id,
+ int *x, int *y)
+{
+ xmlrpc_value *res, *res_x, *res_y;
+
+ igt_debug("RPC DetectResolution(%d)\n", port_id);
+ res = __chamelium_rpc(chamelium_rpc, "DetectResolution", "(i)",
+ port_id);
+
+ xmlrpc_array_read_item(&chamelium_rpc->env, res, 0, &res_x);
+ xmlrpc_array_read_item(&chamelium_rpc->env, res, 1, &res_y);
+ xmlrpc_read_int(&chamelium_rpc->env, res_x, x);
+ xmlrpc_read_int(&chamelium_rpc->env, res_y, y);
+
+ xmlrpc_DECREF(res_x);
+ xmlrpc_DECREF(res_y);
+ xmlrpc_DECREF(res);
+}
+
+void chamelium_capture_video_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port_id, int frame_count)
+{
+ igt_debug("RPC CaptureVideo(%d, %d)\n", port_id, frame_count);
+ xmlrpc_DECREF(__chamelium_rpc(chamelium_rpc, "CaptureVideo", "(iinnnn)", port_id,
+ frame_count));
+}
+
+void chamelium_port_get_captured_resolution_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ int *width, int *height)
+{
+ xmlrpc_value *res, *res_width, *res_height;
+
+ igt_debug("RPC GetCapturedResolution()\n");
+ res = __chamelium_rpc(chamelium_rpc, "GetCapturedResolution", "()");
+
+ xmlrpc_array_read_item(&chamelium_rpc->env, res, 0, &res_width);
+ xmlrpc_array_read_item(&chamelium_rpc->env, res, 1, &res_height);
+ xmlrpc_read_int(&chamelium_rpc->env, res_width, width);
+ xmlrpc_read_int(&chamelium_rpc->env, res_height, height);
+
+ xmlrpc_DECREF(res_width);
+ xmlrpc_DECREF(res_height);
+ xmlrpc_DECREF(res);
+}
+
+static void read_int_from_xml_struct(struct igt_chamelium_rpc *chamelium_rpc,
+ xmlrpc_value *struct_val, const char *key,
+ int *dst)
+{
+ xmlrpc_value *val = NULL;
+
+ xmlrpc_struct_find_value(&chamelium_rpc->env, struct_val, key, &val);
+ if (val) {
+ xmlrpc_read_int(&chamelium_rpc->env, val, dst);
+ xmlrpc_DECREF(val);
+ } else {
+ *dst = -1;
+ }
+}
+
+void chamelium_get_captured_frame_metadata_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ unsigned int index, int *width, int *height,
+ double *timestamp, chamelium_port_id *port_id,
+ int *sequence, size_t *size)
+{
+ xmlrpc_value *res, *tmp;
+
+ igt_debug("RPC GetCapturedFrameMetadata(%d)\n", index);
+ res = __chamelium_rpc(chamelium_rpc, "GetCapturedFrameMetadata", "(i)", index);
+
+ read_int_from_xml_struct(chamelium_rpc, res, "width", width);
+ read_int_from_xml_struct(chamelium_rpc, res, "height", height);
+ read_int_from_xml_struct(chamelium_rpc, res, "port_id", port_id);
+ read_int_from_xml_struct(chamelium_rpc, res, "sequence", sequence);
+ read_int_from_xml_struct(chamelium_rpc, res, "size", (int *)size);
+
+ xmlrpc_struct_find_value(&chamelium_rpc->env, res, "timestamp", &tmp);
+ if (tmp) {
+ xmlrpc_read_double(&chamelium_rpc->env, tmp, timestamp);
+ xmlrpc_DECREF(tmp);
+ } else {
+ *timestamp = NAN;
+ }
+
+ xmlrpc_DECREF(res);
+}
+
+/*
+ * The caller must free the returned pointer
+ */
+struct igt_chamelium_rpc_frame_dump *chamelium_read_captured_frame_rpc
+ (struct igt_chamelium_rpc *chamelium_rpc, unsigned int index)
+{
+ struct igt_chamelium_rpc_frame_dump *frame;
+ xmlrpc_value *res;
+
+ frame = malloc(sizeof(*frame));
+
+ chamelium_get_captured_frame_metadata_rpc(chamelium_rpc, index, &frame->width,
+ &frame->height, &frame->timestamp,
+ &frame->port_id, &frame->sequence,
+ &frame->size);
+
+ igt_debug("RPC ReadCapturedFrame(%d)\n", index);
+ res = __chamelium_rpc(chamelium_rpc, "ReadCapturedFrame", "(i)", index);
+
+ xmlrpc_read_base64(&chamelium_rpc->env, res, &frame->size, (void *)&frame->bgr);
+
+ xmlrpc_DECREF(res);
+
+ return frame;
+}
+
+void chamelium_port_get_video_params_rpc(struct igt_chamelium_rpc *chamelium_rpc,
+ chamelium_port_id port_id,
+ struct igt_chamelium_rpc_video_params *params)
+{
+ xmlrpc_value *res, *tmp;
+
+ igt_debug("RPC GetVideoParams(%d)\n", port_id);
+ res = __chamelium_rpc(chamelium_rpc, "GetVideoParams", "(i)", port_id);
+
+ xmlrpc_struct_find_value(&chamelium_rpc->env, res, "clock", &tmp);
+ if (tmp) {
+ xmlrpc_read_double(&chamelium_rpc->env, tmp, ¶ms->clock);
+ xmlrpc_DECREF(tmp);
+ } else {
+ params->clock = NAN;
+ }
+
+ read_int_from_xml_struct(chamelium_rpc, res, "htotal", ¶ms->htotal);
+ read_int_from_xml_struct(chamelium_rpc, res, "hactive", ¶ms->hactive);
+ read_int_from_xml_struct(chamelium_rpc, res, "hsync_offset",
+ ¶ms->hsync_offset);
+ read_int_from_xml_struct(chamelium_rpc, res, "hsync_width",
+ ¶ms->hsync_width);
+ read_int_from_xml_struct(chamelium_rpc, res, "hsync_polarity",
+ ¶ms->hsync_polarity);
+ read_int_from_xml_struct(chamelium_rpc, res, "vtotal", ¶ms->vtotal);
+ read_int_from_xml_struct(chamelium_rpc, res, "vactive", ¶ms->vactive);
+ read_int_from_xml_struct(chamelium_rpc, res, "vsync_offset",
+ ¶ms->vsync_offset);
+ read_int_from_xml_struct(chamelium_rpc, res, "vsync_width",
+ ¶ms->vsync_width);
+ read_int_from_xml_struct(chamelium_rpc, res, "vsync_polarity",
+ ¶ms->vsync_polarity);
+
+ xmlrpc_DECREF(res);
+}
+
+bool chamelium_has_audio_board_rpc(struct igt_chamelium_rpc *chamelium_rpc)
+{
+ xmlrpc_value *res;
+ xmlrpc_bool has_audio_board;
+
+ igt_debug("RPC HasAudioBoard()\n");
+ res = __chamelium_rpc(chamelium_rpc, "HasAudioBoard", "()");
+ xmlrpc_read_bool(&chamelium_rpc->env, res, &has_audio_board);
+
+ xmlrpc_DECREF(res);
+
+ return has_audio_board;
+}
+
+igt_constructor {
+ /* Frame dumps can be large, so we need to be able to handle very large
+ * responses
+ *
+ * Limit here is 15MB
+ */
+ xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, 15728640);
+}
+
+// TODO: Move it somewhere else
+drmModeConnectorPtr igt_get_connector_from_name(int drm_fd, const char *port_name)
+{
+ drmModeResPtr res = drmModeGetResources(drm_fd);
+ int i;
+
+ if (!res)
+ return 0;
+
+ for (i = 0; i < res->count_connectors; i++) {
+ char name[50];
+ bool found;
+
+ drmModeConnectorPtr connector = drmModeGetConnector(drm_fd, res->connectors[i]);
+
+ /* We have to generate the connector name on our own */
+ snprintf(name, 50, "%s-%u",
+ kmstest_connector_type_str(connector->connector_type),
+ connector->connector_type_id);
+
+
+ if (strcmp(port_name, name) == 0) {
+ drmModeFreeResources(res);
+ return connector;
+ }
+ drmModeFreeConnector(connector);
+ }
+ drmModeFreeResources(res);
+ return NULL;
+}
+
+static double elapsed(const struct timespec *start, const struct timespec *end)
+{
+ return (end->tv_sec - start->tv_sec) + 1e-9 * (end->tv_nsec - start->tv_nsec);
+}
+
+bool igt_wait_for_connector_status(int drm_fd, unsigned int connector_id, double timeout,
+ int drm_mode)
+{
+ drmModeConnector *connector;
+ struct timespec start, end;
+
+ clock_gettime(CLOCK_MONOTONIC, &start);
+ clock_gettime(CLOCK_MONOTONIC, &end);
+
+ while (elapsed(&start, &end) <= timeout) {
+ connector = drmModeGetConnector(drm_fd, connector_id);
+ if (connector->connection == drm_mode) {
+ free(connector);
+ return true;
+ }
+ free(connector);
+ clock_gettime(CLOCK_MONOTONIC, &end);
+ }
+
+ igt_debug("Timeout waiting for connection status %d on connector %d\n", drm_mode,
+ connector_id);
+ return false;
+}
+
+enum pipe igt_get_pipe_for_output(igt_display_t *display,
+ igt_output_t *output)
+{
+ enum pipe pipe;
+
+ for_each_pipe(display, pipe) {
+ if ((igt_output_is_connected((output)) &&
+ (output->config.valid_crtc_idx_mask & (1 << (pipe)))))
+ return pipe;
+ }
+
+ igt_assert_f(false, "No pipe found for output %s\n", igt_output_name(output));
}
diff --git a/lib/chamelium/v3/igt_chamelium.h b/lib/chamelium/v3/igt_chamelium.h
index 1848f66b574f..01e1357b5226 100644
--- a/lib/chamelium/v3/igt_chamelium.h
+++ b/lib/chamelium/v3/igt_chamelium.h
@@ -3,6 +3,118 @@
#ifndef V3_IGT_CHAMELIUM_H
#define V3_IGT_CHAMELIUM_H
-void chamelium_v3_init(void);
+#include "config.h"
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <xf86drmMode.h>
+
+#include "igt_debugfs.h"
+#include "igt_kms.h"
+#include "igt_list.h"
+
+#include "igt_edid.h"
+
+struct igt_chamelium_rpc;
+struct igt_chamelium_rpc_frame_dump;
+
+typedef int chamelium_port_id;
+typedef int chamelium_edid_id;
+
+struct igt_chamelium_rpc_video_params {
+ double clock;
+ int htotal, hactive, hsync_offset, hsync_width, hsync_polarity;
+ int vtotal, vactive, vsync_offset, vsync_width, vsync_polarity;
+};
+
+struct chamelium_rpc_port_mapping {
+ struct igt_list_head link;
+ chamelium_port_id port_id;
+ bool is_children;
+ chamelium_port_id parent_id;
+ char *connector_name;
+ bool adapter_allowed;
+};
+
+struct igt_chamelium_rpc *chamelium_rpc_init_from_config(void);
+struct igt_chamelium_rpc *chamelium_rpc_init(char *url, size_t url_len);
+const struct chamelium_rpc_port_mapping *
+chamelium_rpc_find_port_mapping_by_id(struct igt_chamelium_rpc *chamelium,
+ chamelium_port_id port_id);
+drmModeConnectorPtr
+chamelium_rpc_port_mapping_get_connector(const struct chamelium_rpc_port_mapping *chamelium_port_mapping,
+ int drm_fd);
+struct igt_list_head *chamelium_rpc_get_port_mapping(struct igt_chamelium_rpc *chamelium);
+void chamelium_rpc_fill_port_mapping(struct igt_chamelium_rpc *chamelium, int drm_fd);
+void chamelium_rpc_uninit(struct igt_chamelium_rpc *chamelium_rpc);
+
+/* Move this somewhere else */
+drmModeConnectorPtr igt_get_connector_from_name(int drm_fd, const char *port_name);
+bool igt_wait_for_connector_status(int drm_fd, unsigned int connector_id, double timeout,
+ int drm_mode);
+enum pipe igt_get_pipe_for_output(igt_display_t *display, igt_output_t *output);
+
+unsigned int chamelium_get_connector_type_rpc(struct igt_chamelium_rpc *chamelium,
+ chamelium_port_id port);
+void chamelium_reset_rpc(struct igt_chamelium_rpc *chamelium);
+void chamelium_get_mac_rpc(struct igt_chamelium_rpc *chamelium, char mac[6]);
+char *chamelium_get_port_name_rpc(struct igt_chamelium_rpc *chamelium, chamelium_port_id port_id);
+int chamelium_get_supported_ports_rpc(struct igt_chamelium_rpc *chamelium,
+ chamelium_port_id **port_ids);
+int chamelium_get_children_rpc(struct igt_chamelium_rpc *chamelium, chamelium_port_id port_id,
+ chamelium_port_id **port_ids);
+bool chamelium_is_mst_rpc(struct igt_chamelium_rpc *chamelium, chamelium_port_id port_id);
+bool chamelium_has_audio_support_rpc(struct igt_chamelium_rpc *chamelium,
+ chamelium_port_id port_id);
+bool chamelium_has_video_support_rpc(struct igt_chamelium_rpc *chamelium,
+ chamelium_port_id port_id);
+chamelium_edid_id chamelium_create_edid_rpc(struct igt_chamelium_rpc *chamelium,
+ const struct edid *edid);
+void chamelium_destroy_edid_rpc(struct igt_chamelium_rpc *chamelium, chamelium_edid_id edid_id);
+const struct edid *chamelium_read_edid_rpc(struct igt_chamelium_rpc *chamelium,
+ chamelium_port_id port_id);
+void chamelium_apply_edid_rpc(struct igt_chamelium_rpc *chamelium, chamelium_port_id port_id,
+ chamelium_edid_id edid_id);
+bool chamelium_is_conflict_rpc(struct igt_chamelium_rpc *chamelium, chamelium_port_id port_id_a,
+ chamelium_port_id port_id_b);
+const chamelium_port_id *
+chamelium_get_mutually_exclusive_ports_rpc(struct igt_chamelium_rpc *chamelium,
+ chamelium_port_id port_id);
+bool chamelium_is_plugged_rpc(struct igt_chamelium_rpc *chamelium, chamelium_port_id port_id);
+void chamelium_plug_rpc(struct igt_chamelium_rpc *chamelium, chamelium_port_id port_id);
+void chamelium_plug_with_children_rpc(struct igt_chamelium_rpc *chamelium,
+ chamelium_port_id port_id, chamelium_port_id *children,
+ size_t children_port_count);
+void chamelium_unplug_rpc(struct igt_chamelium_rpc *chamelium, chamelium_port_id port_id);
+void chamelium_unplug_hpd_rpc(struct igt_chamelium_rpc *chamelium, chamelium_port_id port_id);
+void chamelium_fire_hpd_pulse_rpc(struct igt_chamelium_rpc *chamelium, chamelium_port_id port_id,
+ int deassert_interval_usec, int assert_interval_usec,
+ int repeat_count, int end_level);
+void chamelium_fire_mixed_hpd_pulses_rpc(struct igt_chamelium_rpc *chamelium,
+ chamelium_port_id port_id, int *widths_msec,
+ size_t widths_msec_count);
+void chamelium_schedule_hpd_toggle_rpc(struct igt_chamelium_rpc *chamelium,
+ chamelium_port_id port_id, int delay_ms, bool end_level);
+bool chamelium_port_wait_video_input_stable_rpc(struct igt_chamelium_rpc *chamelium,
+ chamelium_port_id port_id, int timeout_secs);
+bool chamelium_is_pysical_plugged_rpc(struct igt_chamelium_rpc *chamelium,
+ chamelium_port_id port_id);
+const chamelium_port_id *chamelium_probe_ports_rpc(struct igt_chamelium_rpc *chamelium);
+void chamelium_port_get_resolution_rpc(struct igt_chamelium_rpc *chamelium,
+ chamelium_port_id port_id, int *x, int *y);
+void chamelium_capture_video_rpc(struct igt_chamelium_rpc *chamelium, chamelium_port_id port_id,
+ int frame_count);
+void chamelium_port_get_captured_resolution_rpc(struct igt_chamelium_rpc *chamelium, int *width,
+ int *height);
+void chamelium_get_captured_frame_metadata_rpc(struct igt_chamelium_rpc *chamelium,
+ unsigned int index, int *width, int *height,
+ double *timestamp, chamelium_port_id *port_id,
+ int *sequence, size_t *size);
+struct igt_chamelium_rpc_frame_dump *
+chamelium_read_captured_frame_rpc(struct igt_chamelium_rpc *chamelium, unsigned int index);
+void chamelium_port_get_video_params_rpc(struct igt_chamelium_rpc *chamelium,
+ chamelium_port_id port_id,
+ struct igt_chamelium_rpc_video_params *params);
+bool chamelium_has_audio_board_rpc(struct igt_chamelium_rpc *chamelium);
#endif //V3_IGT_CHAMELIUM_H
--
2.43.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH i-g-t RFC 06/13] lib/chamelium: Introduce a simple chamelium v3 test
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
` (4 preceding siblings ...)
2024-06-05 14:30 ` [PATCH i-g-t RFC 05/13] lib/chamelium: Implement all RPC calls for the chamelium v3 Louis Chauvet
@ 2024-06-05 14:30 ` Louis Chauvet
2024-06-05 14:30 ` [PATCH i-g-t RFC 07/13] tests/chamelium: Introduce basic edid test Louis Chauvet
` (9 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Louis Chauvet @ 2024-06-05 14:30 UTC (permalink / raw)
To: igt-dev, ihf, markyacoub, thomas.petazzoni, Louis Chauvet
Check if the chamelium is accessible
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
tests/chamelium/v3/kms_chamelium_v3_basic.c | 30 +++++++++++++++++++++++++++++
tests/meson.build | 1 +
2 files changed, 31 insertions(+)
diff --git a/tests/chamelium/v3/kms_chamelium_v3_basic.c b/tests/chamelium/v3/kms_chamelium_v3_basic.c
new file mode 100644
index 000000000000..f07106c064cb
--- /dev/null
+++ b/tests/chamelium/v3/kms_chamelium_v3_basic.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: MIT
+
+#include <igt.h>
+#include "chamelium/v3/igt_chamelium.h"
+
+igt_main
+{
+ struct igt_chamelium_rpc *chamelium;
+
+ igt_describe("Test if the chamelium can list all the ports.");
+ igt_subtest("chamelium-list-ports") {
+ chamelium_port_id *ports;
+ int port_count;
+
+ chamelium = chamelium_rpc_init_from_config();
+
+ port_count = chamelium_get_supported_ports_rpc(chamelium, &ports);
+
+ for (int i = 0; i < port_count; i++) {
+ const char *name = chamelium_get_port_name_rpc(chamelium, ports[i]);
+
+ igt_info("Port %d: name: %s\n", ports[i], name);
+ free(name);
+ }
+
+ free(ports);
+
+ chamelium_rpc_uninit(chamelium);
+ }
+}
diff --git a/tests/meson.build b/tests/meson.build
index d7c20e235325..51396548eec9 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -335,6 +335,7 @@ chamelium_v2_progs = [
]
chamelium_v3_progs = [
+ 'kms_chamelium_v3_basic',
]
test_deps = [ igt_deps ]
--
2.43.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH i-g-t RFC 07/13] tests/chamelium: Introduce basic edid test
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
` (5 preceding siblings ...)
2024-06-05 14:30 ` [PATCH i-g-t RFC 06/13] lib/chamelium: Introduce a simple chamelium v3 test Louis Chauvet
@ 2024-06-05 14:30 ` Louis Chauvet
2024-06-05 14:30 ` [PATCH i-g-t RFC 08/13] lib/monitor_edids: Introduce helpers to get EDID from a monitor EDID Louis Chauvet
` (8 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Louis Chauvet @ 2024-06-05 14:30 UTC (permalink / raw)
To: igt-dev, ihf, markyacoub, thomas.petazzoni, Louis Chauvet
This commit adds a new Chamelium v3 test that verifies the correct
handling of EDID data. The test uploads a custom EDID to the Chamelium and
then verifies that the EDID data can be read back from the kernel.
This test is inspired from the v2 version.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
tests/chamelium/v3/kms_chamelium_v3_edid.c | 93 ++++++++++++++++++++++++++++++
tests/meson.build | 1 +
2 files changed, 94 insertions(+)
diff --git a/tests/chamelium/v3/kms_chamelium_v3_edid.c b/tests/chamelium/v3/kms_chamelium_v3_edid.c
new file mode 100644
index 000000000000..acf62ba78a32
--- /dev/null
+++ b/tests/chamelium/v3/kms_chamelium_v3_edid.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: MIT
+
+#include <igt.h>
+#include "chamelium/v3/igt_chamelium.h"
+
+static void collect_and_compare_edid(int drm_fd,
+ const struct chamelium_rpc_port_mapping *port_mapping,
+ const struct edid *edid)
+{
+ drmModePropertyBlobPtr edid_blob = NULL;
+ drmModeConnector *connector;
+ uint64_t edid_blob_id;
+
+ connector = chamelium_rpc_port_mapping_get_connector(port_mapping, drm_fd);
+ igt_assert(kmstest_get_property(drm_fd, connector->connector_id,
+ DRM_MODE_OBJECT_CONNECTOR, "EDID", NULL,
+ &edid_blob_id, NULL));
+ igt_assert(edid_blob_id != 0);
+ edid_blob = drmModeGetPropertyBlob(drm_fd, edid_blob_id);
+ igt_assert(edid_blob);
+
+ igt_assert(memcmp(edid, edid_blob->data, edid_get_size(edid)) == 0);
+
+ drmModeFreePropertyBlob(edid_blob);
+ drmModeFreeConnector(connector);
+}
+
+static void upload_and_read_edid(int drm_fd, struct igt_chamelium_rpc *chamelium,
+ const struct chamelium_rpc_port_mapping *port_mapping,
+ const struct edid *edid)
+{
+ drmModePropertyBlobPtr edid_blob = NULL;
+ drmModeConnector *connector;
+ uint64_t edid_blob_id;
+ int edid_id;
+
+ chamelium_reset_rpc(chamelium);
+ edid_id = chamelium_create_edid_rpc(chamelium, edid);
+ chamelium_apply_edid_rpc(chamelium, port_mapping->port_id, edid_id);
+ chamelium_plug_rpc(chamelium, port_mapping->port_id);
+
+ connector = chamelium_rpc_port_mapping_get_connector(port_mapping, drm_fd);
+ assert(igt_wait_for_connector_status(drm_fd, connector->connector_id, 10.0,
+ DRM_MODE_CONNECTED));
+ drmModeFreeConnector(connector);
+
+ collect_and_compare_edid(drm_fd, port_mapping, edid);
+}
+
+static void igt_custom_edid_type_read(int drm_fd, struct igt_chamelium_rpc *chamelium,
+ struct chamelium_rpc_port_mapping *port_mapping,
+ enum igt_custom_edid_type edid)
+{
+ upload_and_read_edid(drm_fd, chamelium, port_mapping, igt_kms_get_custom_edid(edid));
+}
+
+igt_main {
+ struct igt_chamelium_rpc *chamelium;
+ int drm_fd;
+
+ igt_fixture {
+ chamelium = chamelium_rpc_init_from_config();
+ igt_assert(chamelium);
+ drm_fd = drm_open_driver_master(DRIVER_ANY);
+ igt_assert(drm_fd);
+ chamelium_rpc_fill_port_mapping(chamelium, drm_fd);
+ }
+
+ igt_describe("Read basic EDID from the chamelium.");
+ igt_subtest_with_dynamic("edid-read-basic") {
+ struct chamelium_rpc_port_mapping *port, *tmp;
+
+ igt_list_for_each_entry_safe(port, tmp, chamelium_rpc_get_port_mapping(chamelium),
+ link) {
+ igt_dynamic_f("port-%d", port->port_id) {
+ char *name;
+
+ name = chamelium_get_port_name_rpc(chamelium, port->port_id);
+ igt_info("Testing port %s (%s)\n", port->connector_name, name);
+ free(name);
+ igt_custom_edid_type_read(drm_fd, chamelium, port,
+ IGT_CUSTOM_EDID_BASE);
+ igt_custom_edid_type_read(drm_fd, chamelium, port,
+ IGT_CUSTOM_EDID_ALT);
+ }
+ }
+ }
+
+ igt_fixture {
+ chamelium_rpc_uninit(chamelium);
+ drm_close_driver(drm_fd);
+ }
+}
diff --git a/tests/meson.build b/tests/meson.build
index 51396548eec9..c37180eb3d3d 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -336,6 +336,7 @@ chamelium_v2_progs = [
chamelium_v3_progs = [
'kms_chamelium_v3_basic',
+ 'kms_chamelium_v3_edid',
]
test_deps = [ igt_deps ]
--
2.43.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH i-g-t RFC 08/13] lib/monitor_edids: Introduce helpers to get EDID from a monitor EDID
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
` (6 preceding siblings ...)
2024-06-05 14:30 ` [PATCH i-g-t RFC 07/13] tests/chamelium: Introduce basic edid test Louis Chauvet
@ 2024-06-05 14:30 ` Louis Chauvet
2024-06-05 14:30 ` [PATCH i-g-t RFC 09/13] tests/chamelium: Introduce 4k stress edid Louis Chauvet
` (7 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Louis Chauvet @ 2024-06-05 14:30 UTC (permalink / raw)
To: igt-dev, ihf, markyacoub, thomas.petazzoni, Louis Chauvet
Add two helpers around monitor_edid list: extracting an edid and edid list
for a specific connector type
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
lib/monitor_edids/monitor_edids_helper.c | 61 +++++++++++++++++++++++++++++++-
lib/monitor_edids/monitor_edids_helper.h | 3 ++
2 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/lib/monitor_edids/monitor_edids_helper.c b/lib/monitor_edids/monitor_edids_helper.c
index 1cbf1c22f0bb..cbd6d6fd54db 100644
--- a/lib/monitor_edids/monitor_edids_helper.c
+++ b/lib/monitor_edids/monitor_edids_helper.c
@@ -14,7 +14,10 @@
#include <string.h>
#include <assert.h>
-#include "igt_core.h"
+#include "igt.h"
+#include "igt_edid.h"
+#include "dp_edids.h"
+#include "hdmi_edids.h"
static uint8_t convert_hex_char_to_byte(char c)
{
@@ -90,3 +93,59 @@ void free_chamelium_edid_from_monitor_edid(struct chamelium_edid *edid)
free(edid);
edid = NULL;
}
+
+struct edid *edid_from_monitor_edid(const monitor_edid *monitor_edid)
+{
+ uint8_t *raw_edid;
+ size_t edid_size;
+ int i;
+
+ edid_size = strlen(monitor_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(monitor_edid->edid[i * 2]) << 4 |
+ convert_hex_char_to_byte(monitor_edid->edid[i * 2 + 1]);
+ }
+
+ if (edid_get_size((struct edid *)raw_edid) > edid_size) {
+ uint8_t *new_edid;
+
+ igt_warn("The edid size stored in the raw edid is shorter 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;
+}
+
+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 = ARRAY_SIZE(DP_EDIDS_4K);
+ return DP_EDIDS_4K;
+ case DRM_MODE_CONNECTOR_HDMIA:
+ *count = ARRAY_SIZE(HDMI_EDIDS_4K);
+ return HDMI_EDIDS_4K;
+ default:
+ igt_assert_f(0, "No 4k EDID for the connector %s\n",
+ kmstest_connector_type_str(type));
+ }
+ } else {
+ switch (type) {
+ case DRM_MODE_CONNECTOR_DisplayPort:
+ *count = ARRAY_SIZE(DP_EDIDS_NON_4K);
+ return DP_EDIDS_NON_4K;
+ case DRM_MODE_CONNECTOR_HDMIA:
+ *count = ARRAY_SIZE(HDMI_EDIDS_NON_4K);
+ return HDMI_EDIDS_NON_4K;
+ default:
+ igt_assert_f(0, "No EDID for the connector %s\n",
+ kmstest_connector_type_str(type));
+ }
+ }
+}
diff --git a/lib/monitor_edids/monitor_edids_helper.h b/lib/monitor_edids/monitor_edids_helper.h
index 63a183409293..ff5672058816 100644
--- a/lib/monitor_edids/monitor_edids_helper.h
+++ b/lib/monitor_edids/monitor_edids_helper.h
@@ -30,4 +30,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);
+struct edid *edid_from_monitor_edid(const monitor_edid *monitor_edid);
+struct monitor_edid *get_edid_for_connector_type(uint32_t type, size_t *count, bool four_k);
+
#endif /* TESTS_CHAMELIUM_MONITOR_EDIDS_MONITOR_EDIDS_HELPER_H_ */
\ No newline at end of file
--
2.43.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH i-g-t RFC 09/13] tests/chamelium: Introduce 4k stress edid
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
` (7 preceding siblings ...)
2024-06-05 14:30 ` [PATCH i-g-t RFC 08/13] lib/monitor_edids: Introduce helpers to get EDID from a monitor EDID Louis Chauvet
@ 2024-06-05 14:30 ` Louis Chauvet
2024-06-05 14:30 ` [PATCH i-g-t RFC 10/13] tests/chamelium: Introduce non-4k " Louis Chauvet
` (6 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Louis Chauvet @ 2024-06-05 14:30 UTC (permalink / raw)
To: igt-dev, ihf, markyacoub, thomas.petazzoni, Louis Chauvet
Introduce some helpers to uses monitor edid and upload them to the
chamelium.
Complement the EDID test to also test 4k screens. The current database
contains EDID for HDMI and DP ports.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
tests/chamelium/v3/kms_chamelium_v3_edid.c | 45 ++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/tests/chamelium/v3/kms_chamelium_v3_edid.c b/tests/chamelium/v3/kms_chamelium_v3_edid.c
index acf62ba78a32..76bdddd81174 100644
--- a/tests/chamelium/v3/kms_chamelium_v3_edid.c
+++ b/tests/chamelium/v3/kms_chamelium_v3_edid.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
#include <igt.h>
+#include "monitor_edids/monitor_edids_helper.h"
#include "chamelium/v3/igt_chamelium.h"
static void collect_and_compare_edid(int drm_fd,
@@ -54,6 +55,22 @@ static void igt_custom_edid_type_read(int drm_fd, struct igt_chamelium_rpc *cham
upload_and_read_edid(drm_fd, chamelium, port_mapping, igt_kms_get_custom_edid(edid));
}
+static void edid_stress_resolution(int drm_fd, struct igt_chamelium_rpc *chamelium,
+ struct chamelium_rpc_port_mapping *port_mapping,
+ monitor_edid edids_list[],
+ size_t edids_list_len)
+{
+ for (int i = 0; i < edids_list_len; i++) {
+ struct edid *edid = edid_from_monitor_edid(&edids_list[i]);
+
+ igt_info("Testing out the EDID for %s\n",
+ monitor_edid_get_name(&edids_list[i]));
+ upload_and_read_edid(drm_fd, chamelium, port_mapping, edid);
+ free(edid);
+ }
+}
+
+
igt_main {
struct igt_chamelium_rpc *chamelium;
int drm_fd;
@@ -86,6 +103,34 @@ igt_main {
}
}
+ igt_describe("Read many different 4k EDID from the chamelium");
+ igt_subtest_with_dynamic("edid-stress-4k") {
+ struct chamelium_rpc_port_mapping *port, *tmp;
+
+ igt_list_for_each_entry_safe(port, tmp, chamelium_rpc_get_port_mapping(chamelium),
+ link) {
+ igt_dynamic_f("port-%d", port->port_id) {
+ drmModeConnectorPtr connector;
+ size_t edid_count;
+ char *name;
+
+ name = chamelium_get_port_name_rpc(chamelium, port->port_id);
+ igt_info("Testing port %s (%s)\n", port->connector_name, name);
+ free(name);
+
+ connector = chamelium_rpc_port_mapping_get_connector(port, drm_fd);
+ igt_assert(connector);
+ edid_stress_resolution(drm_fd, chamelium, port,
+ get_edid_for_connector_type(connector->connector_type,
+ &edid_count,
+ true),
+ edid_count);
+
+ drmModeFreeConnector(connector);
+ }
+ }
+ }
+
igt_fixture {
chamelium_rpc_uninit(chamelium);
drm_close_driver(drm_fd);
--
2.43.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH i-g-t RFC 10/13] tests/chamelium: Introduce non-4k stress edid
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
` (8 preceding siblings ...)
2024-06-05 14:30 ` [PATCH i-g-t RFC 09/13] tests/chamelium: Introduce 4k stress edid Louis Chauvet
@ 2024-06-05 14:30 ` Louis Chauvet
2024-06-05 14:30 ` [PATCH i-g-t RFC 11/13] tests/chamelium: Introduce test resolution Louis Chauvet
` (5 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Louis Chauvet @ 2024-06-05 14:30 UTC (permalink / raw)
To: igt-dev, ihf, markyacoub, thomas.petazzoni, Louis Chauvet
Complement the EDID test to also test non-4k screens. The current database
contains EDID for HDMI and DP ports.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
tests/chamelium/v3/kms_chamelium_v3_edid.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/tests/chamelium/v3/kms_chamelium_v3_edid.c b/tests/chamelium/v3/kms_chamelium_v3_edid.c
index 76bdddd81174..836086f2dc13 100644
--- a/tests/chamelium/v3/kms_chamelium_v3_edid.c
+++ b/tests/chamelium/v3/kms_chamelium_v3_edid.c
@@ -131,6 +131,34 @@ igt_main {
}
}
+ igt_describe("Read many different non-4k EDID from the chamelium");
+ igt_subtest_with_dynamic("edid-stress-non-4k") {
+ struct chamelium_rpc_port_mapping *port, *tmp;
+
+ igt_list_for_each_entry_safe(port, tmp, chamelium_rpc_get_port_mapping(chamelium),
+ link) {
+ igt_dynamic_f("port-%d", port->port_id) {
+ drmModeConnectorPtr connector;
+ size_t edid_count;
+ char *name;
+
+ name = chamelium_get_port_name_rpc(chamelium, port->port_id);
+ igt_info("Testing port %s (%s)\n", port->connector_name, name);
+ free(name);
+
+ connector = chamelium_rpc_port_mapping_get_connector(port, drm_fd);
+ igt_assert(connector);
+ edid_stress_resolution(drm_fd, chamelium, port,
+ get_edid_for_connector_type(connector->connector_type,
+ &edid_count,
+ false),
+ edid_count);
+
+ drmModeFreeConnector(connector);
+ }
+ }
+ }
+
igt_fixture {
chamelium_rpc_uninit(chamelium);
drm_close_driver(drm_fd);
--
2.43.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH i-g-t RFC 11/13] tests/chamelium: Introduce test resolution
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
` (9 preceding siblings ...)
2024-06-05 14:30 ` [PATCH i-g-t RFC 10/13] tests/chamelium: Introduce non-4k " Louis Chauvet
@ 2024-06-05 14:30 ` Louis Chauvet
2024-06-05 14:30 ` [PATCH i-g-t RFC 12/13] tests/chamelium: Introduce test sleep Louis Chauvet
` (4 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Louis Chauvet @ 2024-06-05 14:30 UTC (permalink / raw)
To: igt-dev, ihf, markyacoub, thomas.petazzoni, Louis Chauvet
Introduce a new tests to ensures that the resolution listed and used by
the DRM device is correct according to the EDID.
This is inspired from the v2 version.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
tests/chamelium/v3/kms_chamelium_v3_edid.c | 103 ++++++++++++++++++++++++++++-
1 file changed, 102 insertions(+), 1 deletion(-)
diff --git a/tests/chamelium/v3/kms_chamelium_v3_edid.c b/tests/chamelium/v3/kms_chamelium_v3_edid.c
index 836086f2dc13..a85091a3c660 100644
--- a/tests/chamelium/v3/kms_chamelium_v3_edid.c
+++ b/tests/chamelium/v3/kms_chamelium_v3_edid.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
#include <igt.h>
+
#include "monitor_edids/monitor_edids_helper.h"
#include "chamelium/v3/igt_chamelium.h"
@@ -70,6 +71,89 @@ static void edid_stress_resolution(int drm_fd, struct igt_chamelium_rpc *chameli
}
}
+static void edid_resolution_list(int drm_fd, struct igt_chamelium_rpc *chamelium,
+ struct chamelium_rpc_port_mapping *port_mapping)
+{
+ int screen_res_w, screen_res_h;
+ drmModeConnector *connector;
+ chamelium_edid_id edid_id;
+ drmModeModeInfoPtr modes;
+ struct igt_fb fb = {0};
+ igt_display_t display;
+ bool is_video_stable;
+ igt_output_t *output;
+ igt_plane_t *primary;
+ int count_modes, i;
+ enum pipe pipe;
+
+ chamelium_reset_rpc(chamelium);
+
+ edid_id = chamelium_create_edid_rpc(chamelium,
+ igt_kms_get_custom_edid(IGT_CUSTOM_EDID_BASE));
+ chamelium_apply_edid_rpc(chamelium, port_mapping->port_id, edid_id);
+
+ chamelium_plug_rpc(chamelium, port_mapping->port_id);
+
+ connector = chamelium_rpc_port_mapping_get_connector(port_mapping, drm_fd);
+ assert(igt_wait_for_connector_status(drm_fd, connector->connector_id, 10.0,
+ DRM_MODE_CONNECTED));
+ drmModeFreeConnector(connector);
+
+ connector = chamelium_rpc_port_mapping_get_connector(port_mapping, drm_fd);
+ modes = connector->modes;
+ count_modes = connector->count_modes;
+
+ igt_display_require(&display, drm_fd);
+ igt_require(display.is_atomic);
+ igt_display_require_output(&display);
+
+ for (i = 0; i < count_modes; ++i)
+ igt_debug("#%d %s %uHz\n", i, modes[i].name, modes[i].vrefresh);
+
+ for (i = 0; i < count_modes; ++i) {
+ igt_info("Testing #%d %s %uHz\n", i, modes[i].name,
+ modes[i].vrefresh);
+
+ igt_display_reset(&display);
+
+ output = igt_output_from_connector(&display, connector);
+ igt_assert(output);
+ pipe = igt_get_pipe_for_output(&display, output);
+ igt_output_set_pipe(output, pipe);
+
+ /* Set the screen mode with the one we chose. */
+ igt_create_color_fb(drm_fd, modes[i].hdisplay, modes[i].vdisplay,
+ DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_LINEAR, 1, 0, 0, &fb);
+
+ primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+ igt_assert(primary);
+
+ igt_plane_set_fb(primary, &fb);
+ igt_fb_set_size(&fb, primary, modes[i].hdisplay, modes[i].vdisplay);
+ igt_plane_set_size(primary, modes[i].hdisplay, modes[i].vdisplay);
+
+ igt_output_override_mode(output, &modes[i]);
+
+ igt_display_commit2(output->display, COMMIT_ATOMIC);
+
+ is_video_stable = chamelium_port_wait_video_input_stable_rpc(chamelium,
+ port_mapping->port_id,
+ 10);
+ igt_assert(is_video_stable);
+
+ chamelium_port_get_resolution_rpc(chamelium, port_mapping->port_id, &screen_res_w, &screen_res_h);
+ igt_assert_eq(screen_res_w, modes[i].hdisplay);
+ igt_assert_eq(screen_res_h, modes[i].vdisplay);
+
+ igt_remove_fb(drm_fd, &fb);
+ }
+
+ igt_modeset_disable_all_outputs(&display);
+
+ igt_display_fini(&display);
+ drmModeFreeConnector(connector);
+}
+
igt_main {
struct igt_chamelium_rpc *chamelium;
@@ -78,7 +162,7 @@ igt_main {
igt_fixture {
chamelium = chamelium_rpc_init_from_config();
igt_assert(chamelium);
- drm_fd = drm_open_driver_master(DRIVER_ANY);
+ drm_fd = drm_open_driver(DRIVER_ANY);
igt_assert(drm_fd);
chamelium_rpc_fill_port_mapping(chamelium, drm_fd);
}
@@ -159,6 +243,23 @@ igt_main {
}
}
+ igt_describe("Set a basic EDID and check if resolution are correct");
+ igt_subtest_with_dynamic("edid-resolution-list") {
+ struct chamelium_rpc_port_mapping *port, *tmp;
+
+ igt_list_for_each_entry_safe(port, tmp, chamelium_rpc_get_port_mapping(chamelium), link) {
+ igt_dynamic_f("port-%d", port->port_id) {
+ char *name;
+
+ name = chamelium_get_port_name_rpc(chamelium, port->port_id);
+ igt_info("Testing port %s (%s)\n", port->connector_name, name);
+ free(name);
+
+ edid_resolution_list(drm_fd, chamelium, port);
+ }
+ }
+ }
+
igt_fixture {
chamelium_rpc_uninit(chamelium);
drm_close_driver(drm_fd);
--
2.43.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH i-g-t RFC 12/13] tests/chamelium: Introduce test sleep
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
` (10 preceding siblings ...)
2024-06-05 14:30 ` [PATCH i-g-t RFC 11/13] tests/chamelium: Introduce test resolution Louis Chauvet
@ 2024-06-05 14:30 ` Louis Chauvet
2024-06-05 14:30 ` [PATCH i-g-t RFC 13/13] tests/chamelium: Add MST test Louis Chauvet
` (3 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Louis Chauvet @ 2024-06-05 14:30 UTC (permalink / raw)
To: igt-dev, ihf, markyacoub, thomas.petazzoni, Louis Chauvet
Introduce a new test to ensures that if the display is changed during a
sleep, the new one is properly detected.
This is inspired from the v2 version.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
lib/monitor_edids/monitor_edids_helper.h | 3 +-
tests/chamelium/v3/kms_chamelium_v3_edid.c | 56 ++++++++++++++++++++++++++++++
2 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/lib/monitor_edids/monitor_edids_helper.h b/lib/monitor_edids/monitor_edids_helper.h
index ff5672058816..3e91cee423b8 100644
--- a/lib/monitor_edids/monitor_edids_helper.h
+++ b/lib/monitor_edids/monitor_edids_helper.h
@@ -12,8 +12,9 @@
#define TESTS_CHAMELIUM_MONITOR_EDIDS_MONITOR_EDIDS_HELPER_H_
#include <stdint.h>
+#include "igt.h"
-#include "chamelium/v2/igt_chamelium.h"
+struct chamelium_edid;
/* Max Length can be increased as needed, when new EDIDs are added. */
#define EDID_NAME_MAX_LEN 28
diff --git a/tests/chamelium/v3/kms_chamelium_v3_edid.c b/tests/chamelium/v3/kms_chamelium_v3_edid.c
index a85091a3c660..efd53b392f4f 100644
--- a/tests/chamelium/v3/kms_chamelium_v3_edid.c
+++ b/tests/chamelium/v3/kms_chamelium_v3_edid.c
@@ -154,6 +154,45 @@ static void edid_resolution_list(int drm_fd, struct igt_chamelium_rpc *chamelium
drmModeFreeConnector(connector);
}
+static void test_suspend_resume_edid_change(int drm_fd, struct igt_chamelium_rpc *chamelium,
+ struct chamelium_rpc_port_mapping *port_mapping,
+ enum igt_suspend_state state,
+ enum igt_suspend_test test)
+{
+ chamelium_edid_id base_edid, alt_edid;
+ drmModeConnectorPtr connector;
+
+ chamelium_reset_rpc(chamelium);
+
+ base_edid = chamelium_create_edid_rpc(chamelium, igt_kms_get_base_edid());
+ igt_assert(base_edid);
+ alt_edid = chamelium_create_edid_rpc(chamelium, igt_kms_get_alt_edid());
+ igt_assert(alt_edid);
+
+ chamelium_apply_edid_rpc(chamelium, port_mapping->port_id, base_edid);
+ chamelium_plug_rpc(chamelium, port_mapping->port_id);
+ connector = chamelium_rpc_port_mapping_get_connector(port_mapping, drm_fd);
+ igt_assert(igt_wait_for_connector_status(drm_fd, connector->connector_id, 10.0,
+ DRM_MODE_CONNECTED));
+ drmModeFreeConnector(connector);
+ collect_and_compare_edid(drm_fd, port_mapping, igt_kms_get_base_edid());
+
+ chamelium_apply_edid_rpc(chamelium, port_mapping->port_id, alt_edid);
+
+ // Schedule the hpd pulse during the sleep state
+ chamelium_schedule_hpd_toggle_rpc(chamelium, port_mapping->port_id,
+ igt_get_autoresume_delay(state) * 1000 / 2,
+ true);
+ igt_system_suspend_autoresume(state, test);
+
+ connector = chamelium_rpc_port_mapping_get_connector(port_mapping, drm_fd);
+ igt_assert(igt_wait_for_connector_status(drm_fd, connector->connector_id, 10.0,
+ DRM_MODE_CONNECTED));
+ drmModeFreeConnector(connector);
+
+ collect_and_compare_edid(drm_fd, port_mapping, igt_kms_get_alt_edid());
+}
+
igt_main {
struct igt_chamelium_rpc *chamelium;
@@ -260,6 +299,23 @@ igt_main {
}
}
+ igt_describe("Check if hotplug during sleeping are correctly handled");
+ igt_subtest_with_dynamic("edid-edid-suspend-mem") {
+ struct chamelium_rpc_port_mapping *port, *tmp;
+ igt_list_for_each_entry_safe(port, tmp, chamelium_rpc_get_port_mapping(chamelium), link) {
+ igt_dynamic_f("port-%d", port->port_id) {
+ char *name;
+
+ name = chamelium_get_port_name_rpc(chamelium, port->port_id);
+ igt_info("Testing port %s (%s)\n", port->connector_name, name);
+ free(name);
+
+ test_suspend_resume_edid_change(drm_fd, chamelium, port, SUSPEND_STATE_MEM,
+ SUSPEND_TEST_NONE);
+ }
+ }
+ }
+
igt_fixture {
chamelium_rpc_uninit(chamelium);
drm_close_driver(drm_fd);
--
2.43.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH i-g-t RFC 13/13] tests/chamelium: Add MST test
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
` (11 preceding siblings ...)
2024-06-05 14:30 ` [PATCH i-g-t RFC 12/13] tests/chamelium: Introduce test sleep Louis Chauvet
@ 2024-06-05 14:30 ` Louis Chauvet
2024-06-05 16:36 ` ✗ Fi.CI.BUILD: failure for tests/chamelium: Integrate the chamelium v3 Patchwork
` (2 subsequent siblings)
15 siblings, 0 replies; 18+ messages in thread
From: Louis Chauvet @ 2024-06-05 14:30 UTC (permalink / raw)
To: igt-dev, ihf, markyacoub, thomas.petazzoni, Louis Chauvet
Introduce a test to check EDID on MST ports. This plug all the children in
the chamelium and apply a different EDID for each.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
tests/chamelium/v3/kms_chamelium_v3_edid.c | 96 ++++++++++++++++++++++++++++++
1 file changed, 96 insertions(+)
diff --git a/tests/chamelium/v3/kms_chamelium_v3_edid.c b/tests/chamelium/v3/kms_chamelium_v3_edid.c
index efd53b392f4f..b1685c1f2569 100644
--- a/tests/chamelium/v3/kms_chamelium_v3_edid.c
+++ b/tests/chamelium/v3/kms_chamelium_v3_edid.c
@@ -193,6 +193,82 @@ static void test_suspend_resume_edid_change(int drm_fd, struct igt_chamelium_rpc
collect_and_compare_edid(drm_fd, port_mapping, igt_kms_get_alt_edid());
}
+static void edid_mst(int drm_fd, struct igt_chamelium_rpc *chamelium, chamelium_port_id port_id)
+{
+ const struct edid *edid = igt_kms_get_base_edid();
+ chamelium_port_id *children_port_ids;
+ int edid_id;
+ int children_port_count = chamelium_get_children_rpc(chamelium, port_id,
+ &children_port_ids);
+
+ struct edid **modified_edids;
+
+ modified_edids = calloc(children_port_count + 1, sizeof(*modified_edids));
+ igt_assert(modified_edids);
+
+ for (int i = 0; i <= children_port_count; i++) {
+ modified_edids[i] = malloc(edid_get_size(edid));
+ memcpy(modified_edids[i], edid, edid_get_size(edid));
+ modified_edids[i]->serial[0] = i;
+ modified_edids[i]->serial[1] = i;
+ modified_edids[i]->serial[2] = i;
+ modified_edids[i]->serial[3] = i;
+ edid_update_checksum(modified_edids[i]);
+ }
+
+ chamelium_reset_rpc(chamelium);
+
+ edid_id = chamelium_create_edid_rpc(chamelium, modified_edids[0]);
+ igt_assert(edid_id);
+ chamelium_apply_edid_rpc(chamelium, port_id, edid_id);
+
+ for (int i = 0; i < children_port_count; i++) {
+ edid_id = chamelium_create_edid_rpc(chamelium, modified_edids[i + 1]);
+ igt_assert(edid_id);
+ chamelium_apply_edid_rpc(chamelium, children_port_ids[i], edid_id);
+ }
+
+ chamelium_plug_with_children_rpc(chamelium, port_id, children_port_ids,
+ children_port_count);
+ drmModeResPtr res = drmModeGetResources(drm_fd);
+
+ drmModeFreeResources(res);
+ sleep(3);
+ res = drmModeGetResources(drm_fd);
+ for (int i = 0; i <= children_port_count; i++) {
+ bool found = false;
+
+ for (int j = 0; j < res->count_connectors; j++) {
+ drmModeConnectorPtr connector = drmModeGetConnector(drm_fd,
+ res->connectors[j]);
+ uint64_t edid_blob_id;
+
+ igt_assert(kmstest_get_property(drm_fd, connector->connector_id,
+ DRM_MODE_OBJECT_CONNECTOR, "EDID", NULL,
+ &edid_blob_id, NULL));
+ if (edid_blob_id != 0) {
+ drmModePropertyBlobPtr edid_blob = drmModeGetPropertyBlob(drm_fd,
+ edid_blob_id);
+
+ igt_assert(edid_blob);
+
+ if (memcmp(modified_edids[i], edid_blob->data,
+ edid_get_size(modified_edids[i])) == 0)
+ found = true;
+ }
+
+ drmModeFreeConnector(connector);
+ }
+
+ igt_assert_f(found, "No connector were found with the correct EDID.\n");
+
+ free(modified_edids[i]);
+ }
+
+ drmModeFreeResources(res);
+ free(modified_edids);
+}
+
igt_main {
struct igt_chamelium_rpc *chamelium;
@@ -316,6 +392,26 @@ igt_main {
}
}
+ igt_describe("Check if hotplug during sleeping are correctly handled");
+ igt_subtest_with_dynamic("DP-MST-edid-read") {
+ chamelium_port_id *port_ids;
+ int port_count;
+
+ port_count = chamelium_get_supported_ports_rpc(chamelium, &port_ids);
+ for (int j = 0; j < port_count; j++) {
+ if (chamelium_is_mst_rpc(chamelium, port_ids[j])) {
+ igt_dynamic_f("port-%d", port_ids[j]) {
+ char *name;
+
+ name = chamelium_get_port_name_rpc(chamelium, port_ids[j]);
+ igt_info("Testing port %s\n", name);
+ free(name);
+
+ edid_mst(drm_fd, chamelium, port_ids[j]);
+ }
+ }
+ }
+ }
igt_fixture {
chamelium_rpc_uninit(chamelium);
drm_close_driver(drm_fd);
--
2.43.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* ✗ Fi.CI.BUILD: failure for tests/chamelium: Integrate the chamelium v3
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
` (12 preceding siblings ...)
2024-06-05 14:30 ` [PATCH i-g-t RFC 13/13] tests/chamelium: Add MST test Louis Chauvet
@ 2024-06-05 16:36 ` Patchwork
2024-06-07 19:05 ` ✗ GitLab.Pipeline: warning " Patchwork
2024-06-11 16:51 ` [PATCH i-g-t RFC 00/13] " Kamil Konieczny
15 siblings, 0 replies; 18+ messages in thread
From: Patchwork @ 2024-06-05 16:36 UTC (permalink / raw)
To: Louis Chauvet; +Cc: igt-dev
== Series Details ==
Series: tests/chamelium: Integrate the chamelium v3
URL : https://patchwork.freedesktop.org/series/134506/
State : failure
== Summary ==
IGT patchset build failed on latest successful build
08560f766a505e729dfee2846c1c11d28dd0e3d0 tools/intel_vbt_decode: Decode device handle as a bitmask
Tail of build.log:
[1573/1687] Generating xe_pat.testlist with a meson_exe.py custom command.
[1574/1687] Linking target tools/intel_bios_dumper.
[1575/1687] Generating xe_pm.testlist with a meson_exe.py custom command.
[1576/1687] Linking target benchmarks/gem_userptr_benchmark.
[1577/1687] Generating xe_peer2peer.testlist with a meson_exe.py custom command.
[1578/1687] Generating xe_pm_residency.testlist with a meson_exe.py custom command.
[1579/1687] Generating xe_noexec_ping_pong.testlist with a meson_exe.py custom command.
[1580/1687] Linking target benchmarks/gem_exec_nop.
[1581/1687] Linking target benchmarks/gem_exec_fault.
[1582/1687] Linking target benchmarks/gem_syslatency.
[1583/1687] Linking target benchmarks/gem_exec_trace.
[1584/1687] Generating xe_vm.testlist with a meson_exe.py custom command.
[1585/1687] Linking target benchmarks/gem_latency.
[1586/1687] Generating xe_query.testlist with a meson_exe.py custom command.
[1587/1687] Linking target benchmarks/gem_prw.
[1588/1687] Linking target benchmarks/gem_set_domain.
[1589/1687] Generating xe_render_copy.testlist with a meson_exe.py custom command.
[1590/1687] Generating xe_prime_self_import.testlist with a meson_exe.py custom command.
[1591/1687] Generating kms_chamelium_hpd.testlist with a meson_exe.py custom command.
[1592/1687] Linking target benchmarks/gem_exec_reloc.
[1593/1687] Generating kms_chamelium_audio.testlist with a meson_exe.py custom command.
[1594/1687] Generating xe_spin_batch.testlist with a meson_exe.py custom command.
[1595/1687] Generating xe_sysfs_scheduler.testlist with a meson_exe.py custom command.
[1596/1687] Linking target benchmarks/gem_wsim.
[1597/1687] Generating xe_waitfence.testlist with a meson_exe.py custom command.
[1598/1687] Generating xe_sysfs_defaults.testlist with a meson_exe.py custom command.
[1599/1687] Generating kms_chamelium_color.testlist with a meson_exe.py custom command.
[1600/1687] Generating kms_chamelium_edid.testlist with a meson_exe.py custom command.
[1601/1687] Generating kms_chamelium_frames.testlist with a meson_exe.py custom command.
[1602/1687] Generating kms_chamelium_v3_basic.testlist with a meson_exe.py custom command.
[1603/1687] Linking target benchmarks/kms_vblank.
[1604/1687] Linking target benchmarks/intel_upload_blit_large_gtt.
[1605/1687] Linking target benchmarks/intel_upload_blit_small.
[1606/1687] Linking target benchmarks/prime_lookup.
[1607/1687] Linking target benchmarks/intel_upload_blit_large.
[1608/1687] Linking target benchmarks/vgem_mmap.
[1609/1687] Linking target benchmarks/kms_fb_stress.
[1610/1687] Linking target benchmarks/intel_upload_blit_large_map.
[1611/1687] Linking target tools/igt_stats.
[1612/1687] Linking target tools/intel_display_poller.
[1613/1687] Linking target tools/intel_display_crc.
[1614/1687] Linking target tools/intel_dump_decode.
[1615/1687] Linking target tools/skl_compute_wrpll.
[1616/1687] Linking target tools/intel_audio_dump.
[1617/1687] Linking target tools/hsw_compute_wrpll.
[1618/1687] Linking target tools/intel_backlight.
[1619/1687] Compiling C object 'runner/527aa9f@@runner_test@exe/runner_tests.c.o'.
[1620/1687] Compiling C object 'lib/76b5a35@@i915_perf@sha/meson-generated_.._i915_perf_metrics_acmgt2.c.o'.
[1621/1687] Compiling C object 'lib/76b5a35@@i915_perf@sha/meson-generated_.._i915_perf_metrics_acmgt3.c.o'.
ninja: build stopped: subcommand failed.
^ permalink raw reply [flat|nested] 18+ messages in thread* ✗ GitLab.Pipeline: warning for tests/chamelium: Integrate the chamelium v3
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
` (13 preceding siblings ...)
2024-06-05 16:36 ` ✗ Fi.CI.BUILD: failure for tests/chamelium: Integrate the chamelium v3 Patchwork
@ 2024-06-07 19:05 ` Patchwork
2024-06-11 16:51 ` [PATCH i-g-t RFC 00/13] " Kamil Konieczny
15 siblings, 0 replies; 18+ messages in thread
From: Patchwork @ 2024-06-07 19:05 UTC (permalink / raw)
To: Louis Chauvet; +Cc: igt-dev
== Series Details ==
Series: tests/chamelium: Integrate the chamelium v3
URL : https://patchwork.freedesktop.org/series/134506/
State : warning
== Summary ==
Pipeline status: FAILED.
see https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/1194074 for the overview.
build:tests-debian-meson has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/59518807):
^~~~~~~~~
../lib/chamelium/v3/igt_chamelium.c: In function ‘igt_get_connector_from_name’:
../lib/chamelium/v3/igt_chamelium.c:967:35: error: initialization of ‘drmModeConnectorPtr’ {aka ‘struct _drmModeConnector *’} from ‘int’ makes pointer from integer without a cast [-Werror=int-conversion]
drmModeConnectorPtr connector = drmModeGetConnector(drm_fd, res->connectors[i]);
^~~~~~~~~~~~~~~~~~~
../lib/chamelium/v3/igt_chamelium.c:965:8: warning: unused variable ‘found’ [-Wunused-variable]
bool found;
^~~~~
../lib/chamelium/v3/igt_chamelium.c: In function ‘igt_wait_for_connector_status’:
../lib/chamelium/v3/igt_chamelium.c:1000:13: error: assignment to ‘drmModeConnector *’ {aka ‘struct _drmModeConnector *’} from ‘int’ makes pointer from integer without a cast [-Werror=int-conversion]
connector = drmModeGetConnector(drm_fd, connector_id);
^
cc1: some warnings being treated as errors
ninja: build stopped: subcommand failed.
section_end:1717605446:step_script
section_start:1717605446:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1717605447:cleanup_file_variables
ERROR: Job failed: exit code 1
build:tests-fedora has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/59518802):
[1431/1815] Generating kms_chamelium_v3_basic.testlist with a meson_exe.py custom command.
ninja: build stopped: subcommand failed.
ninja: Entering directory `build'
[1/1054] Generating version.h with a custom command.
[2/386] Generating kms_chamelium_frames.testlist with a meson_exe.py custom command.
[3/386] Generating kms_chamelium_hpd.testlist with a meson_exe.py custom command.
[4/386] Linking target tests/kms_chamelium_v3_edid.
FAILED: tests/kms_chamelium_v3_edid
cc -o tests/kms_chamelium_v3_edid 'tests/59830eb@@kms_chamelium_v3_edid@exe/chamelium_v3_kms_chamelium_v3_edid.c.o' -Wl,--as-needed -Wl,--no-undefined -Wl,--start-group lib/libigt.so.0 /usr/lib64/libcairo.so /usr/lib64/libglib-2.0.so /usr/lib64/libdrm.so /usr/lib64/libdw.so /usr/lib64/libelf.so /usr/lib64/libkmod.so /usr/lib64/libudev.so -lm /usr/lib64/libpciaccess.so /usr/lib64/libpixman-1.so -pthread -lrt -lz /usr/lib64/libdrm_nouveau.so /usr/lib64/libdrm_amdgpu.so /usr/lib64/libunwind.so /usr/lib64/libgsl.so /usr/lib64/libgslcblas.so /usr/lib64/libasound.so /usr/lib64/libxmlrpc.so /usr/lib64/libxmlrpc_util.so /usr/lib64/libxmlrpc_client.so /usr/lib64/libprocps.so -Wl,--end-group '-Wl,-rpath,$ORIGIN/../lib' -Wl,-rpath-link,/builds/gfx-ci/igt-ci-tags/build/lib
/usr/bin/ld: tests/59830eb@@kms_chamelium_v3_edid@exe/chamelium_v3_kms_chamelium_v3_edid.c.o: in function `__igt_unique____real_main273':
/builds/gfx-ci/igt-ci-tags/build/../tests/chamelium/v3/kms_chamelium_v3_edid.c:323: undefined reference to `get_edid_for_connector_type'
/usr/bin/ld: /builds/gfx-ci/igt-ci-tags/build/../tests/chamelium/v3/kms_chamelium_v3_edid.c:351: undefined reference to `get_edid_for_connector_type'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
section_end:1717605486:step_script
section_start:1717605486:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1717605486:cleanup_file_variables
ERROR: Job failed: exit code 1
build:tests-fedora-clang has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/59518806):
[1433/1815] Generating kms_chamelium_hpd.testlist with a meson_exe.py custom command.
[1434/1815] Compiling C object 'tests/amdgpu/b9f2b1d@@amd_basic@exe/amd_basic.c.o'.
[1435/1815] Compiling C object 'tests/amdgpu/b9f2b1d@@amd_bo@exe/amd_bo.c.o'.
ninja: build stopped: subcommand failed.
ninja: Entering directory `build'
[1/1052] Generating version.h with a custom command.
[2/382] Linking target tests/kms_chamelium_v3_edid.
FAILED: tests/kms_chamelium_v3_edid
clang -o tests/kms_chamelium_v3_edid 'tests/59830eb@@kms_chamelium_v3_edid@exe/chamelium_v3_kms_chamelium_v3_edid.c.o' -Wl,--as-needed -Wl,--no-undefined -Wl,--start-group lib/libigt.so.0 /usr/lib64/libcairo.so /usr/lib64/libglib-2.0.so /usr/lib64/libdrm.so /usr/lib64/libdw.so /usr/lib64/libelf.so /usr/lib64/libkmod.so /usr/lib64/libudev.so -lm /usr/lib64/libpciaccess.so /usr/lib64/libpixman-1.so -pthread -lrt -lz /usr/lib64/libdrm_nouveau.so /usr/lib64/libdrm_amdgpu.so /usr/lib64/libunwind.so /usr/lib64/libgsl.so /usr/lib64/libgslcblas.so /usr/lib64/libasound.so /usr/lib64/libxmlrpc.so /usr/lib64/libxmlrpc_util.so /usr/lib64/libxmlrpc_client.so /usr/lib64/libprocps.so -Wl,--end-group '-Wl,-rpath,$ORIGIN/../lib' -Wl,-rpath-link,/builds/gfx-ci/igt-ci-tags/build/lib
/usr/bin/ld: tests/59830eb@@kms_chamelium_v3_edid@exe/chamelium_v3_kms_chamelium_v3_edid.c.o: in function `__igt_unique____real_main273':
/builds/gfx-ci/igt-ci-tags/build/../tests/chamelium/v3/kms_chamelium_v3_edid.c:323: undefined reference to `get_edid_for_connector_type'
/usr/bin/ld: /builds/gfx-ci/igt-ci-tags/build/../tests/chamelium/v3/kms_chamelium_v3_edid.c:351: undefined reference to `get_edid_for_connector_type'
clang-9: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
section_end:1717605496:step_script
section_start:1717605496:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1717605497:cleanup_file_variables
ERROR: Job failed: exit code 1
build:tests-fedora-no-libdrm-nouveau has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/59518805):
[1390/1647] Generating kms_chamelium_frames.testlist with a meson_exe.py custom command.
[1391/1647] Generating kms_chamelium_hpd.testlist with a meson_exe.py custom command.
[1392/1647] Compiling C object 'tests/v3d/cad21b8@@v3d_perfmon@exe/v3d_perfmon.c.o'.
ninja: build stopped: subcommand failed.
ninja: Entering directory `build'
[1/921] Generating version.h with a custom command.
[2/257] Linking target tests/kms_chamelium_v3_edid.
FAILED: tests/kms_chamelium_v3_edid
cc -o tests/kms_chamelium_v3_edid 'tests/59830eb@@kms_chamelium_v3_edid@exe/chamelium_v3_kms_chamelium_v3_edid.c.o' -Wl,--as-needed -Wl,--no-undefined -Wl,--start-group lib/libigt.so.0 /usr/lib64/libcairo.so /usr/lib64/libglib-2.0.so /usr/lib64/libdrm.so /usr/lib64/libdw.so /usr/lib64/libelf.so /usr/lib64/libkmod.so /usr/lib64/libudev.so -lm /usr/lib64/libpciaccess.so /usr/lib64/libpixman-1.so -pthread -lrt -lz /usr/lib64/libunwind.so /usr/lib64/libgsl.so /usr/lib64/libgslcblas.so /usr/lib64/libasound.so /usr/lib64/libxmlrpc.so /usr/lib64/libxmlrpc_util.so /usr/lib64/libxmlrpc_client.so /usr/lib64/libprocps.so -Wl,--end-group '-Wl,-rpath,$ORIGIN/../lib' -Wl,-rpath-link,/builds/gfx-ci/igt-ci-tags/build/lib
/usr/bin/ld: tests/59830eb@@kms_chamelium_v3_edid@exe/chamelium_v3_kms_chamelium_v3_edid.c.o: in function `__igt_unique____real_main273':
/builds/gfx-ci/igt-ci-tags/build/../tests/chamelium/v3/kms_chamelium_v3_edid.c:323: undefined reference to `get_edid_for_connector_type'
/usr/bin/ld: /builds/gfx-ci/igt-ci-tags/build/../tests/chamelium/v3/kms_chamelium_v3_edid.c:351: undefined reference to `get_edid_for_connector_type'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
section_end:1717605485:step_script
section_start:1717605485:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1717605485:cleanup_file_variables
ERROR: Job failed: exit code 1
build:tests-fedora-no-libunwind has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/59518803):
[1436/1815] Linking target tests/amdgpu/amd_bo.
[1437/1815] Linking target tests/amdgpu/amd_assr.
[1438/1815] Generating kms_chamelium_frames.testlist with a meson_exe.py custom command.
ninja: build stopped: subcommand failed.
ninja: Entering directory `build'
[1/1052] Generating version.h with a custom command.
[2/379] Linking target tests/kms_chamelium_v3_edid.
FAILED: tests/kms_chamelium_v3_edid
cc -o tests/kms_chamelium_v3_edid 'tests/59830eb@@kms_chamelium_v3_edid@exe/chamelium_v3_kms_chamelium_v3_edid.c.o' -Wl,--as-needed -Wl,--no-undefined -Wl,--start-group lib/libigt.so.0 /usr/lib64/libcairo.so /usr/lib64/libglib-2.0.so /usr/lib64/libdrm.so /usr/lib64/libdw.so /usr/lib64/libelf.so /usr/lib64/libkmod.so /usr/lib64/libudev.so -lm /usr/lib64/libpciaccess.so /usr/lib64/libpixman-1.so -pthread -lrt -lz /usr/lib64/libdrm_nouveau.so /usr/lib64/libdrm_amdgpu.so /usr/lib64/libgsl.so /usr/lib64/libgslcblas.so /usr/lib64/libasound.so /usr/lib64/libxmlrpc.so /usr/lib64/libxmlrpc_util.so /usr/lib64/libxmlrpc_client.so /usr/lib64/libprocps.so -Wl,--end-group '-Wl,-rpath,$ORIGIN/../lib' -Wl,-rpath-link,/builds/gfx-ci/igt-ci-tags/build/lib
/usr/bin/ld: tests/59830eb@@kms_chamelium_v3_edid@exe/chamelium_v3_kms_chamelium_v3_edid.c.o: in function `__igt_unique____real_main273':
/builds/gfx-ci/igt-ci-tags/build/../tests/chamelium/v3/kms_chamelium_v3_edid.c:323: undefined reference to `get_edid_for_connector_type'
/usr/bin/ld: /builds/gfx-ci/igt-ci-tags/build/../tests/chamelium/v3/kms_chamelium_v3_edid.c:351: undefined reference to `get_edid_for_connector_type'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
section_end:1717605482:step_script
section_start:1717605482:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1717605483:cleanup_file_variables
ERROR: Job failed: exit code 1
build:tests-fedora-oldest-meson has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/59518804):
[1438/1815] Generating kms_chamelium_hpd.testlist with a meson_exe.py custom command.
[1439/1815] Compiling C object 'tests/amdgpu/tests@amdgpu@@amd_color@exe/amd_color.c.o'.
[1440/1815] Linking target tests/amdgpu/amd_basic.
ninja: build stopped: subcommand failed.
ninja: Entering directory `build'
[1/1051] Generating version.h with a custom command.
[2/377] Linking target tests/kms_chamelium_v3_edid.
FAILED: tests/kms_chamelium_v3_edid
cc -o tests/kms_chamelium_v3_edid 'tests/tests@@kms_chamelium_v3_edid@exe/chamelium_v3_kms_chamelium_v3_edid.c.o' -Wl,--no-undefined -Wl,--as-needed -Wl,--start-group lib/libigt.so.0 /usr/lib64/libcairo.so /usr/lib64/libglib-2.0.so /usr/lib64/libdrm.so /usr/lib64/libdw.so /usr/lib64/libelf.so /usr/lib64/libkmod.so /usr/lib64/libudev.so -lm /usr/lib64/libpciaccess.so /usr/lib64/libpixman-1.so -lrt -lz /usr/lib64/libdrm_nouveau.so /usr/lib64/libdrm_amdgpu.so /usr/lib64/libunwind.so /usr/lib64/libgsl.so /usr/lib64/libgslcblas.so -lm /usr/lib64/libasound.so /usr/lib64/libxmlrpc.so /usr/lib64/libxmlrpc_util.so /usr/lib64/libxmlrpc_client.so -lm -lm /usr/lib64/libprocps.so -lm -Wl,--end-group -pthread '-Wl,-rpath,$ORIGIN/../lib' -Wl,-rpath-link,/builds/gfx-ci/igt-ci-tags/build/lib
/usr/bin/ld: tests/tests@@kms_chamelium_v3_edid@exe/chamelium_v3_kms_chamelium_v3_edid.c.o: in function `__igt_unique____real_main273':
/builds/gfx-ci/igt-ci-tags/build/../tests/chamelium/v3/kms_chamelium_v3_edid.c:323: undefined reference to `get_edid_for_connector_type'
/usr/bin/ld: /builds/gfx-ci/igt-ci-tags/build/../tests/chamelium/v3/kms_chamelium_v3_edid.c:351: undefined reference to `get_edid_for_connector_type'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
section_end:1717605480:step_script
section_start:1717605480:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1717605480:cleanup_file_variables
ERROR: Job failed: exit code 1
== Logs ==
For more details see: https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/1194074
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3
2024-06-05 14:30 [PATCH i-g-t RFC 00/13] tests/chamelium: Integrate the chamelium v3 Louis Chauvet
` (14 preceding siblings ...)
2024-06-07 19:05 ` ✗ GitLab.Pipeline: warning " Patchwork
@ 2024-06-11 16:51 ` Kamil Konieczny
15 siblings, 0 replies; 18+ messages in thread
From: Kamil Konieczny @ 2024-06-11 16:51 UTC (permalink / raw)
To: igt-dev; +Cc: Louis Chauvet, ihf, markyacoub, thomas.petazzoni
Hi Louis,
On 2024-06-05 at 16:30:12 +0200, Louis Chauvet wrote:
> Hi all,
>
> This patch series introduces a new wrapper for the Chameleon v3 board, a
> testing tool used primarily for Chromebooks, but also by community members
> to increase test coverage of graphic devices. The Chameleon v3 is an
> upgrade from its predecessor, with the ability to emulate 2 HDMI and 2
> DisplayPort devices, including MST devices.
>
> The board can read and analyze any stream on the DisplayPort and HDMI
> cables, and even take captures, making it an ideal tool for testing
> hardware, driver, and user space behavior in specific situations, such as
> screen hotplugging and multiple MST screens. However, the changes between
> the v2 and v3, such as the addition of MST support and the removal of CRC
> for screen captures, would require significant modifications to the
> existing tests and wrappers.
>
> To avoid this complexity and ensure that the Chameleon v3 is fully
> supported and the v2 is not broken, I wrote a new wrapper with
> simplicity and ease of use in mind. The Chameleon v3 wrapper should only
> manage the Chameleon itself, without the need for DRM displays, EDID
> caching/modifications, or state machines. This approach will make it
> easier for developers to use the Chameleon v3 and contribute to its
> development.
>
> In this RFC, I did not merged the common code between the v2 and v3, but
> it is planned for the next version.
>
> Before I continue working on this series, I want to make sure that it
> is up to the standard of the project and that I am heading in the right
> direction.
>
> This series can be splitted in three parts:
> - PATCH 1-3: extracting the v2 wrapper and tests in its own directory
> - PATCH 4-6: Introducing the RPC wrapper
> - PATCH 6-12: Introduce few tests on EDID and MST
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>
Please look into compilation errors, also try to use checkpatch.pl script
from Linux kernel (you could ignore line too long or camel case for drm
and few others).
Regards,
Kamil
> ---
> Louis Chauvet (13):
> tests/chamelium: Extract chamelium v2 tests into its own directory
> lib/chamelium: Extract chamelium v2 wrapper into its own directory
> lib/chamelium: Change build options to split chamelium v2 and v3
> lib/chamelium: Introduce the foundation for the chamelium v3 library
> lib/chamelium: Implement all RPC calls for the chamelium v3
> lib/chamelium: Introduce a simple chamelium v3 test
> tests/chamelium: Introduce basic edid test
> lib/monitor_edids: Introduce helpers to get EDID from a monitor EDID
> tests/chamelium: Introduce 4k stress edid
> tests/chamelium: Introduce non-4k stress edid
> tests/chamelium: Introduce test resolution
> tests/chamelium: Introduce test sleep
> tests/chamelium: Add MST test
>
> docs/testplan/meson.build | 4 +-
> lib/{ => chamelium/v2}/igt_chamelium.c | 2 +-
> lib/{ => chamelium/v2}/igt_chamelium.h | 0
> lib/{ => chamelium/v2}/igt_chamelium_stream.c | 2 +-
> lib/{ => chamelium/v2}/igt_chamelium_stream.h | 0
> lib/chamelium/v3/igt_chamelium.c | 1026 +++++++++++++++++++++++
> lib/chamelium/v3/igt_chamelium.h | 120 +++
> lib/igt.h | 6 +-
> lib/igt_kms.c | 14 +-
> lib/meson.build | 16 +-
> lib/monitor_edids/monitor_edids_helper.c | 61 +-
> lib/monitor_edids/monitor_edids_helper.h | 6 +-
> lib/tests/meson.build | 8 +-
> meson.build | 45 +-
> meson_options.txt | 8 +-
> tests/chamelium/{ => v2}/kms_chamelium_audio.c | 0
> tests/chamelium/{ => v2}/kms_chamelium_color.c | 0
> tests/chamelium/{ => v2}/kms_chamelium_edid.c | 2 +-
> tests/chamelium/{ => v2}/kms_chamelium_frames.c | 0
> tests/chamelium/{ => v2}/kms_chamelium_helper.c | 0
> tests/chamelium/{ => v2}/kms_chamelium_helper.h | 0
> tests/chamelium/{ => v2}/kms_chamelium_hpd.c | 0
> tests/chamelium/v3/kms_chamelium_v3_basic.c | 30 +
> tests/chamelium/v3/kms_chamelium_v3_edid.c | 419 +++++++++
> tests/kms_color_helper.h | 2 +-
> tests/kms_feature_discovery.c | 6 +-
> tests/kms_tiled_display.c | 6 +-
> tests/meson.build | 61 +-
> 28 files changed, 1785 insertions(+), 59 deletions(-)
> ---
> base-commit: cea4eb0dae57dae8c21782c64ad8174c39d1df38
> change-id: 20240522-dev-remove-static-ports-9382ffbbf146
>
> Best regards,
> --
> Louis Chauvet <louis.chauvet@bootlin.com>
>
^ permalink raw reply [flat|nested] 18+ messages in thread